Skip to content

chore(web): remove mecmua from the working tree (PR 2) - #9607

Open
usirin wants to merge 1 commit into
mainfrom
umut/9558-remove-retired-product
Open

usirin wants to merge 1 commit into
mainfrom
umut/9558-remove-retired-product

Conversation

@usirin

@usirin usirin commented Sep 21, 2026

Copy link
Copy Markdown
Member

Part of #9558. This is PR 2, after PR 1 and the operator's adopt confirmation.

Removes the retired publishing product in one change: routes, pages, worker services, three flags, schema, catalogs, fixtures, and documentation. The working tree and tracked filenames contain zero case-insensitive mecmua matches. The shared composer stays in use by Atölye; shell boot keeps an empty flag manifest and its typed user member.

The two previously renamed migrations are now zero-byte no-ops. All four Drizzle snapshots drop only the retired tables' entries, and the migration guard generated the second baseline. Every other migration stays byte-identical and in place. Every decision record stays, with unchanged frontmatter.

Pending outside this PR's local validation: the seven kept issues still need the operator's scope edits; integration and browser execution need the normal preview/CI run. Those acceptance criteria are not claimed complete below. No deployment, D1 command, dashboard change, issue closure, or milestone closure was performed by this work.

Production follow-up — operator only

After this PR lands, the operator may run DROP TABLE mecmua_post; DROP TABLE mecmua_subscription; outside this PR. That drop is destructive. The issue's recorded counts are mecmua_post = 3 rows and mecmua_subscription = 0 rows. The driver confirmed export outside the repo. This PR adds no drop migration and does not perform the drop.

