Creator ruling 2026-11-01. One SKU, one price, Steam does the selling. - Pro is a one-time Steam DLC on the free app: $79 introductory, $99 on a stated date, announced where the price is shown and actually raised. - The subscription is retired. The reasoning is in decisions.md: no service behind a monthly fee (no servers, no cloud, no content), ~1-3 subscribers per 1,000 installs against 5-8% churn, and it carried the most expensive code in the product. - Polar goes dormant. Its customer-portal design is recorded, not built. The "freemium on Steam, convert on Polar, Valve gets nothing" proposal is rejected: in-app purchases must use the Steam Wallet, so it risks the listing to save ~$24 a sale. - Entitlement collapses to `steamDlcOwned`. No lease, no key, no portal, no device limit; the greyed tier opens the Steam store overlay, so every purchase stays inside Valve's own surface. - The site publishes the model and links the store page. It takes no payment and hosts no binaries. - The $400 lifetime died with the subscription it anchored. Founding 200 died with the coupons and passes it needed. Costs: $115 fixed year one; $79 nets $55.30 after Steam, so three sales cover the year.
99 lines
10 KiB
Markdown
99 lines
10 KiB
Markdown
# TASKS — the active queue
|
||
|
||
> One line per live item; the detail lives in `TASKS/task-*.md`. Done work is in
|
||
> [`TASKS/archive.md`](TASKS/archive.md) (2026-10-29 snapshot of the old catalogue). Retired
|
||
> decisions are in [`docs/ai/decisions.md`](docs/ai/decisions.md).
|
||
> Markers: ☐ queued · 🔶 in progress · ⏳ blocked · ⏸ deferred · ❌ retired.
|
||
|
||
## The surge — six days, all remaining coding (2026-11-02 → 11-07)
|
||
|
||
**Every open coding row is assigned below.** No later phase, no "after launch" list. Target is
|
||
**6–8 units a day** (above the measured 3–5 baseline — that is the point of a surge). If a day
|
||
overruns, the smallest item moves to the next day; a launch blocker never moves.
|
||
|
||
**Rules, every unit, no exceptions:** one Good Dog test · clean build 0 warnings · per-class tests
|
||
green · `./scripts/verify.sh` on the declared scope · commit with the doc fact it falsifies
|
||
corrected. No new scope mid-week; anything discovered goes on a list for day 6.
|
||
|
||
| Day | Units | Done when |
|
||
|---|---|---|
|
||
| **1 · Mon** — licensing | `IEntitlement` seam + Steam DLC impl + fake · `HasProOutput` on the seam · greyed tier entries · licence UI four states + 7/1/0-day notices + "monthly is on the website, not Steam" · licence ID in About · system messages (`SystemMessage`/`MessageCenter` strip) · Debug-only `InternalsVisibleTo` | Fake drives all four states; Steam-less launch is the free profile; About shows the licence ID |
|
||
| **2 · Tue** — release blockers | Visibility picker + `UpdateBroadcast` · `StreamConfig` defaults · TASK 53 output contract (geometry test per tier, 9:16 e2e) · 9·5 webcam identity key · Move transitions (per-layer carry-across-scenes) | A public broadcast starts and changes while live; every tier pinned by a test |
|
||
| **3 · Wed** — resilience | TASK 32: blip retry → measured grace → amber RECONNECTING → one-click Back on air → fragmented MP4 → ingest pre-flight · 33 bandwidth step-down | Killing the network mid-broadcast recovers without ending it |
|
||
| **4 · Thu** — content & media | 3·17 Text layer · 21 media acquisition wiring + file picker + loop/volume UI · 49 chat profanity filter · 34 scheduled streams | Text layer renders/persists; media file plays, loops, has volume; scheduled stream created |
|
||
| **5 · Fri** — data & settings | 3·20 RewardEvent persistence + `superChatEvents.list` backfill · 39·2 YPP slice 2 · 37 defaults-vs-current split · 35 scene-linked audio · 40·A/C/D settings round · 55·2–3 disk hygiene | Session report reads persisted events; defaults can be reverted; temp clips cleaned |
|
||
| **6 · Sat** — finish & prove | 50 publish recording · preview undo (Ctrl+Z) · 14 creator feedback batch · 36 gold pass · full sweep: clean build, whole per-class suite, `publish.sh` artifact, EULA/privacy/notices in the artifact · commit + push | Gold pass list empty; artifact stages; suite green; pushed |
|
||
|
||
**Day 6 is the only polish day.** No polish passes before it — a surge dies on cosmetic passes taken
|
||
in the middle.
|
||
|
||
## Next up (after the surge slice)
|
||
|
||
**TASK 3·17 — the Text layer** is scheduled in the surge (day 4). Placeholder detail retained for
|
||
the unit itself: `AddSource` creates it 0×0, all four compositor paths `continue` past it,
|
||
`FramePump`'s hash skips it, it is not draggable, and it has no text/font/colour properties or
|
||
persistence. Text content, font family/size/weight/style, colour, alignment, drag/resize,
|
||
persisted; renderer mirrors `Services/ChatBoxRenderer.cs`.
|
||
|
||
## Queue
|
||
|
||
> Every open coding row here is assigned to a surge day above. Rows still marked ☐ on
|
||
> 2026-11-07 are a failure of the plan, not a scheduling note.
|
||
| Task | Status | Scope | Detail |
|
||
|---|---|---|---|
|
||
| 3·17 | ☐ **NEXT** | **Text layer** — content, font family/size/weight/style, colour, alignment, drag/resize, persisted | [`task-03`](TASKS/task-03-capture-pipeline.md) |
|
||
| 21 | 🔶 | Media source: acquisition wiring + file picker + loop/volume UI (decoder, manager, pacing, loop all shipped — **no `AcquireAsync` caller exists**) | [`task-21`](TASKS/task-21-media-source.md) |
|
||
| — | ☐ | Transitions **Move**: per-layer carry-across-scenes flag, per-scene placement, fixed z band | [`ui-surface`](docs/ai/ui-surface.md) |
|
||
| 55·2–3 | ☐ | Disk hygiene: delete `%TEMP%` alert clips on close + sweep at startup; low-disk guard before REC (slice 1 shipped) | [`task-55`](TASKS/task-55-disk-hygiene.md) |
|
||
| 40·A/C/D | ☐ | App Settings: active-camera picker; persist output resolution + surface transition defaults + confirm-before-End; accent consolidation | [`task-40`](TASKS/task-40-app-settings-round.md) |
|
||
| 3·20 | ☐ | RewardEvent persistence: canonical `RewardEvents` table + `superChatEvents.list` 30-day backfill (the session report and journey read it) | [`task-03`](TASKS/task-03-capture-pipeline.md) |
|
||
| 32 | ☐ | Stream resilience: blip retry → measured grace + amber "RECONNECTING" → one-click Back on air → fragmented MP4 → ingest pre-flight | [`task-32`](TASKS/task-32-stream-resilience.md) |
|
||
| 33 | ☐ | Bandwidth auto step-down: pure policy over dropped-frame rate, one-way within a broadcast | [`task-33`](TASKS/task-33-bandwidth-step-down.md) |
|
||
| 34 | ☐ | Scheduled streams (Text-drawer version) | [`task-34`](TASKS/task-34-scheduled-streams.md) |
|
||
| 35 | ☐ | Scene-linked audio | [`task-35`](TASKS/task-35-scene-linked-audio.md) |
|
||
| 37 | ☐ | Defaults vs current layout split (build-id); enables one-click revert to defaults | [`task-37`](TASKS/task-37-defaults-current-split.md) |
|
||
| — | ✅ | **Preview undo (Ctrl+Z / Ctrl+Shift+Z)** — done 2026-11-01: `Models/PreviewHistory` + `MainViewModel.Preview`, one step per gesture, gated on `EditingActive`, cleared on layout load. Property edits not yet in the stack | [`ui-surface`](docs/ai/ui-surface.md) |
|
||
| 39·2 | ☐ | YPP slice 2: Analytics scopes, watch-hours/Shorts velocity + ETA | [`task-39`](TASKS/task-39-ypp-journey-tracker.md) |
|
||
| 49 | ☐ | Chat profanity filter: local, opt-in, **non-persistent**, user-supplied word list | [`task-49`](TASKS/task-49-chat-profanity-filter.md) |
|
||
| 50 | ☐ | One-button publish of the local recording (resumable upload) | [`task-50`](TASKS/task-50-publish-recording.md) |
|
||
| 53 | ☐ | Output-format contract: pin every tier with a geometry test, prove 9:16 end-to-end, recorded file matches output | [`task-53`](TASKS/task-53-output-formats.md) |
|
||
| 54 | 🔶 | Freemium: EULA + privacy shipped; **no licence path built** — needs the entitlement seam, the output-profile cap and the licence UI below; site copy still says free forever | [`task-54`](TASKS/task-54-marcom-free-merch.md) |
|
||
| — | 🔶 | **Steamworks entitlement** — `IEntitlement` + `SteamEntitlement` (Steamworks.NET) + fake **done**; needs the DLC app id from Steamworks. **Polar path retired** — one-time Steam DLC only | [`commercial`](docs/ai/commercial.md) |
|
||
| — | ❌ | **Polar subscription path** — retired 2026-11-01 with the one-price model. Design kept in `decisions.md`, not built | [`decisions`](docs/ai/decisions.md) |
|
||
| — | 🔶 | **OutputProfile gate** — resolver + `EncoderOptions` wiring **done** (`Models/OutputProfile.cs`, one ffmpeg/two outputs, dev override); remaining: greyed tier entries in the dropdown, entitlement wiring | [`commercial`](docs/ai/commercial.md) |
|
||
| — | ☐ | **Licence UI** — two states only: owned → Pro · not owned → greyed tiers + "unlock on Steam" (opens the store overlay). No key entry, no notices, no portal | [`commercial`](docs/ai/commercial.md) |
|
||
| — | ☐ | **System messages** — `SystemMessage` + `MessageCenter`, strip above the dock, dedupe by key, short history, never composited | [`ui-surface`](docs/ai/ui-surface.md) |
|
||
| — | ☐ | **Steam packaging** — rename, `publish` output + `steam_api64.dll`, depot, `steamcmd` upload, store page + assets, DLC app | [`Distribution.md`](Distribution.md) |
|
||
| — | ☐ | **Training-video series** — capture the first 8–10 recurring questions as videos on `@llamacasty`; each is documentation, channel content and monetization at once | MARCOM → support→content loop |
|
||
| 9·5 | ☐ | Webcam identity key reconciliation | [`task-09`](TASKS/task-09-live-stream-management.md) |
|
||
| 14 | 🔶 | Creator feedback batch — branch 3+ | [`task-14`](TASKS/task-14-creator-feedback-batch.md) |
|
||
| — | ☐ | Small: `StreamConfig` defaults (`TargetBitrate=6000`, `1920x1080`) are stale — the dropdown drives `StreamHealth` | this line |
|
||
| 36 | ☐ | **Gold pass** — the v1 gate, always the last unit (see 1.0 gates) | [`task-36`](TASKS/task-36-gold-pass.md) |
|
||
| 48 | ⏸ | Distribution & packaging — route settled 2026-10-31 (winget/portable first; Steam + Store parked). Build steps: [`Distribution.md`](Distribution.md); starts after the entitlement seam | [`task-48`](TASKS/task-48-distribution-msix.md) |
|
||
| 10 | ❌ | Retired 2026-10-08; superseded by the TASK 54 rows above — the Polar design it described is rebuilt as a lease (`commercial.md`), not revived as written | [`task-10`](TASKS/task-10-monetization.md) |
|
||
|
||
## Pending the creator's hands (not programming)
|
||
|
||
- ✅ App Settings grouping + right-click gear — reported working 2026-10-29.
|
||
- ✅ Transition picker/durations, Wipe, preview + program transitions — reported working 2026-10-29.
|
||
- ✅ Brand logo layer — reported working 2026-10-29.
|
||
- ⏳ Vertical-tier camera check (Live tile inside the band, Chat rect-only) — outstanding.
|
||
- ⏳ **Webcam cadence**: a Release take in the failing geometry (vertical tier first) blocks Units 1–2.
|
||
No fix until a reading names the stage.
|
||
|
||
## 1.0 gates (before the first shipped build)
|
||
|
||
- **Visibility picker** — replace the always-Private lock, hide the TEST button, and wire
|
||
`UpdateBroadcast` in the same unit (it is the only code that can change a broadcast's privacy).
|
||
- **Kill the dev multi-instance affordance** — `Helpers/InstanceProfile.cs` is already `#if DEBUG`;
|
||
re-prove it on a Release build.
|
||
- **Release engineering** — `scripts/publish.sh` **done** (self-contained win-x64, `ffmpeg\`
|
||
guarded, no test artifacts), `LlamaCasty.exe` assembly rename **done**, full license texts beside
|
||
`THIRD-PARTY-NOTICES.txt` (TASK 4 req 9). Outstanding: Debug-only `InternalsVisibleTo`.
|
||
- **Gold pass** (TASK 36): the screens/layers audit, native-Windows verification, and the
|
||
branding-flash decision.
|
||
|
||
## Research
|
||
|
||
[`research-youtube-api.md`](TASKS/research-youtube-api.md) · [`research-store-certification.md`](TASKS/research-store-certification.md)
|