docs: the always-Private lock is a decision, and it unlocks at v1
Asked twice about a decision that has been settled since 2026-09-01, so this is a documentation failure rather than a question worth answering a third time. The note was already there and it was accurate. It still didn't work, which is the whole lesson: every sentence in it was descriptive. It said why the lock exists and where the unlock lives, and not one sentence told the reader what to DO when it looks like a defect. I read it, recognised it, and asked anyway — because recognition is not instruction. It also pointed at TASK 36 for the unlock while the creator's actual answer is v1, so it was confidently wrong on top of being non-directive, which is worse than saying nothing. Rewritten as a prohibition carrying its own trigger: verdict in imperative voice, then the observations that make it look broken (privacy=private in the diag line, the PRIVATE badge, recordFromStart/DVR on, no delete call in the codebase) so recognition fires the instruction instead of prompting a question, then the retired delete question with its verified answer. Also: it belongs to v1, not TASK 36, and UpdateBroadcastMetadataAsync:112 is a retrofit path, not the product change. MyMistakes.md gets the transferable part, because the fix is not "write it down" — it is "write decisions as prohibitions, not rationale, and treat a repeated correction as a broken note rather than an impatient user". TASKS.md gets it under 1.0 gates so it is a tracked deliverable, not prose.
This commit is contained in:
@@ -1362,3 +1362,40 @@ even when the compiler accepts it. `fileName` + `memberName` looks fine and is w
|
||||
shape puts the variable part last and the required context first. This is the same family as the
|
||||
prose-matching lesson — **the aim is to make the wrong thing hard to write, not to detect it
|
||||
afterward** — and I got it wrong in the very commit written to apply that idea.
|
||||
|
||||
## Asked twice about a deliberate, already-documented decision (2026-10-04)
|
||||
|
||||
**What happened:** the creator asked whether the test streams still upload private, and added "I
|
||||
don't think you're able to delete them". I answered, researched `videos.delete`, and then — in the
|
||||
very next exchange — *offered to build a cleanup tool*, which re-litigated a decision that has been
|
||||
settled since 2026-09-01. Then got asked about it again. The creator's response: "I keep telling
|
||||
you; maybe you should write it down." It **was** written down. The note existed, was accurate, and
|
||||
named the decision correctly. It still did not work.
|
||||
|
||||
**Why the note failed — this is the actual lesson.** The old text read:
|
||||
|
||||
> **Visibility picker — DELIBERATE TEST-PHASE LOCK, not drift.** The "always Private" enforcement
|
||||
> stays while the creator runs multi-month real-world testing… The unlock is a deliberate final-pass
|
||||
> item in **TASK 36**, wired with the dialog selection — never opportunistic.
|
||||
|
||||
Every sentence is **descriptive**. It explains *why* the lock exists and *where* the unlock lives.
|
||||
Not one sentence instructs the reader. So it told me what the truth was but never told me what to
|
||||
*do* when the truth looked like a defect — and `privacy=private` in a log line, a PRIVATE badge, and
|
||||
the absence of any delete call all *look* like defects. I read it, recognised it, and still asked,
|
||||
because recognition is not instruction. Worse, "never opportunistic" and "TASK 36" pointed at a
|
||||
*different* answer than the one the creator actually gave me (v1, not TASK 36), so the note was
|
||||
partly stale on top of being non-directive.
|
||||
|
||||
**The generalisation:** a decision note must be written as a **prohibition addressed to the future
|
||||
reader, carrying its own trigger** — not as rationale. Three parts, all required:
|
||||
1. **The verdict, in imperative voice:** "do not change it", not "it stays because".
|
||||
2. **The trigger condition:** *what you will observe* that makes it look wrong — `privacy=private`
|
||||
in a log, the PRIVATE badge, no delete call — so recognition fires the instruction automatically.
|
||||
3. **The correction, verbatim, where it differs from the note.** The creator's answer (v1) was not
|
||||
what the note said (TASK 36). A note that is confidently wrong is worse than no note: it makes me
|
||||
confidently re-ask.
|
||||
|
||||
Corollary, and the part I keep skipping: **a repeated user correction is a documentation failure,
|
||||
not a user annoyance.** The second time the same question gets asked, the correct response is not a
|
||||
better answer — it is to go find why the written answer did not land, and fix *that*. Answering
|
||||
well the first time was never the problem; the map was not carrying the instruction.
|
||||
|
||||
@@ -303,6 +303,16 @@ second encoder path needing a "redirect". Record+simulcast is one ffmpeg with tw
|
||||
|
||||
## 1.0 gates (do these before the first shipped build)
|
||||
|
||||
- **⛔ Replace the always-Private broadcast lock with a real visibility option (creator ruling,
|
||||
restated 2026-10-04).** `privacyStatus = "private"` hardcoded in
|
||||
`YouTubeStreamService.CreateBroadcast` is deliberate and correct for the whole pre-v1 test
|
||||
phase — it is the reason test VODs of a still-breaking product stay off the channel. At v1 it
|
||||
becomes a user-selectable visibility option in the Go-Live dialog, wired to the same
|
||||
`UpdateBroadcastMetadataAsync` path. **Before v1, do not touch it and do not raise it as a
|
||||
question, observation or suggestion — it has been asked and answered repeatedly.** Full rationale
|
||||
and the retired "can we delete the test VODs?" question: `ai.md` → YouTube Live API design
|
||||
constraints.
|
||||
|
||||
- **Kill the dev multi-instance affordance.** `Helpers/InstanceProfile.cs` is already entirely
|
||||
`#if DEBUG`, so a Release build ships as `DataRoot => DefaultRoot` / `WebViewDataFolder => null`.
|
||||
Nothing to do but *keep it that way* — and re-prove it:
|
||||
|
||||
@@ -1717,6 +1717,28 @@ These are the hard facts behind every decision. Full list in `TASKS.md`.
|
||||
to subscribers and serve as post-mortem review tapes; bulk-delete pre-GA. The unlock is a
|
||||
deliberate final-pass item in **TASK 36 (gold pass)**, wired with the dialog selection — never
|
||||
opportunistic. The PRIVATE badge keeps showing when the stream is actually private.
|
||||
- **⛔⛔ STOP. The always-Private lock is a DECISION, not a bug, not drift, not an open question.
|
||||
(Creator ruling, restated 2026-10-04 after being asked about it AGAIN.)**
|
||||
`privacyStatus = "private"` hardcoded in `YouTubeStreamService.CreateBroadcast` is
|
||||
**exactly right as written. Do not change it, do not "unlock" it, and — this is the part I keep
|
||||
getting wrong — do not raise it as a question, an observation, a suggestion, or a
|
||||
"heads-up".** The creator has now answered this more than once.
|
||||
- **What it becomes:** the hardcoded lock is replaced by a real, user-selectable
|
||||
visibility option in the Go-Live dialog — **at v1, not before.** Not at 1.0-candidate, not
|
||||
at GA prep, not opportunistically during any other unit.
|
||||
- **Why it exists:** pre-v1 test streams would otherwise publish VODs of a product still
|
||||
breaking, in public, to subscribers. Private keeps those tapes usable for post-mortem review
|
||||
while staying invisible to the channel's audience.
|
||||
- **Do not let these look like symptoms of the one they resemble.** All are working as designed:
|
||||
`privacy=private` in the broadcast diag line; the PRIVATE badge; `recordFromStart`/DVR ON;
|
||||
and the absence of any delete call in the codebase (there is no delete feature, by design at
|
||||
this stage — "can we delete the test VODs" is a *retired* question, answered 2026-10-04:
|
||||
`videos.delete` accepts `youtube.force-ssl` which we already hold, private is a visibility
|
||||
setting not a deletion lock, and anyway a broadcast that never reaches `live` never becomes a
|
||||
VOD at all).
|
||||
- **`CreateBroadcast:112` is not the unlock** — `UpdateBroadcastMetadataAsync` can already set
|
||||
visibility post-hoc, but that is the retrofit path, not the product change. The product change
|
||||
is the dialog option at v1.
|
||||
- **Full broadcast form (TASK 9 item 7) — RESCOPED 2026-09-01** — the core editable fields ship (since 2026-08-24) as the always-visible **Text drawer**: title, description, tags, visibility, made-for-kids, live-editable; scheduling ships as **TASK 34** (drawer ☑ Scheduled + adoption at Start). The old **Advanced tab is permanently out of product** (the 10% margin — see TASKS.md → "Out of product"): latency locked `low`, DVR/record-from-start locked on, embed/projection/CC/region fixed at sane defaults, invisible — every exposed field is a support ticket. `categoryId` is removed from `CreateBroadcast` (not a `liveBroadcast` field, silently ignored). Monetization enablement (if ever needed) rides the reward-events chain via `liveBroadcasts.update`, not a form field. Go-live order (TASK 9, shipped 2026-08-16):
|
||||
`BeginGoLive` → `PrepareAndStartLiveAsync` — ensure the reusable stream (`GetOrCreateReusableStreamAsync`,
|
||||
cache it), create the broadcast bound to it (`CreateBroadcast(..., stream.Id)` → `boundStreamId`),
|
||||
|
||||
Reference in New Issue
Block a user