Acceptance criteria — issue order

  • 1. PR 1 migration rename, byte-identical bodies. Merged PR 9565 renamed them to 0025_retired_table_a.sql and 0026_retired_table_b.sql, retaining both numeric prefixes and original SQL bytes.
  • 2. PR 1 generated baseline. PR 9565 committed the output of pnpm --filter @kampus/migrations-guard baseline; its two hashes retained their original values.
  • 3. PR 1 documented the adopt prerequisite. PR 9565's body requires the adopt deploy before PR 2 and explains that only the two recorded filenames change, with no SQL replay.
  • 4. Production adopt completed. The operator's confirmation reports new filenames, unchanged hashes/apply dates, no SQL replay, and green production. The agreed names are 0025_retired_table_a.sql and 0026_retired_table_b.sql; production was not queried by this work.
  • 5. Nine issues closed as not planned with a link back. Read-only GitHub verification found CLOSED / NOT_PLANNED and a comment pointing to 9558 on 2506, 2526, 3106, 3107, 3115, 3116, 3122, 7870, and 7871.
  • 6. Seven kept issues rescoped with explanatory comments. Still pending for the operator: Rite felt moments: end silent state changes (backlog-release signal, vouch-withdrawal + removal notice, incelemede honesty, terfi teach-at-unlock) #4307, terfi teach-at-unlock: promotion moment teaches Vouch first, grounded in read history #7062, apps/web date formatters are pinned to tr-TR, so an English reader sees Turkish dates #7659, The account-deletion confirmation phrase stays Turkish in the en locale #7663, The brand-noun test's whole-word count makes English copy drop the brand nouns #7665, App shell chrome keeps Turkish literals no i18n migration child owned #7723, Bookmark lives inside Pano despite being a distinct feature #8906. Read-only verification found the old mentions in all seven bodies and no 9558 cleanup comment. The user reserved board steps.
  • 7. Milestone 25 closed. Milestone 25 was closed before this branch's roadmap edit; read-only verification and the operator comment agree.
  • 8. Delete inventory group (a). All 47 actual deletions: 22 worker files + 8 components + 12 pages/styles/gate files + 2 catalogs + 3 flag tests. The issue's “48 deletions” includes an arithmetic error: the account test is a separate rename. The user approved that correction in this session before implementation. git diff --name-status --find-renames confirms 47 deletions and one rename.
  • 9. Preserve account locale coverage. Renamed the mixed locale test to account.locale.test.tsx, removed only the retired catalog assertions, retained both account tests; the client suite passes.
  • 10. Remove all group (b) wiring, including all three flags. App.tsx, routes, fate registry/views/layers/errors, fanned mutations, catalogs, wire codes, flags/keys.ts, flagship/resources.ts, and alchemy.run.ts are clean. SHELL_FLAG_KEYS is [] as const; flag declarations and factories are removed through source. Typecheck and the zero-match scan pass.
  • 11. Remove both schema tables and the account-deletion subscription statement. schema.ts no longer declares either table; Pasaport.ts keeps the mute and visibility cleanup. The integration test retains those seeds and assertions.
  • 12. Empty the renamed SQL, edit four snapshots, generate baseline again. Both SQL files are zero bytes. Each snapshot loses exactly 17 DDL entries; a parsed-JSON comparison proved every other entry and metadata field unchanged. No snapshot generator ran. Baseline output: wrote baseline for 38 migration(s); migration guard passes.
  • 13. Document the destructive operator drop. See “Production follow-up” above: table names, 3/0 row counts, export confirmation, and the outside-PR operator boundary.
  • 14. Clean group (c), keeping every decision record. All listed docs, glossary rows, patterns and seven decision records are edited. No .decisions/ file is deleted. A byte comparison of every record's frontmatter against the branch base found no change; decisions-index validates all 390 records.
  • 15. Remove the roadmap arc, paragraph and Mermaid node after milestone closure. All three are gone from ROADMAP.md; roadmap-guard passes I1–I5 with three arc rows.
  • 16. Apply the approved two-product wording. ROADMAP.md:7 keeps the existing sözlük/pano glosses; DEVELOPMENT.md:3 names the same two products. Authority: founder wording approval.
  • 17. Re-ground both boot tests on user. shell-boot-parity.unit.test.ts covers the shared me resolver's fresh identity, trusted standing, serialization, and signed-out null. 29-edge-shell-boot-journey.spec.ts now checks the user pill's geometry, signed-in first paint, and absent-payload fallback. Unit tests pass; Playwright lists all three tests. Browser execution remains pending.
  • 18. Empty content scan at this PR head. git grep -i mecmua produces no output, exit 1. Main's post-merge verification remains with the operator; this PR is not merged.
  • 19. Empty tracked filename scan. git ls-files | grep -i mecmua produces no output, exit 1, after staging the deletions and rename.
  • 20. Typecheck, lint, unit and integration tests pass. Typecheck, lint, web unit/client tests, and touched package tests pass; results below. Integration execution is pending: the configured harness deploys Cloudflare stacks and uses remote D1, prohibited in this task.
  • 21. Brand nouns and catalog parity. All three brandNouns.unit.test.ts assertions pass: nonempty coverage, equal catalog key sets, identical brand nouns.
  • 22. Turkish catalog split. Both catalog-split.unit.test.ts assertions pass, including a real build's separate English chunk.
  • 23. App build. pnpm --filter @kampus/web build passes (built in 8.20s).
  • 24. Required guards green on PR 2. All five pass locally: roadmap, migrations, i18n, doc links, decisions index. Exact results below. Their GitHub checks are pending when this PR opens.

Validation results

Run in this branch's isolated checkout, using package-owned scripts. The final targeted unit run covers the boot changes made while the full suite was running.

$ pnpm typecheck
Tasks: 31 successful, 31 total
Cached: 26 cached, 31 total
Time: 23.31s

$ pnpm lint
Checked 3846 files in 5s. No fixes applied.
Found 10 warnings.
(exit 0; existing warnings in unchanged files)

$ pnpm --filter @kampus/web test:unit
Test Files 323 passed (323)
Tests 2812 passed (2812)

$ pnpm --filter @kampus/web test:client
Test Files 72 passed (72)
Tests 396 passed (396)

$ pnpm --filter @kampus/web test:unit src/i18n/brandNouns.unit.test.ts src/i18n/catalog-split.unit.test.ts src/flags worker/features/flagship/shell-boot-parity.unit.test.ts worker/features/fate-live/fanned-mutations
Test Files 7 passed (7)
Tests 46 passed (46)
brandNouns: 3 passed; catalog-split: 2 passed

$ pnpm --filter @kampus/composer test
Test Files 4 passed (4)
Tests 14 passed (14)

$ pnpm --filter @kampus/fabrika-cli test src/campaign src/triage
Test Files 31 passed (31)
Tests 748 passed (748)

$ pnpm --filter @kampus/migrations-guard test
Test Files 2 passed (2)
Tests 37 passed (37)

$ pnpm --filter @kampus/web build
built in 8.20s
(existing chunk-size/plugin-timing warnings)

