finishing AIs work because tokens
This commit is contained in:
@@ -27,6 +27,15 @@ Nothing actively mid-flight. The last TASK 21 work unit (the **UI picker / acqui
|
||||
slice**) is **handed off**, not in progress — spec reproduced in the section below.
|
||||
It is a GUI feature that must be built + verified natively on Windows.
|
||||
|
||||
**2026-09-01 — doc-only work unit (monetization awareness spec'd into the map):** NOT
|
||||
code — the user asked to integrate the built-in monetization-awareness requirement into
|
||||
the existing docs as precursor/related work, then said "exec". Done: `ai.md`
|
||||
(Monetization section + Tests note), `TASKS.md` (TASK 10 "Related work" + the two Alerts
|
||||
items), and `MONETIZATION.md` (gitignored; product stance that analytics is free & ungated).
|
||||
No code changed; no task numbers added (kept as related work per the no-expand-queue rule).
|
||||
Whether this stays a docs-only change or seeds the first code slice (reward-event capture)
|
||||
is the user's call — nothing in flight until decided.
|
||||
|
||||
## Project-wide code-complete picture (2026-08-31, user's framing)
|
||||
|
||||
The user revisited the ongoing "how code-complete are we" question. Current agreed read:
|
||||
|
||||
@@ -119,7 +119,7 @@ Lifecycle: `created → ready → [testing] → live → complete` (transitional
|
||||
17. ☐ **Text source** — live text ("Starting soon", "Back in 5", handle, callout)
|
||||
18. ✅ **Chat box** — YouTube live chat rendered *on* the stream so viewers read along in-video — `ChatBoxRenderer` (WPF FormattedText → VideoFrame), configurable font size/color/badges/timestamps/max-messages via Elements panel, schema v10, persisted across save/load
|
||||
19. ❌ **Background removal (milestone 2)** — ONNX Runtime + DirectML, MediaPipe Selfie Segmentation — deliberately NOT in this build
|
||||
20. ☐ **Alerts** — Super Chat / membership / subscribe pop-ins; build after the six; **the one paid feature** (see Monetization in `ai.md`)
|
||||
20. ☐ **Alerts** — Super Chat / membership / subscribe pop-ins; build after the six; **the one paid feature** (see Monetization in `ai.md`). **Precursor — reward-event capture (2026-09-01):** Alerts render from the app's canonical `RewardEvent` feed (all 7 `liveChatMessage` reward types, persisted to SQLite + the session report — see TASK 10 → "Related work — monetization awareness"), so it consumes that already-built data rather than re-integrating `liveChatMessages`. That capture is the required prior milestone.
|
||||
21. ✅ **Show Desktop toggle** — `Source.ShowDesktop` bool persisted in DB (schema migration + LayoutStore read/write). When checked, primary monitor captures regardless of fullscreen game state. Toggling off falls back to running game or releases to static placeholder. `ClearBackdropCaptureAsync` clears `CaptureKey` + `VideoImageSource` so static fallback renders. Toggle on Live backdrop context menu (IsCheckable MenuItem).
|
||||
22. ✅ **Top bar — status light + avatar + Log In button** — red/green/pulsing ellipse (disconnected/connected/live). Avatar border visible only when connected, loads via `BitmapImage` code-behind. "Log In" button visible when disconnected, calls `StartStreamCommand` → GoLiveWindow. `ShowStartStream` now requires `IsConnected`.
|
||||
23. ✅ **Chat preview — one-at-a-time mock messages** — `RunMockChatPreviewAsync`: simple async loop, displays `MockChatMessages[n]` via `Take(n+1)`, 1000ms between messages, wraps at end. `ChatPreviewEnabled` property on Source (default true). Stops on real messages, restarts on fade timer clear.
|
||||
@@ -148,7 +148,8 @@ the hot few and nothing esoteric. If a user needs more, they've graduated to OBS
|
||||
6. **Chat box** — YouTube live chat rendered *on* the stream so viewers read along in-video. YT-native.
|
||||
7. **Alerts** — Super Chat / membership / subscribe pop-ins. The dopamine source. **The one big lift**
|
||||
(Super Chat event streaming + on-stream rendering/animation); build after the six. **Also the one
|
||||
paid feature** — see Monetization in `ai.md`.
|
||||
paid feature** — see Monetization in `ai.md`. Consumes the canonical `RewardEvent` feed (reward-event
|
||||
capture, TASK 10 → related work).
|
||||
|
||||
Deliberately NOT supported: game capture, browser source, media playlist, VLC, color-key voodoo, MIDI.
|
||||
|
||||
@@ -710,6 +711,15 @@ the validator → persisted), compositor bar overlay (top/bottom + above-flash),
|
||||
**Goal:** annual subscription via Polar.sh that removes the branding watermark. All features are
|
||||
free — the only difference between free and paid is the watermark.
|
||||
|
||||
**Related work — monetization awareness (2026-09-01, ungated, free):** this task's billing is the
|
||||
*payer* side; the *product* also carries built-in, ungated monetization awareness for every creator —
|
||||
reward-event capture (all 7 `liveChatMessage` reward event types → canonical `RewardEvent` → SQLite
|
||||
persistence), per-session/broadcast reports (members, Super Chat $, stickers, gifts, milestones — the
|
||||
in-app replacement for the emailed "stream activity report"), and a journey tracker (position % +
|
||||
ETA vs. versioned, date-aware YPP thresholds; the Tier-2 bar doubles for new applicants 2027-02-01).
|
||||
Details and design notes: `ai.md` → Monetization. This is tracked as related work under this task's
|
||||
narrative, not a separate task number — it ships in its own code slices with one integration test each.
|
||||
|
||||
**Business details (pricing, Polar product/checkout/discounts) in `MONETIZATION.md` (gitignored).**
|
||||
|
||||
**Polar product:** `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` (LlamaCasty, $99/yr, currently `private`)
|
||||
|
||||
@@ -130,6 +130,11 @@ GlobalHotkeyTests + HotkeyConfigTests (TASK 20), WebcamMenuGateTests (TASK 26),
|
||||
`AudioPipelineTests.Mix_HonorsProviderGains…` + `RoundClipInteractionTests.Round_Clip_Corner_Is_Grabbable…`
|
||||
are NOT regressions; see HANDOFF.md. Run test classes individually — the full-suite vstest run hangs.)**
|
||||
|
||||
Reward-event capture (monetization awareness, see the Monetization section) will add its integration
|
||||
tests here when it ships: one real chat-poll payload containing all seven reward event types →
|
||||
assert the persisted canonical `RewardEvent` rows (type + amount/currency/tier/memberLevel/participant
|
||||
ids) round-trip into SQLite.
|
||||
|
||||
### Real-MainWindow tests MUST be hermetic (DB pollution bug)
|
||||
|
||||
The integration test boots a real `MainWindow` → `MainViewModel` → real `LayoutStore`
|
||||
@@ -861,6 +866,33 @@ crooked.
|
||||
how-tos / feature requests / manual-skimmers. Maintenance cadence = "when I get around to it" with
|
||||
emergency patches; not a 24/7 service promise.
|
||||
|
||||
**Monetization awareness (built-in, ungated, free — 2026-09-01):** the app is monetization-aware by
|
||||
design, for **every** creator, free and ungated (the only subscriber swap remains the branding-flash
|
||||
removal above). It has three layers, all free — this is the product's differentiator, not a paid tier:
|
||||
|
||||
- **Reward-event capture (the data foundation).** The live-chat poll (`YouTubeChatService.Poll`)
|
||||
already receives every reward event over `liveChatMessages` but today only decodes two
|
||||
(`superChatEvent`, `newSponsorEvent`); the other five — `superStickerEvent`, `membershipGiftingEvent`,
|
||||
`giftMembershipReceivedEvent`, `memberMilestoneChatEvent`, `giftEvent` — are silently dropped. The
|
||||
plan: decode all seven into a canonical `RewardEvent` and persist each to a SQLite table
|
||||
(`RewardEvents`: broadcastId, type, timestamp, amountMicros, currency, tier, memberLevelName,
|
||||
gifter/recipient channelIds). `superChatEvents.list` (30-day lookback) backfills prior broadcasts.
|
||||
This single feed is the foundation that Alerts, the session report, and the journey tracker all read.
|
||||
- **Session / broadcast report.** A session is created at Go Live; the poll + End roll that session's
|
||||
reward totals (new members, Super Chat $, stickers $, gifts, milestones). This is the in-app
|
||||
replacement for the emailed external "stream activity report" — the incumbents (Streamlabs et al.)
|
||||
email near-useless post-stream summaries; we track the same data natively and maintain it.
|
||||
- **Journey tracker.** On sign-in/startup, pull current `channels.list?mine=true&part=statistics`
|
||||
(`subscriberCount`/`viewCount`/`videoCount` — the current OAuth scopes suffice). Compute position
|
||||
toward each YPP tier threshold and project an ETA curve from the creator's own
|
||||
per-stream/per-day velocity (subs + watch hours). **YPP thresholds are versioned, date-aware DATA,
|
||||
never constants** — the Tier-2 bar doubles for new applicants on **2027-02-01** (long-form 4,000 →
|
||||
8,000 qualified hrs / 365d; Shorts 10M → 20M / 90d), while the Tier-1 fan-funding bar (500 subs /
|
||||
3,000 hrs / 3M Shorts) is unchanged. Hardcoding the pre-2027 numbers would ship a wrong ETA.
|
||||
Analytics-API scopes (`yt-analytics.readonly`, additive `yt-analytics-monetary.readonly`) are an
|
||||
additive capability behind a seam (`IChannelStatsProvider`), not a v1 blocker — current-scope data
|
||||
is the v1 baseline; the Analytics scopes would require an OAuth re-consent, deferred.
|
||||
|
||||
**What was rejected:** always-on watermark (obscurable — replaced by the flash), hard stream-time
|
||||
cutoffs (the worst dead end — a stream dying mid-broadcast reads as broken, and YouTube streams
|
||||
routinely run 2-4 hours), soft-limit nagging, freemium feature tiers, and donation-only (relies on
|
||||
|
||||
Reference in New Issue
Block a user