Skip to content

test(backend): re-certify the agentRuntimeAuth projection guard — main is red - #1432

Closed
lilyshen0722 wants to merge 1 commit into
mainfrom
fix/agent-user-shape-guard-recertify
Closed

lilyshen0722 wants to merge 1 commit into
mainfrom
fix/agent-user-shape-guard-recertify

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

main is red. Test & Coverage fails at origin/main (396bf8f1) — 1 failed, 2790 passed. Every open PR inherits it; my #1429 is how I found it.

● the middleware reads the full User row › the file contains exactly one projection, and it is the Pod.find
    Expected: 1
    Received: 2

Nothing is actually broken

#1312 (AgentCredential substrate, ADR-026 Phase 0, merged 2026-08-27) added to agentRuntimeAuth.ts:82:

const parent = await AgentCredential.findById(credential.parentId).select('status').lean();

That is a projection on AgentCredential, not on the User row. The property the guard defends — no User query is projected, so req.agentUser carries the whole row — is intact. The guard trips on any new .select( in the file on purpose, so the author re-certifies consciously. Its own comment says why a smarter check was rejected:

Enumerate the protected item instead: ANY new .select( anywhere in the file trips this, and the author re-certifies it consciously. A guard that must parse correctly to fail is not a guard.

So this is the guard working. It just never got its re-certification.

Why it reached main, and why no check could have caught it

Ref .select( in agentRuntimeAuth.ts Guard
#1210's base 799e0d7d 1 passes — CI was green
#1210's merge 78e7c97e (= main) 2 fails

#1210 was green on a tree that had stopped existing four days earlier. Merging it at 11:05:07Z today produced a tree neither PR's CI had ever run.

The part worth generalising: these two PRs never conflicted and never could. #1312 edits the middleware; #1210 adds a test that reads the middleware. Disjoint paths — git merge-tree calls them clean, the stale-base guard passes, and nothing in the merge machinery models "this file's assertions depend on that file's contents." A source-assertion guard is coupled to files it does not modify, and that coupling is invisible to every conflict check we run. Textually clean, semantically contradictory.

The fix

Re-certification, not a bumped constant — a bump is precisely the escape hatch the guard exists to close. The count stays as the fail-closed backstop, and on top of it:

  • both certified projections pinned to their receivers by regex;
  • selectReceivers(), which walks each .select( back to the model it is called on and asserts the set is exactly {AgentCredential, Pod}. A future projection on User now fails by name, not just by count.

Verified it still discriminates. Adding .select('_id username') to the User.findOne in the middleware fails two tests — the count (2→3) and the statement-level assertion — and I reverted the mutation afterwards. unit/middleware is 45/45 green.

Also renamed the test: it said "exactly one projection, and it is the Pod.find", which this diff makes untrue.

🤖 Generated with Claude Code

…n is red

`Test & Coverage` fails on origin/main: agentUserShapeContract's load-bearing
assertion expects 1 `.select(` in agentRuntimeAuth.ts and finds 2.

Nothing is actually broken. #1312 (AgentCredential substrate, ADR-026 Phase 0,
merged 2026-08-27) added

    AgentCredential.findById(credential.parentId).select('status')

which is a projection on AgentCredential, not on the User row. The guard trips
on ANY new `.select(` in the file by design, so that the author re-certifies it
consciously — this is the guard working, not a false alarm to be silenced.

Why it reached main: the guard (#1210) was green on its own base 799e0d7,
where the file had exactly 1 projection. #1312 had added the second four days
earlier. Merging #1210 at 11:05Z today produced a tree neither PR's CI had
tested. The two never conflicted and never could: #1312 edits the middleware,
#1210 adds a test that READS the middleware, so they touch disjoint paths and
every merge check — including `git merge-tree` — calls them clean. A source
assertion is coupled to files it does not modify, and that coupling is
invisible to conflict detection.

Re-certification rather than a bumped constant, which is what the guard's own
comment demands. The count stays as the fail-closed backstop; added on top:

- both certified projections pinned to their receivers by regex;
- `selectReceivers()`, which maps each `.select(` back to the model it is
  called on and asserts the set is exactly {AgentCredential, Pod}. A future
  projection on User now fails by NAME, not just by count.

Verified it still discriminates: adding `.select('_id username')` to the
`User.findOne` in the middleware fails two tests (count 2→3, and the
statement-level assertion). Reverted after. 45/45 in unit/middleware green.

Renamed the test — it said "exactly one projection, and it is the Pod.find",
which stopped being true in this diff.

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

Copy link
Copy Markdown
Contributor Author

Closing in favour of #1430, which is the same repair and was opened first (11:34Z, announced in-pod at 61770 — five minutes before I pushed this, and I missed it).

I gated #1430 independently before deciding, disclosing that I had a competing PR. Its claim holds and then some: five mutations on the middleware, each with the anchor asserted to have moved — statusstate killed, deleting the AgentCredential projection killed, widening the Pod.find projection killed, projecting the User.findOne killed, and the evasion I most wanted ruled out — adding a User projection while deleting the AgentCredential one, so the bare count stays at 2 — killed by its receiver-pinned regexes. 45/45 across unit/middleware.

The only thing this PR adds is selectReceivers(), which maps each .select( back to its model and asserts the set is exactly {AgentCredential, Pod}. Having mutated both, that buys a failure message naming the receiver, not detection power — every case it catches, #1430 already catches. Not worth a conflict on the PR that turns main green. Happy to send it as a follow-up against #1430 once merged, if anyone wants the better failure text.

The finding in the description stands on its own and is the part worth keeping: #1210 was green on its base, where the file had one projection; #1312 had added the second four days earlier; the two touch disjoint paths, so no conflict check could see the interaction. A test that readFileSyncs source has its real base surface in the file it asserts on, not the files it changes.

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