$ pnpm --filter @kampus/web test:e2e 29-edge-shell-boot-journey.spec.ts --list
Total: 3 tests in 1 file
(discovery only, not browser execution)

$ pnpm --filter @kampus/migrations-guard baseline
migrations-guard: wrote baseline for 38 migration(s)

$ pnpm --filter @kampus/migrations-guard check
migrations-guard: OK — consistency, ordering, and immutability hold.

$ pnpm --filter @kampus/fabrika-cli cli guard roadmap-guard check
guard roadmap-guard check: in sync — 3 arc row(s) + 31 campaign row(s) validated against 53 milestone(s), 6 campaign(s) active (I1–I5 all green).

$ pnpm --filter @kampus/fabrika-cli cli guard i18n-guard check
guard i18n-guard check: clean — 205 file(s) scanned, 12 carrying an allowed Turkish literal, none over its ceiling.

$ pnpm --filter @kampus/fabrika-cli cli guard decisions-index validate
guard decisions-index validate: all 390 .decisions/ records carry the four index fields, a filename number matching their `id`, and no duplicate id

$ lychee --offline --no-progress --root-dir <checkout> --files-from <tracked-markdown-list>
7816 Total; 3557 Unique; 4820 OK; 0 Errors; 2996 Excluded
(the same offline options and tracked Markdown input as doc-links.yml)

$ git grep -i mecmua
$ git ls-files | grep -i mecmua
(both outputs empty; both exit 1 = no matches)

$ git diff --check
(no output; exit 0)

LAW-SOURCE: manifest-prose (design-system-manifest.md). The nav retains the sözlük/pano destinations; rendered preview evidence is pending. Governance and code-owner review remain separate PR gates.

Deviations

  • Scope correction — Said: AC8 says 48 deletions. Did: deleted all 47 enumerated files and renamed the account test separately. Why: 22 + 8 + 12 + 2 + 3 = 47; the user approved this correction before editing. Disposition: complete; no extra deletion invented.
  • Pending operator work — Said: AC6 asks for seven issue scope edits. Did: read them and recorded the pending work above. Why: the user reserved board steps. Disposition: operator follow-up; AC6 remains unchecked.
  • Validation limit — Said: AC20 includes integration tests, and the UI guidance asks for rendered evidence. Did: ran offline unit/client tests, builds, guards, and Playwright discovery; did not execute integration or browser journeys. Why: the integration harness deploys stacks and touches remote D1, and the user prohibited deployments/D1 commands. Disposition: preview/CI execution pending; no integration or rendered PASS claimed.
  • Tooling choice — Said: Fabrika build helpers require a build/ branch. Did: used the user's required umut/ branch and direct git/gh for commit, push and PR creation, with normal hooks. Why: the explicit task instruction takes precedence over the helper's branch convention. Disposition: package-owned validation and the claim check were retained; no merge or auto-merge requested.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview deployed

@usirin

usirin commented Sep 21, 2026

Copy link
Copy Markdown
Member Author

governance: PASS @ d2bf9b9 content:28d8176a739b — no contradiction, no weakening

Scope

governance scope derived required at this head over 5 declared roots; 7 files land under
.decisions/, all modified, none added, none deleted. self false, so the §4 fence did not
apply and this round judged by the head's rules.

The gate half — does this quietly weaken a guard

governance guards at this head: no-anchors-in-reach, 0 — 117 files scanned, 69 compared
block-by-block against the base, and no anchored invariant is in this diff's reach. The check
ran and had nothing to weaken.

Read by hand alongside it, because a removal PR is the shape where a guard goes quiet rather than
red:

  • No guard allow-list or ceiling is raised. portability-guard check is clean at this head
    (1471 files, 337 references, none above a declared ceiling), and the portability /
    docLeakExempt settings are untouched.
  • packages/migrations-guard/migration-hashes.json changes exactly two rows, and both new values
    are e3b0c442…b855 — the SHA-256 of the empty string, i.e. generated from the now-empty files,
    not hand-typed. Every other row is byte-identical. migrations-guard check passes
    (consistency, ordering, immutability).
  • The immutability guard is satisfied, not softened: its baseline moved by the sanctioned
    baseline script, which is what AC12 asks for, and the guard still reds on any later drift.
  • roadmap-guard check green (I1–I5, 3 arc rows / 31 campaign rows / 53 milestones),
    i18n-guard check clean, decisions-index validate green over all 390 records.
  • The three Flagship flags are retired by deleting their declarations and their yield* lines, not
    by an exemption, a dashboard step, or a widened default. No DROP TABLE, DELETE FROM or
    ALTER TABLE is added anywhere in the diff.

