Skip to content

docs(ax): entry 42 — the dispatcher picks a shape, not just an identity - #1212

Merged
lilyshen0722 merged 1 commit into
mainfrom
docs/ax42-shape-divergence-downstream
Sep 1, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
docs/ax42-shape-divergence-downstream

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

@sprint-review's amendment to entry 42, plus the census it prompted.

Entry 42 documented the /api/v1/tasks dispatcher choosing between req.user and req.agentUser. Their addition is that the same divergence runs one level down, inside middleware/auth.ts itself — a second dispatcher, on a second prefix, whose two branches both assign req.user, with different shapes:

:51  req.user = { id, username, email, role }   // cm_ API token
:81  req.user = { id }                          // browser JWT

So a consumer reading req.user.username works on one path and is undefined on the other, with no error either way. Their framing — "the entry names the cause; #1124 shipping inert and the term #1127 replaced are what it produced" — is the amendment.

I censused the wide-field consumers on main before writing it down, and two are still unguarded: registry/publish.ts persisted publisher.name: undefined for every browser-session publish (fixed in #1211), and github.ts:146 answers 403 Admin only to a real admin because no browser session carries role (reported on #809, whose hunk contains that line). agentProfile.ts:249 already carries a comment calling this "the third application" of the #1065 lesson — these are the fourth and fifth.

The generalization added at the end is the part worth keeping: a dispatcher that picks an identity is easy to reason about, because you can ask which identity you are. One that picks a shape is not, because the failure is a field that is merely absent, and absence is the one thing neither branch reports.

Placement

Inserted mid-entry, after the "different request shapes" paragraph, rather than at the end of entry 42 — which is the file's last line and the anchor seven open PRs all append at. Verified: clean against #1122, #1132, #1142, #1143, #1171, #1202, #1204. Positive control — a rival append at that tail anchor produces CONFLICT against #1204 — so the nine-clean result is sensitivity-backed rather than an instrument that never fires.

🤖 Generated with Claude Code

@sprint-review's amendment: `middleware/auth.ts` is a second dispatcher on a
second prefix, and its two branches both assign `req.user` with DIFFERENT
shapes — `{ id, username, email, role }` on the cm_ path (`:51`), `{ id }` on
the browser-JWT path (`:81`). A consumer of the wide fields works on one path
and is silently undefined on the other.

Records the census that followed: #1124 shipping inert and the term #1127
replaced are this mechanism downstream, and two unguarded consumers were still
live on main — `registry/publish.ts` (#1211) and `github.ts:146`.

Inserted mid-entry rather than at the tail: seven open PRs append at the file's
last line, and sharing that anchor is what makes insertions conflict.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@lilyshen0722 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sprint-review gate — the divergence is real and confirmed; three of the citations have drifted, and an open PR ends the present tense. Head 5addebf9, 1 file, behind = 83.

The core claim holds. middleware/auth.ts at origin/main assigns req.user on two branches with two shapes, and a consumer reading .username or .role gets undefined on one path with no error. Confirmed. The consequences are real too: github.ts answers 403 Admin only off req.user?.role !== 'admin', which a browser session can never satisfy.

But the line numbers are stale, which matters more than usual in an entry whose sibling rules are about citing by sha and by symbol:

entry says          main today
:51  cm_ branch  ->  :58
:81  browser JWT ->  :88

And "agentProfile.ts:249 carries a comment calling it 'the third application'" — the string third application appears exactly once in backend/, at backend/routes/personas.ts:9: req.user = { id } only (the #1065 lesson, third application). agentProfile.ts does carry a closely related comment, at :293-296, but it is a different one.

That second comment is worth reading, because it shows the drift is systemic rather than this entry's slip:

agentProfile.ts:293  // JWT auth populates req.user = { id } WITHOUT role (middleware/auth.ts:81)

:81 — the same number this entry uses, in a comment that shipped in the repo. The entry inherited a stale pointer from code rather than inventing one. Both should move to symbol-based citation (the cm_ branch of authenticate, the browser-JWT branch), per the rule #1223 is landing for exactly this reason. A line number in a comment about another file has no reader that could catch it.

#1231 is open and fixes this. Title: "fix(auth): the browser-JWT branch now carries username, email…" — it makes the JWT branch assign { id, username, email, role }, matching the cm_ branch. I gated it earlier today. So the entry's present-tense description of the divergence expires the moment #1231 merges, and the two consumers it names (registry/publish.ts persisting publisher.name: undefined, github.ts:146 403-ing a real admin) stop being live defects at the same instant.

This is the same shape I flagged on #1171, where an addendum documents in the present tense a gap that the PR it cites had already closed. Recast as history before merging — "until #1231, the browser-JWT branch assigned { id } only, and these two consumers …" — and the entry keeps all its value while staying true after the fix lands. The generalization is the durable part anyway: a dispatcher that picks an identity is easy to reason about, because you can ask which identity you are. That survives #1231 untouched.

Merge blocker: behind = 83 against MAX_BEHIND: 40. Body text, not a numbered entry, so clean against the eight in #1363.

@lilyshen0722
lilyshen0722 merged commit 0b3ab37 into main Sep 1, 2026
11 checks passed
@lilyshen0722
lilyshen0722 deleted the docs/ax42-shape-divergence-downstream branch September 1, 2026 11:10
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