Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .agent/lessons/INDEX.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Lessons — always-on index
last-curated: 2026-07-17
last-curated: 2026-07-29

These fire every session (auto-loaded via CLAUDE.md). Topic bodies live in `topics/` — read a shard only when its pointer matches. Cap: 10 always-on lessons; when full, demote the least-actionable into a shard rather than deleting it.

Expand All @@ -10,5 +10,7 @@ These fire every session (auto-loaded via CLAUDE.md). Topic bodies live in `topi

- `COMPLETED_WORK.md`'s "shipped" is not owner-verified-complete — never write a public wiki changelog entry or delete a source plan on its word alone (2026-07-18) — during the release doc reduction, COMPLETED_WORK listed HuggingFace voice, AI casting, and the recording-cue expansion as "shipped/live/all shipped." Acting on that, I wrote wiki changelog entries for two and marked their plans deletable. Owner review corrected all three: HF is untested/needs sign-off, AI casting is placeholder/future in the app, recording-cue awaits the owner's portrait-image generation. The changelog entries were reverted; no plan had been deleted (the ledger gate held). **Apply:** treat "shipped" in a summary doc as a claim to verify, not a fact. Before writing the history-of-record (wiki changelog) or deleting a plan, confirm completion against on-disk reality AND owner sign-off — "code + endpoints landed" ≠ "feature complete." A feature marked future/placeholder in the app, or awaiting an owner action, is not a changelog entry and its plan stays. The consolidation ledger (`design-docs/plans/active/final_release/21_*`) is the gate that made this recoverable — keep deletions gated on it.

- `studio-2.0` squash-merges, so a branch's commit SHAs and subjects NEVER appear in its history even when the work fully landed (2026-07-29) — reconciling 32 abandoned branches, a first pass matched commit subjects against `git log origin/studio-2.0` and reported all 32 as unlanded, which was false for nearly all of them; `git rev-list --cherry-pick` was equally useless, because a squash rewrites the patch-id of the whole branch into one commit. Reachability (`--contains`, `merge-base --is-ancestor`) is also unreliable for the same reason, and inflates the count: N branches holding one shared squashed trunk each read as N distinct bodies of unlanded work. **Apply:** to answer "did this branch land", read what the commit changed and then read the CURRENT content of those same files on `origin/studio-2.0` — for a deletion, check the deleted file/test name is also absent there; for an edit, compare the file's content. Only content answers it. Corollary for the reverse direction: a branch whose files no longer exist on `studio-2.0` at all is usually obsolete-by-restructure, not unlanded. Worked verdicts for 32 branches: `.agent/reports/2026-07-29-reconcile-*.md`.

## Topic pointers (read on match)
<!-- Add a line here when a lesson needs more than one sentence: "<trigger keywords> → topics/<name>.md" -->
3 changes: 2 additions & 1 deletion .claude/agents/roster.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@
"audio-quality verdicts",
"information-architecture calls",
"release-facing defaults",
"merging a PR, cutting a release, posting outside this repo",
"merging a PR (not delegated while studio-2.0 is the staging target; a per-task grant expires with that task, OD-0020)",
"cutting a release, posting outside this repo",
"amending CLAUDE.md's binding sections or the mandate"
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# OD-0020: Merge authority stays with the owner while `studio-2.0` is the staging target
Status: accepted Date: 2026-07-29
Scope: `CLAUDE.md` (ask-first list); `.claude/agents/roster.json` (`unowned_surfaces.owner_only`)

Context: On 2026-07-18 the owner did grant merge authority in conversation ("I give you authority to
merge when you deem it ready"), and it was used once, on PR #163. That grant was recorded only in an
untracked memory file; `CLAUDE.md` and `roster.json` were never updated and continued to list merging as
ask-first, so the estate held two contradictory answers for eleven days. The 2026-07-29 retrofit surfaced
the contradiction and the owner resolved it by **narrowing the grant**: he authorized merging for one
specific task (landing PRs #174, #176, #177) and stated he retains the authority generally, because
`studio-2.0` is a temporary staging line and he is particular about nothing merging to the wrong branch
or being destructive while that is true.

Decision: "Merging a PR, cutting a release, or posting anywhere outside this repo (issues/PR comments on
someone else's thread, external services)" remains on the ask-first list. Opening a PR, pushing a branch,
and choosing draft-versus-ready stay do-then-report; only the merge itself is withheld. A per-task
authorization covers that task and expires with it: it is never read forward into a standing grant.

Consequences: Narrows the real 2026-07-18 grant rather than denying it happened. Two lessons sit inside
that: a grant recorded only in untracked memory produced a contradiction nothing could detect, which is
the case for writing rulings into tracked files (OD-0002's closeout discipline), and a conversational
grant can be narrowed later without either party having been wrong at the time. Blocks two specific
reflexes: citing a past one-off
authorization as ongoing permission, and merging a correct-looking change to the wrong base while
`studio-2.0` is standing in for `main`. Note the asymmetry this preserves: Ada can still get work all the
way to a reviewed, mergeable PR without asking, so the cost of the restriction is one message at the end,
not a slower pipeline. This is also the reason the change that records this ruling could not be
self-merged.

**This expires by its own terms.** The owner stated he will loosen the mandate once `studio-2.0` merges
into `main`. That event, not a date, is the trigger to revisit — and revisiting means asking him, not
assuming the loosening is automatic.

Disconfirming evidence: Merges are consistently routed to the owner as required, and the ask turns out to
be pure latency — every request is approved unread over a sustained period, with no merge ever redirected,
delayed, or rejected on inspection. That would show the gate is catching nothing the PR review already
caught. Note what does **not** count: an agent merging anyway is evidence about the agent, not the rule;
and a long quiet stretch with no wrong-base incident may be the rule working rather than the rule being
unnecessary.
1 change: 1 addition & 0 deletions .claude/decisions/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ the other.
| [OD-0017](0017-orchestration-layer-edited-only-from-rooted-session.md) | accepted | CLAUDE.md orchestrator section; .claude/agents/ profiles; .claude/decisions/; roster.json; roster.html | This repo's orchestration layer is edited only from a session rooted in this repo | yes | — |
| [OD-0018](0018-worktrees-are-not-the-default-and-are-removed-on-merge.md) | accepted | `CLAUDE.md` (Orchestrator identity & mandate); `.agent/rules/memory-queue.md`; agent dispatch decisions | Worktrees are not the default workflow, and a worktree is removed when its PR merges | yes | — |
| [OD-0019](0019-a-functional-affordance-survives-a-redesign-only-if-defended.md) | accepted | `.claude/agents/junia-designer.md` (designer convictions); any redesign, visual migration, or screen-parity work | A functional affordance survives a redesign only if it is defended explicitly | yes | — |
| [OD-0020](0020-merge-authority-stays-with-the-owner-until-studio-2-0-lands.md) | accepted | `CLAUDE.md` (ask-first list); `.claude/agents/roster.json` (`unowned_surfaces.owner_only`) | Merge authority stays with the owner while `studio-2.0` is the staging target | yes | — |
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Do-then-report (no permission needed):

Ask-first (unchanged):

- Merging a PR, cutting a release, or posting anywhere outside this repo (issues/PR comments on someone else's thread, external services).
- Merging a PR, cutting a release, or posting anywhere outside this repo (issues/PR comments on someone else's thread, external services). **Merge authority is the owner's and is not delegated (OD-0020)** — `studio-2.0` is a temporary staging line, and the risk being managed is a correct-looking change landing on the wrong base. A per-task authorization to merge covers that task only and expires with it; do NOT read a past one-off grant forward as standing permission. Take the work all the way to a reviewed, mergeable PR without asking, then hand over the merge.
- Destructive or hard-to-reverse operations: data deletion, schema migrations, contract version bumps beyond the task at hand, reversing an ADR.
- Amending CLAUDE.md's binding sections or this mandate itself.
- Perceptual and product judgment: audio-quality verdicts, information-architecture changes, release-facing defaults — stage the evidence (A/B samples, screenshots, diffs) for the owner; never assert the verdict.
Expand Down
16 changes: 16 additions & 0 deletions design-docs/plans/REMAINING_TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ observation is missing.
spec→provenance citation map: [active/final_release/20_stale_docs_retirement.md](active/final_release/20_stale_docs_retirement.md)**
(Section A already done; Section B is the repoint-then-delete remainder).

## Test-suite hygiene

- [ ] **Finish the 2026-07-10 low-value test pruning (~40 tests still present).** The audit landed
(`active/final_release/audits/`) and most of its execution branches merged, but three never did:
Voices/VoiceLab (`751e6bd4`), backend DB (`7753b3fd`), and misc frontend pages (`f3493c36`), all
on `origin/studio2/phase-12.5-style`. The work is pushed and safe, just unmerged.
**Do not cherry-pick** — all three conflict in the same three VoiceLab test files
(`TestSection.test.tsx`, `VariantsSection.test.tsx`, `VoiceIconControls.test.tsx`), which have
moved on since. Redo the deletions against today's files instead, using each commit as the list
of what to remove and re-checking each against `testing-standards.md` R1–R4 before deleting
(a test that was low-value in July may have become load-bearing since). Rough cost: an hour.
Worth doing: the vitest suite leaks memory, so a smaller suite is a real win.
Evidence and per-branch verdicts: `.agent/reports/2026-07-29-reconcile-codeql-and-redundant.md`.
- [ ] Fix the hardcoded-style violation at `frontend/src/pages/Voices/.../ArchetypeQuickPick.tsx:242`
(found in passing during the 2026-07-29 reconciliation; unrelated to the branches assessed).

---

*When every item above clears and Stage 6's tag lands, this file should be empty — retire it and
Expand Down