No weakening found.

The corpus half — does this contradict standing law

No decision record is added, so there is no subject the ranking sweep exists to rank; the
corpus half is a hand read, and I ran governance sweep --record 0173 at this head as a spot
check. It returned shortlist over 323 uncited live-accepted records; the top rows (0250, 0348,
0114, 0313, 0047) are mechanically adjacent on vocabulary and none of them speaks to what this
diff decides.

The questions this diff answers, asked against the corpus:

  1. May a landed migration's recorded name keep its history while its body is emptied? Yes, and
    nothing standing says otherwise. The drift refusal this repo patched in (ADR 0309 amendment,
    Renaming an applied D1 migration id re-runs it on stages that already applied it #7055) classifies on recorded ids versus ids on disk, never on content: both names are on
    disk under their PR-1 names, so orphaned is empty and the check returns before any strategy is
    consulted. Applied-detection downstream is name-keyed, so production never re-reads the emptied
    bodies.
  2. Does emptying them contradict ADR 0309's frozen-flat-history rule? No — no file is deleted,
    renamed or reordered here, the 0025/0026 prefixes stand, and migrations-guard check agrees.
  3. Does removing the mecmua_subscription sweep contradict ADR 0097's account-deletion rule? No.
    The rule is "a per-user relation or preference row keyed by the deleted user's id is deleted in
    the same atomic batch"; the table ceases to exist, so the rule loses a subject rather than an
    arm. Pasaport.ts keeps the user_mute and caylak_visibility_preference deletes, and the
    integration test keeps their seeds and assertions.
  4. Does the empty shell-key manifest contradict ADR 0179's geometry law? No. The law is
    "shell-critical = state whose wrong value moves geometry at first paint"; a manifest with no
    members satisfies it vacuously, and the typed user member (ADR 0185) still carries the
    geometry-critical half. The founder settled the scope of this on the issue (question 1, keep the
    machinery with an empty flag set) — named here as evidence, not as the ground of this verdict.
  5. Does any of the seven records lose id, title, status or date? No. Verified against the
    base; decisions-index validate re-confirms all four fields on all 390.

No contradiction with standing law found. Verdict PASS.

Named, and routed rather than judged here

Three of the seven record edits go past removing a mention and restate the record's own grounds.
This is not a contradiction with standing law and not a weakened guard, so it is not a
governance finding — I am naming it because it is corpus-shaped and it belongs to a human, and I
have routed the text half of it into my review-doc verdict at this head:

  • 0173 — "a systemic blind spot with three confirmed instances" becomes "the reactions
    example shows a systemic blind spot", and "the last two sat inside a single epic — which is
    exactly why plan-epic's story-coverage invariant did not catch them" becomes "the gap can
    occur
    inside a single epic … cannot catch it". A recorded empirical finding that grounds a
    standing gate is restated as a hypothesis.
  • 0176 — one of the verdicts in a list introduced as "Ratified on Decision: first-principles justification — what is the topbar FOR, and which elements earn their place #2591" is deleted and the
    remaining two are renumbered; the heading drops from "The seven element verdicts" to "The element
    verdicts".
  • 0275 — a recorded measurement ("that matcher hits 20 sites", "16 are the feature
    services") is re-derived by subtraction to 17 and 15 rather than re-counted.

The founder's ruling on #9558 authorises "mentions edited out" with no record deleted, and these
three edit rationale rather than mentions. The repo's own visible convention for changing a landed
record's substance is a new amending record plus a status line (0204 amends 0189, 0218 amends
0100, 0350 reads amended-in-part by 0351, CLAUDE.md cites 0129 "amended by 0305"). I found no
standing record
that makes a landed body immutable, so I am not calling this a contradiction —
inventing that law here is exactly what this gate must not do. It is a call for the founder.

Bound to the head read above; nothing outside the verbs' own reads was treated as authority.

@usirin

usirin commented Sep 21, 2026

Copy link
Copy Markdown
Member Author

review-code: FAIL @ d2bf9b9 content:28d8176a739b — three stale-text residues in live code

Judged at d2bf9b93afae7891825a84303fc252b22fd1bcf1, in a worktree seated detached at that commit
and read back off git before every fence. Part of #9558, so unmet criteria are named as facts,
not as failures.

The short version

The removal itself is excellent, and I could not break it where it was most likely to break. The
FAIL is three pieces of residue the deletion left behind in live code — not a defect in the
removal.

What I proved, and how

CI at head: settled / green — 49 check runs, 28 of 43 repo-authored workflows inspected
this SHA. Integration and browser tiers are read off that run, not reproduced locally.

Editing applied migrations (the highest-risk half) — clean, and here is the proof.

  • Both bodies are zero bytes, and both new hash rows read e3b0c44298fc1c149afbf4c8996fb924 27ae41e4649b934ca495991b7852b855 — the SHA-256 of the empty string. That is the baseline script's
    output, not a hand-typed value. Exactly two rows change; every other row in
    migration-hashes.json is byte-identical.
  • migrations-guard check at head: OK — consistency, ordering, and immutability hold.
  • A fresh database still migrates cleanly. Read in the pinned alchemy source and the repo's
    patch: applyAlchemyFormat batches [...record.statements, insertSql(...)], so a record with
    zero statements still sends its bookkeeping INSERT — 0025/0026 apply as recorded no-ops and the
    resulting schema is every table minus the two. The D1 executor filters empty statements before
    joining, so a zero-byte file cannot produce a malformed query.
  • Production cannot trip the drift refusal. detectMigrationsDrift classifies on recorded
    ids versus ids on disk and never on content (patches/alchemy@2.0.0-beta.77.patch): both
    names are on disk under their PR-1 names, so orphaned is empty and the check returns before any
    strategy is read. Applied-detection downstream is name-keyed, so the emptied bodies are never
    re-read on production.
  • The four hand-edited snapshots are internally consistent, proven by running the generator.
    drizzle-kit generate at this head emits
    ba1fead18b915b2c887ae5d60534bf76eccca9eddee0a57b8f0b238f3454c871; the same command at the base
    commit emits the identical SHA-256. Neither output contains a single mecmua byte, and
    neither contains a surprise DROP or CREATE for the removed tables. (Both outputs do carry a
    pre-existing user_profile table rebuild — identical at base and head, so it is drift this PR
    neither caused nor touched. Filed separately, not a finding here.) All four snapshots parse, are
    pure deletions of 173 lines each, and hold zero mecmua references. Probe artifacts removed;
    the tree is clean.

Nothing left behind still reaches the removed product. git grep -i mecmua at head returns
nothing, exit 1, and so does git ls-files | grep -i mecmua. Structurally: pnpm typecheck in
apps/web is 0 errors over 993 files, which is what proves no dangling import, route, fate
registry entry, layer, view or wire code survives. The fate module registry, worker-routes.ts,
fanned-mutations.ts, flags/keys.ts, both i18n indexes, alchemy.run.ts and the Flagship
declarations are all clean by inspection. No sitemap exists to stale.

Shared code kept on purpose is kept. @kampus/composer survives with three live consumers
(LabComposerPage.tsx, Composer.exhibit.tsx, Composer.exhibit.live.tsx). SubnavShell and
ProductSubnavLayout survive with divan, pano and sözlük on them.

No production step hides in the diff. No DROP TABLE, DELETE FROM or ALTER TABLE is added
anywhere. The three flags go by deleting their resources.ts declarations and their three
yield* lines — IaC removal, no dashboard step. The destructive drop is disclosed in the PR body
as an operator step outside this PR, with the 3/0 row counts.

No scope creep. 47 deletions + 69 modifications + 1 rename = 117, and every one of the 69
modified paths is named in the issue's inventory: 46 in group (b) (the 28-row table covers 30
files, plus 5 test/fixture rows, 6 composer, 4 fabrika-cli, 1 hashes), 16 in group (c), 6 in group
(d), plus shell-boot-parity.unit.test.ts, which group (b) names explicitly as collateral. I found
nothing edited the inventory does not explain. The body's 48→47 arithmetic correction is right:
22 + 8 + 12 + 2 + 3 = 47.

