Planning bug: the public write surface's session-gate count was measured over /p/* and generalised — "one of ten" is five of thirteen, and the request intake was recorded as anonymous when it has never been
Found while running MOTIR-4108 (the ADR amendment) under motir run MOTIR-3877, on motir-core origin/main 8d80ac8db, 2026-09-02. The correction is already applied — AMENDMENT 3 §A of docs/decisions/public-surface-hosts.md carries the re-measurement, and the three falsified cards are amended on the record. This card is the telemetry.
The two errors
1 · A count taken over one subtree, quantified over the whole surface.
MOTIR-3877's re-scope table (2026-09-01) reads:
"six of those routes call
getSession()" → Re-measured: ONE of ten is session-gated (follow, a write).
MOTIR-4108's affordance table inherited it. Re-measured with the CLAIM's own predicate — every route.ts under both app/api/public and app/api/public-requests, classified by whether a missing session is a 401:
| class | count |
|---|---|
| no session read at all | 2 (explore, categories) |
optional actorUserId ?? null | 6 (p/[identifier], items, tree, roadmap, changelog, subscribe) |
| REQUIRES a session | 5 (p/[identifier]/follow, projects/[projectId]/requests, …/requests/duplicates, public-requests/[id]/upvote, public-requests/[id]/comments) |
git grep -c . is not the instrument; the enumeration is. The original count was correct about app/api/public/p/* and the sentence it produced was about the public write surface — the exact X ⊋ Y shape run.md's re-measure the PREDICATE rule names.
2 · An affordance recorded as anonymous that is session-gated.
MOTIR-4108's table: "submit a feature request (POST /api/public/projects/{projectId}/requests) | already anonymous". The route's own header comment says the opposite:
"A LOGGED-OUT caller is rejected 401 (sign-in-to-act — reading a public project is anonymous, but every WRITE needs an account)"
requireCompliantSession() is called on it and on its duplicate pre-check. Reading a public project is anonymous; posting to one never has been.
What it cost, and what it would have cost
Nothing yet, because AMENDMENT 3 re-measured before deciding. Had it not: error 2 would have shipped an anonymous submit form on motir.co against a route that 401s every caller, and the E2E written to assert it (MOTIR-4122 AC 3) would have been written to a behaviour that does not exist — discovered in a browser, in a second repository, at the end of the story.
The falsified cards, all amended in the same pass
| card | clause | disposition |
|---|---|---|
| MOTIR-3877 | verification recipe step 4 — "Submit a feature request as an anonymous visitor" | amended: submission is sign-in-to-act, via AMENDMENT 3 row 6's hand-off |
| MOTIR-4108 | its own affordance table, two rows | superseded by AMENDMENT 3 §A, which records both errors |
| MOTIR-4122 | AC 3 — "The anonymous feature-request submission is exercised for real" | amended to the hand-off, both session states |
The takeaway
A re-measurement that CORRECTS an earlier number inherits the earlier number's scope unless it restates the predicate. "Re-measured: ONE of ten" reads as a careful correction — it names a method, a count and a denominator — and it is a correct measurement of a subtree presented as a property of a surface. The denominator is the tell: ten was the count of app/api/public/** route files at the moment of writing, and the sentence is about every route a public page can write to.
Acceptance criteria
motir-meta'splan-rules/carries the corollary: a correction inherits the corrected claim's scope, so a re-measurement restates the predicate and the denominator, not only the number — placed with the existing enumeration rule rather than as a new one.- The rule covers a FLOW, not only a population. A re-measurement of a multi-endpoint flow enumerates EVERY endpoint the flow touches — the third occurrence (see the comment of 2026-09-02) re-measured the submit correctly and left its duplicate pre-check unread, and the wrong half reached a merged design asset before anyone noticed.
- The rule cites this card and the three errors above as its fixture.
Context refs
motir-core/docs/decisions/public-surface-hosts.mdAMENDMENT 3 §A — the re-measurement, on branchparent/MOTIR-3877-public-project-pages(not yet merged at filing)motir-core/app/api/public/projects/[projectId]/requests/route.ts— the header comment that contradicts the cardmotir-meta/prompts/run.md— re-measure the PREDICATE, not only the REF, the run-time half this instance matches exactlymotir-meta/prompts/plan-rules/phase-deepen.md— the ENUMERATION limb, the authoring-side half