8221bd6478ff2b7e1e41d2294fb624b24cb2a170
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
abfab25685 |
build: the exe is LlamaCasty.exe, and the publish script proves the artifact
Renames AssemblyName to LlamaCasty before the first Steam depot — Steamworks is explicit that renaming a live exe is painful, so this had to land first, not later. Four assembly-qualified pack URIs carried the old name, not three: MainWindow (window icon), OverlayHost (logo), RenameRecordingDialog and KeepBroadcastDialog. Pack URIs resolve by assembly name at runtime, so a stale one compiles, passes every test and then silently renders nothing the first time that view opens. AssemblyIdentityTests guards both halves — the assembly name, and no source XAML still naming the legacy assembly. Packaging/Package.appxmanifest and package-msix.sh carry the exe name too. scripts/publish.sh replaces the by-hand publish: single-file win-x64, ReadyToRun, ffmpeg beside the exe, and it refuses to finish if ffmpeg, LICENSE, PRIVACY.md or THIRD-PARTY-NOTICES.txt are missing, or if a test assembly leaked in. That last guard exists because the first publish was wrong in a way no test could see: PublishSingleFile + IncludeNativeLibrariesForSelfExtract bundled the libav*.dll family into the exe — a 9-file output with no ffmpeg folder and a 182 MB binary, so the locator would have found nothing at runtime. ExcludeFromSingleFile="true" on the content keeps the folder a folder. Diffing against a control publish without the single-file flags found it; guessing at item globs wasted two attempts first (recorded in MyMistakes.md). Measured: 127 MB exe + 129 MB ffmpeg = 257 MB depot. Tests: AssemblyIdentity, StorePackaging, BuildStamp, BundledFonts all pass; app builds with 0 warnings. |
||
|
|
8f79b20a18 |
docs(distribution): Steam is the only channel — the zip, winget and the Store are dead
The site said "Coming soon to Steam" while the app docs still said direct download plus winget primary with Steam parked. One of them had to move, and the creator's ruling is Steam exclusive: a free app on Steam with the paid edition as a Steam DLC, and the $10/month plan sold off-Steam by Polar. Records the constraint that shapes the code, not just the prose: - Steamworks requires in-app purchases to use the Steam Wallet (Microtransactions doc, quoted in commercial.md), so the monthly is *stated*, never *sold*, inside a Steam build; the lifetime is plain DLC bought on the store page and read with BIsDlcInstalled. - Entitlement is `steamDlcOwned || polarKeyValid`, both resolving to one OutputProfile. steam_api64.dll ships beside the exe and is a functional dependency, not the rejected "IP protection" native DLL — without it DLC ownership cannot be read. Launched without Steam, the app falls back to the free profile rather than refusing to start. - Signing is moot: Steam installs never meet SmartScreen. Artifact Signing stays on the shelf for the day a non-Steam download exists. Year-one fixed cost is ~$115. - The exe rename must land before the first depot upload — Steamworks warns about renaming a live exe. Distribution.md is rewritten to SteamPipe mechanics (publish output, depot, steamcmd, DLC wiring, clean-account purchase/refund test). product.md, decisions.md (a new "Steam exclusive" entry with every dead vector), TASKS.md (Steamworks entitlement row, Steam packaging row), ai.md, index.md and the TASK 48 banner follow. MyMistakes.md gains the Steam rules that cost real time today: installs skip SmartScreen, updates are free, the Wallet rule, and the recurring-billing caveat. |
||
|
|
57ef9e7a5e |
docs(commercial): the claim page was never needed, signing waits for revenue, and support is a filter
Four things derived this session superseded what the plan said twenty-four hours earlier,
and the docs are corrected where each one died:
**Licensing needs no server.** Polar's customer-portal endpoints authenticate on the key
itself plus the public organization_id; the org access token is only needed to create
products. Channel binding rides in `conditions: {channel_id}`, re-checked on every
validate — so the "claim page" (a hosted OAuth flow that wrote the UC id onto the key)
and the key database it implied are deleted. Device management, key rotation and
subscription auto-revocation are Polar's; four states, one lease, no callback endpoint.
**Signing is deferred until two subscribers.** It never removes the day-one SmartScreen
warning (EV's instant-bypass died in 2024), so buying it before revenue buys only the
publisher line. Renamed to Azure Artifact Signing, $9.99/mo Basic, and it requires a
paid Azure subscription. Year-one fixed cost drops from ~$135 to ~$15.
**The Store account is free.** Microsoft waived the $19 individual fee and removed the
$99 company fee in May 2026, which makes the Store the only zero-cost route to a
Microsoft-signed install — the free answer to SmartScreen, noted beside the paid one.
**Support is a filter, not a promise.** Email, best effort, no SLA, refunds on request
without argument; no training service, no helpdesk. A repeated question becomes a
training video on @llamacasty, which is content and monetization instead of a ticket.
GitHub issues on the releases repo are the deliberate friction.
Also settled: binaries live in a second Gitea repo (`llamacasty-releases`) push-mirrored
to a public GitHub repo — issues and assets public, code private, one publish direction
(a git mirror carries refs, not GitHub Release assets); `@llamacasty` is
standard-verified with intermediate features, so live streaming, >15 min uploads and
custom thumbnails work today and no SIM or ID is needed; and OAuth comes out of Testing
mode by publishing the app (100-user lifetime cap, no 7-day token death).
TASKS.md now opens with the four-day surge slice — artifact shape, output gate,
entitlement seam, real-machine day — because those are what the first public release
waits on. HANDOFF.md rewritten. MyMistakes.md gains the Polar recipe and the
"verify means three different things" entry. MARCOM.md gains the support→content loop
and the surface roles.
|
||
|
|
7827d239e2 |
docs(commercial): one source of truth for the money — prices, entitlement, channels
The commercial plan was spread over five documents written in five different weeks, and they contradicted each other: product.md sold the Store, decisions.md called the Store dead then re-opened, Distribution.md (736 lines) still described Polar as a download host, MARCOM.md quoted "no subscription" next to a paid tier, and README.md promised "free forever". An outsider could not tell what ships. docs/ai/commercial.md is now the only place money is decided: free = whole app at a 921,600 px / 30 fps output profile covering the recording as well as the stream; Pro = $10/mo or $400 lifetime through Polar, key bound to the buyer's YouTube channel ID via a claim page, 2 activations, 7–14 day lease with offline grace, fail closed, never downgrade a running stream; one portable zip + winget primary, Steam and the Store parked; Azure Trusted Signing (~$9.99/mo), no EV; Founding 200 promo; ~$135/yr costs; anti-piracy posture and what is permanently rejected. Everything else now points at it instead of restating it: - product.md — money sections replaced with pointers; packaging rewritten to winget-first, Store parked; signing updated to Trusted Signing. - decisions.md — graveyard with cause of death for free-forever, the Store ordering, the updater, and the 2026-10-30 reversal of the quality-ceiling rejection. - Distribution.md — rewritten to release mechanics only (artifact, GitHub Releases, winget manifest, signing, checklist, takedown): 736 → 120 lines. - TASKS.md — TASK 54 rewritten, TASK 48's route settled, TASK 10 superseded, five new rows (entitlement seam, output-profile gate, licence UI, system messages, packaging). - README.md — "free forever" replaced with the real split. - capture.md — obs-backgroundremoval is GPL-3.0 and so licence-INCOMPATIBLE since the proprietary EULA; the old "compatible" line was falsified by that change. - TASKS/task-10, task-48, task-51, task-54 — superseded-banner at the top of each, so none of them reads as current policy. - HANDOFF.md — rewritten: plan settled, next code unit is the entitlement seam. MARCOM.md and MONETIZATION.md (gitignored) were corrected in place: policy pointer at the top of each, the flash removed from every live claim, the Polar fee break-even corrected to ~$900/mo, and the projections flagged as written against a dead model. |
||
|
|
0498f7e130 |
legal: proprietary EULA + privacy policy; GPL terms retired
Licensing posture changes to closed-source commercial software (creator ruling 2026-10-30): free tier caps output at 720p30, a paid licence unlocks 1080p ($10/month or $400 lifetime). - LICENSE is now an End User License Agreement: grant, what you may do with your own content, no redistribution/reverse engineering, third-party components prevail, updates at publisher discretion, warranty and liability limits, termination, governing law. - ADDITIONAL-TERMS.md deleted — those were GPL §7 terms and have no meaning under the EULA. - THIRD-PARTY-NOTICES.txt keeps every third-party obligation and drops the GPL header and §6 source offer; it states plainly that LlamaCasty ships no source. - PRIVACY.md is new: exactly what is written locally (layout DB, DPAPI token, capped log, recordings you choose), what leaves the machine (Google's APIs only, with your account), and the standing promises (chat rendered never stored, no telemetry, no ad SDKs). - README, docs/ai/product.md, docs/ai/decisions.md and TASKS.md record the decision and the obligations that still bind (ffmpeg LGPL as a separate process, OFL fonts, CC0 icons, model provenance, notices in the About screen). Deliberately NOT decided here: key issuance/verification and the resolution gate itself. Earlier GPL builds remain GPL for the versions that shipped under it. |
||
|
|
84c335a929 |
design: bundle Inter + JetBrains Mono (OFL-1.1) as the standard typefaces
The DESIGN.md type standard needs the fonts actually present — the machine's installed faces are not a design system. Four Inter weights (400/500/600/700) and two JetBrains Mono weights (500/600) ship as WPF resources from Assets/Fonts; the token families resolve them with the `/Assets/Fonts/#Family` pack form, so nothing depends on an install or a network fetch. Licensing (recorded in docs/ai/product.md): OFL-1.1 is a free licence but is NOT GPL-compatible in the linking sense. These are separate .ttf files loaded through WPF's font stack — an aggregate, not linked code — so they coexist with the GPL-3.0 app. Obligations carried: copyright line in THIRD-PARTY-NOTICES.txt (new items 13-14), the OFL text beside the files (Assets/Fonts/OFL-*.txt), no modification, no reserved-name reuse. Guard: BundledFontsTests — files exist and are real binaries, the csproj ships them, the theme uses pack URIs (a bare family name would silently fall back), the notice and both OFL texts are present, and no third font family sneaks in. Pending visual confirmation: the first launch should render panel text in Inter and telemetry in JetBrains Mono. |
||
|
|
565b8dbd6f |
docs(design): DESIGN.md becomes the visual standard (tokens merged, controls rejected)
Merges the 2026-10-29 Stitch export into the existing 2026-10-26 token sheet and promotes the file from "redesign exploration" to the normative standard: - type scale (32→10px), spacing, radii and elevation levels — the three scales the old DESIGN.md listed as missing - meter thresholds: cyan ≤ -12 dB, amber -12..-3, red > -3 - interaction rules: focus ring, hover step, 150ms/90ms easing, no springs Four export tokens rejected as Material-3 warm-seed artifacts (recorded with reasons): tertiary #4cd7f6 (kept #38bdf8), outline #ab8986, outline-variant #5b403e, on-surface-variant #e4beba (kept slate #94a3b8). Product rulings recorded: #e94560 retired as the app's general accent (blue takes every interactive role, red is live/record only, wordmark artwork untouched); error gets its own surface (#93000a) so it cannot be mistaken for on-air red. The export's dock, four bays, page-nav sidebar, CPU/GPU/NVENC readouts and acrylic blur are explicitly marked exploratory, not spec — the design principle is a simpler surface, not hardware cosplay. On-stream output styling stays outside this theme. Falsified facts fixed in the same commit: product.md brand section now points at DESIGN.md for UI tokens (MARCOM.md stays the marketing palette), and ui-surface.md no longer calls DESIGN.md an unreconciled exploration. Docs-only unit: scope-check run, no build. |
||
|
|
5a102a4a37 |
docs: decisions log, queue trim, HANDOFF rewrite — the map stops being a treadmill
TASKS.md 467 → 66 lines: one line per live item, detail stays in TASKS/ task-*.md. The old catalogue (63 rows of paragraph status prose plus the historical narration) is preserved verbatim as TASKS/archive.md — a 2026-10-29 snapshot, not the live queue. The "out of product" list and every retired decision moved to docs/ai/decisions.md with cause of death. HANDOFF.md 440 → 40 lines, and it is now OVERWRITTEN, not appended: branch, what's in flight, next action, live landmines, pending creator checks. History belongs to git log; the previous handoff is reachable at ee3c592:HANDOFF.md. docs/ai/decisions.md (new) collects what no longer governs: the paid tier and its pricing, Polar, Store IAP, the Store route and why it died, the deleted Velopack updater, signing economics, the retired monetization ideas, and the permanent out-of-product list. Facts that lived in the old ai.md "Current limitations" section were re-homed rather than dropped with the router rewrite: OAuth/DPAPI/session behaviour → docs/ai/youtube-api.md; paths, persistence and the Google project number → docs/ai/environment.md. verify.sh caps now cover all four always-read files (AGENTS 210, ai 100, HANDOFF 40, TASKS 120). Docs-only unit: scope-check run, no build. |
||
|
|
a311c8feb1 |
docs(ai): partition ai.md into five subsystem files (verbatim moves)
ai.md 1,308 → 228 lines. No prose rewritten: every block was moved as-is so nothing could be lost in translation, then replaced by a pointer. New files: - docs/ai/environment.md — LAN/SSH + Gitea push recipe, Windows dotnet build/run, test-suite map, hermetic real-MainWindow test rule - docs/ai/product.md — brand/naming, AI transparency, GPL licensing prohibitions, free-forever monetization, auth/account assumptions, packaging & distribution - docs/ai/youtube-api.md — go-live ordering, the broadcast-binding fix, the private-only lock, health parsing, end-stream pre-flight, Test mode, chat insert shape - docs/ai/overlays.md — social bar, native alert box (animations, clip, ticker), chat box conventions - docs/ai/ui-surface.md — control surface, scene strip, preview rail, hotkeys, broadcast drawer, toasts, transitions, brand logo, launch geometry, theme/properties conventions ai.md keeps the response/derivation rules, the architecture table, the four existing invariant stubs, and one pointer per moved subsystem. docs/ai/index.md routes every file with a "read when" column. References falsified by the move were fixed in the same commit: AGENTS.md build note → environment.md → Run, and the "Related" footers in frame-pipeline.md / output.md / capture.md now point at the owning files. Docs-only unit: scope-check run, no build (no source touched). |