SHELL_FLAG_KEYS going empty does not break consumers, and the e2e spec still tests something
real.
ShellFlagKey and BootMemberKey collapse to never, and typecheck stays green.
29-edge-shell-boot-journey.spec.ts is genuinely re-grounded rather than gutted: the first test now
signs up, seeds __BOOT__ from the edge's own resolved user, and asserts the user pill's bounding
box is unmoved across first paint → hydrate → settle with CLS still effectively zero. That is the
same invariant the old test carried, moved onto the member that still exists.
resolveBootFlag's replacement test is stronger than what it replaced — it runs over all 17
DECLARED_FLAGS and asserts each stays on the fetch path even when the payload carries its key.

Targeted unit run at head: 11 files, 145 tests, all passing — brandNouns.unit.test.ts,
catalog-split.unit.test.ts, all of src/flags, worker/env.unit.test.ts,
shell-boot-parity.unit.test.ts, shell-boot.unit.test.ts, dev-override.unit.test.ts,
wireCodes-per-class.unit.test.ts.

Findings — why this is a FAIL

1. readShellFlags's docblock now states a false reason for its own export.
apps/web/worker/features/flagship/shell-boot-route.ts:53-56 reads:

Exported so the parity test reads the __BOOT__ shell flags through the exact seam the handler
uses (ADR 0179 AC2).

The rewritten shell-boot-parity.unit.test.ts no longer imports readShellFlags at all. The only
caller is now line 109 in the same file, so the export has no reason left and its stated one sends
the next reader looking for a test that does not exist. Either drop the export or say what it is
for now. This repo's rule is that a comment carries an invariant the code cannot express; this one
carries a fact that is no longer true.

2. readBootMember is left exported and uncallable. apps/web/src/flags/boot.ts:22 is
export function readBootMember(key: BootMemberKey), and BootMemberKey is now never, so no
argument can satisfy it. The diff deleted its entire describe block from boot.test.ts, so it is
also untested. Typecheck stays green only because nothing calls it — this is dead API that reads as
live. Remove it, or keep it and say in a comment that it is the re-entry point for a refilled
manifest.

3. shell-keys.ts's docblock explains the empty manifest with the wrong reason. Lines 10-14
still read "Only the flags whose wrong value moves geometry at first paint … The Subnav-zone seam
graduated and was retired (ADR 0136), so no flag shapes those zones any more" above
SHELL_FLAG_KEYS = [] as const. The manifest is empty because this PR removed its last two members,
not because of ADR 0136, and nothing says the empty set is deliberate. A reader who finds an empty
array under a comment about a different retirement will reasonably read it as a mistake.

Named, not blocking

Deviations

deviation-disclosure: PASS. The section is present, and both entries match substance I verified
independently — the 47-vs-48 arithmetic checks out, and AC6's pending state is real. I found no
undisclosed deviation, which means nothing undisclosed that this gate could see, not that none
exists.

Verdict-written: 2026-09-21T03:17:49Z

@usirin

usirin commented Sep 21, 2026

Copy link
Copy Markdown
Member Author

review-doc: FAIL @ d2bf9b9 content:28d8176a739b — ADR 0179 left self-contradictory by its own edit

Judged at d2bf9b93afae7891825a84303fc252b22fd1bcf1, in a worktree seated detached at that commit
and read back off git before every fence. 17 files class doc.

What holds

The doc edits are surgical and, with one exception, correct. Every modified doc path is named
in the issue's inventory group (c); nothing is edited that the inventory does not explain.

Guards, all green at this head. roadmap-guard check — in sync, I1–I5 all green, 3 arc rows

  • 31 campaign rows against 53 milestones, which is what milestone deps: effect→beta.78, alchemy→beta.52, drizzle→1.0-rc.3 (single coordinated bump) #25 being closed first bought.
    decisions-index validate — all 390 records carry the four index fields, filename numbers match
    id, no duplicates. i18n-guard check — clean. portability-guard check — clean, 337 references,
    none above a declared ceiling (owed because the diff touches packages/fabrika-cli/src/).

AC14 holds. No .decisions/ file is deleted; all seven are modified. id, title, status
and date are intact on every one, re-confirmed by decisions-index validate.

AC15 holds. The Mecmua v2 arc row, its paragraph and the arc_mecmua_v2 mermaid node are all
gone from ROADMAP.md, and the landing follows milestone #25's closure, which is why I3/I5 are
green rather than red.

AC16 holds, on the evidence it names. The marked criterion points at the founder's answer to
open question 3, recorded on #9558 on 2026-09-20: "two products: sözlük and pano", keeping each
product's existing gloss. ROADMAP.md:7 reads "two products — sözlük (the community of
definitions) and pano (the shared board of links and posts)" and DEVELOPMENT.md:3 reads
"kamp.us's two products (sözlük and pano)". Both match the ruling, both keep the glosses, neither
still says three.

Editorial craft (writing-for-agents): the surviving prose reads clean. The glossary's
shell-state row was rewritten rather than merely trimmed — "The flag manifest is currently empty;
the typed user member (ADR 0185) supplies session identity" — which is the right instinct, and it
is the one place the PR says out loud what the empty manifest means.

Findings — why this is a FAIL

1. ADR 0179 §1 now contains a sentence the diff itself made false.
.decisions/0179-edge-resolved-shell-state-boot-contract.md:56-60, one paragraph, after the edit:

That is exactly: nav-shaping flags + session presence (signedIn) … The edge payload is
therefore four booleans and no fate data.

"Four" counted the three named flags plus signedIn. The diff replaced the closed enumeration with
an open category three lines above and left the number standing, so the record now asserts a
payload size with no antecedent — and the real payload at this head carries zero shell booleans.
This is a live status: accepted record, and this repo tells agents to check the governing decision
before treating a source/guidance difference as intended design; an agent reading §1 today is told
something false about the boot contract. It is a one-line fix, and it sits inside the paragraph the
diff edited, which is why it blocks.

The same edit also weakens the sentence's form: "That is exactly: nav-shaping flags" applies a
closed-set word to an unenumerated category. Whatever replaces "four booleans" should settle both.

2. ADR 0179's per-instance resolution table is left asserting a route that cannot exist.
Line 108 survives as the table's only remaining flag row:

| PHOENIX_NAV_IA — topbar restructure | shell-key manifest → __BOOT__ |

git grep PHOENIX_NAV_IA over apps/ and packages/ returns nothing — that flag is not in
flags/keys.ts and not anywhere in the code — and the manifest it claims to route through is now
[] as const. The flag's absence pre-dates this PR, so this is not a regression the diff caused;
what the diff did is delete the row's two siblings and leave it standing alone, so the table now
reads as if PHOENIX_NAV_IA is the live shell key. Resolve it while the paragraph above it is being
fixed, rather than leaving the record half-corrected.

Named for the founder, not judged here

Three of the seven record edits go past "mentions edited out" and restate the record's own grounds.
I posted the full reasoning on the governance namespace at this head; the short form:

  • 0173 — "a systemic blind spot with three confirmed instances" becomes "the reactions
    example shows a systemic blind spot", and "the last two sat inside a single epic — which is
    exactly why plan-epic's story-coverage invariant did not catch them" becomes "the gap can
    occur
    inside a single epic … cannot catch it". A recorded empirical finding that grounds a
    standing gate is rewritten as a hypothesis. Its §4 heading still reads "the concrete instances"
    (plural) above one instance.
  • 0176 — one of the verdicts in a list introduced as "Ratified on Decision: first-principles justification — what is the topbar FOR, and which elements earn their place #2591" is deleted and the
    remaining two renumbered; "The seven element verdicts" becomes "The element verdicts".
  • 0275 — a recorded measurement ("that matcher hits 20 sites", "16 are the feature
    services") is re-derived by subtraction to 17 and 15 rather than re-counted at a real head.

The founder's ruling on #9558 authorises editing mentions out with no record deleted, and the repo's
visible convention for changing a landed record's substance is a new amending record plus a status
line (0204 amends 0189, 0218 amends 0100, 0350 reads amended-in-part by 0351). I found no standing
record making a landed body immutable, so I am not treating this as a contradiction — it is a call
the founder should make, and it is the reason I am naming it rather than routing it into a fix.

0097 and 0182 also recount, but both stay truthful about what they now describe ("The remaining
tables are…", "The remaining examples from the live subnav audit…"), so I am not raising them.

Nits, non-blocking

  • DEVELOPMENT.md:3 uses a typographic apostrophe in "kamp.us's" where the same sentence's "it's
    this repo's engine" uses a straight one. Cosmetic, worth matching.
  • .decisions/0179's line 57 now runs past the wrap width its neighbours hold, a side effect of the
    in-place edit.

Deviations

deviation-disclosure: PASS — the section is present and substantive, and its two entries match
what I verified independently. Nothing undisclosed that this gate could see.

Verdict-written: 2026-09-21T03:18:35Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant