Skip to content

refactor(plugin-auth): move AuthManager's MCP access-token verifier into auth-manager-mcp-access-token.ts (#25224 cut 9) - #25461

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-lg3wrj
Oct 23, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-lg3wrj

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread

Part of #25224
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6348891160, 6364006498

The basis for the Clause-②: no line: this is a move. No accept set, route, refusal, code or answer changes, and the published surface is measured unchanged at both commits:

  • @objectstack/plugin-auth's dist/index.d.ts and dist/index.d.mts are raw byte-identical to base at commit 1 and at head (0 diff lines, so the union-order normalisation has nothing to do). The positive control is the one ruling 6348891160 asks for.
  • Its ESM and CJS entries export the same 159 names at base, at commit 1 and at head.

The .d.ts bar is ruling 6348891160 item 1 (on #25222, covering this card). Ruling 6364006498 is Sales's ruling A on this card, for bodies that read shared unexported helpers. This is the first cut it applies to.

Cut 9 of the auth-manager.ts split: the MCP access-token verifier. Two AuthManager method bodies (94 lines) and the one module-level declaration only they read (11 lines) move unedited, re-indented one level, into one new module, packages/plugins/plugin-auth/src/auth-manager-mcp-access-token.ts. #25224 stays open for the later cuts.

This follows the amended claim 6367866058, which amends 6365318480 on the file cut 8 left (#25423, landed note 6366862591). The shape is cuts 1 to 8's, which is #23050's.

Branch: claude/project-thread-lg3wrj, the harness-pinned branch for this session, restarted from origin/main 2b7c331537 after #25423 merged. It names no issue, so the card relation is this body's first line.

auth-manager.ts goes from 8,790 to 8,711 lines. The cut is +247 / −112 over 4 files: 359 changed lines, under the 3,000-line line. It is not a governed surface (check-governed-merges.mjs --branch HEAD: 0 of the 4 paths hit the register).

There are two commits, so the index.ts change is measured by itself:

  • b048a93241: index.ts names auth-manager.ts's published exports, and one comment sentence is reworded;
  • 619494870b: the move.

Commit 1: index.ts names what it publishes from auth-manager.ts

Ruling 6364006498, parameter 1. index.ts:16 was export * from './auth-manager.js';, so any module-level helper exported from auth-manager.ts for a module split out of it would have been published. It is now an explicit export { … } from './auth-manager.js'; of the 14 names auth-manager.ts exports at base, in declaration order:

DEFAULT_AUTH_BASE_PATH, readMcpServerEnabledEnv, resolveOidcProviderEnabled, resolveDcrEnabled, resolveScimEnabled, assertScimAdminCoherence, isOAuthEligibleBaseUrl, type InvitationPlacementServiceLike, readInvitationPlacementIntent, type AuthManagerOptions, ipMatchesRange, normalizeAuthEmailLocale, authEmailLocaleFromRequest, AuthManager.

A four-line comment above it says a new export of auth-manager.ts is published only by adding it there. The list was read off the base file with the TypeScript compiler API: 14 exported declarations, exactly these, in this order. At head the file has 15, and the fifteenth, OAUTH_ORGANIZATION_CLAIM (commit 2), is not listed.

One comment-only reword, agreed with the seat. Cut 5's module header (auth-manager-email-sms-delivery.ts:45–:49) said "index.ts re-exports auth-manager.ts whole, so exporting them from there would add them to the published surface, and a value import of that file from here would be a cycle." This commit makes the first half false, and the PR would otherwise ship a statement it makes false. The sentence now reads:

The four module-level declarations move with the bodies rather than being imported back, because only these bodies read them. (index.ts lists the names it publishes from auth-manager.ts one by one, so a helper exported there in place for a module split out of it stays off the published surface.) Nothing re-exports this module, so the published surface does not move.

  • The cycle half is dropped. A value import of auth-manager.ts from a split module is a cycle, but cuts 8 and 9 take one by design, read only inside function bodies, so it is no longer a reason. "Only these bodies read them" is measured: none of the four names (SMS_QUOTA_EXCEEDED_CODE, isSmsQuotaRefusal, smsQuotaExceededApiError, PHONE_OTP_SEND_REFUSAL_CODE) has a reader in auth-manager.ts.
  • Neither the old nor the new wording cites an ADR-NNNN, with or without a decision letter: 0 and 0.
  • The file's token sequence is unchanged: 1,427 tokens before and after, compared with the template-aware scanner the move proof uses (trivia skipped), and a comment-free print of the file is identical. Negative control: one string token changed ('TOO_MANY_REQUESTS' → 'TOO_MANY_REQUEST') makes both comparisons fail, exit 1.

What commit 1 changes in the build, measured at b048a93241:

  • dist/index.d.ts and dist/index.d.mts are raw byte-identical to base;
  • the ESM and CJS entries export the same 159 names;
  • index.js and index.mjs are byte-identical to base. Only index.js.map and index.mjs.map move, because index.ts's lines moved.

Commit 2: the move

moved base line lines members it reads
verifyMcpAccessToken (public) :7228 74 getApi, getAuthIssuer, getMcpResourceUrl, isMcpOAuthEnabled, rereadKeyringForUnknownKey
rereadKeyringForUnknownKey (private) :7321 20 config, and unknownKeyReread (read and written)
readPublishedJwks (module-level, with its docblock) :1483–:1493 11 —

Lines are base 2b7c331537. The members come from a walk of every this.X in each body with the TypeScript compiler API. No body has a bare this, this[...], arguments or super, or a this inside a function or a nested class. The one member a body assigns is unknownKeyReread (rereadKeyringForUnknownKey).

  • verifyMcpAccessToken is the local, fail-closed check of an OAuth 2.1 Bearer access token this deployment's authorization server minted: the signature against the published key set, iss, aud, the refusal of a token no human delegated, and the organization claim.
  • rereadKeyringForUnknownKey is the one forced keyring re-read a token signed by an unknown key earns, single-flight and floored at UNKNOWN_SIGNING_KEY_REREAD_FLOOR_MS.
  • readPublishedJwks moves with them, unexported. It reads the key set /jwks publishes. Its only readers are the two moved bodies (:7238, :7329). No anchor anywhere in the tree names it, and no test reads it. Its docblock cites [#24186] and no ADR.

OAUTH_ORGANIZATION_CLAIM is exported in place (ruling 6364006498, parameter 2):

  • :1465 becomes export const OAUTH_ORGANIZATION_CLAIM = 'organization_id';. That is the only edit to text that stays.
  • It does not move. buildPluginList (:4398, which stays) mints the claim with it, and verifyMcpAccessToken (:7288) reads it back; its docblock calls it "one spelling for both ends".
  • The new module imports it by value from ./auth-manager.js, beside type AuthManager. The one read is inside verifyMcpAccessToken's body, when a token is verified. The module's top level is three imports, readPublishedJwks, the host interface and the two functions, so nothing reads the binding while the two modules are first evaluated.
  • index.ts (commit 1) does not list it, so it is not published. The head's ESM and CJS entries do not export it, and dist/index.d.ts does not name it.

Imports.

  • retireHeldKeyrings and UNKNOWN_SIGNING_KEY_REREAD_FLOOR_MS (./signing-key-read-cache.js) leave auth-manager.ts, where their only reader was rereadKeyringForUnknownKey's body, and that import line goes. The two docblock mentions of UNKNOWN_SIGNING_KEY_REREAD_FLOOR_MS that stay in the class are backticked text, not {@link}.
  • type JSONWebKeySet (jose) stays in auth-manager.ts, for the unknownKeyReread field and the rereadKeyringForUnknownKey signature. The new module imports it as well.
  • The await import('jose') inside verifyMcpAccessToken moves with the body.

Evaluation order. signing-key-read-cache.js was first reached through auth-manager.ts's own import line (:146). It is now first reached through auth-manager-plugin-assembly.js, which imports createSigningKeyReader from it (cut 6's import line, :221 at head). Its top level is one type-only import, literal constants, a Set, a WeakMap, interfaces and function declarations. It imports no value and does nothing outside itself, so the change in order cannot be observed.

The shape

  • The class keeps both methods at their places, with their names, signatures and docblocks: the published .d.ts lists each one. Each body is now a host literal of exactly the members that body reads, typed as a Pick of McpAccessTokenHost, plus .call.
  • McpAccessTokenHost lives in the new module. It names the 7 members the bodies read, each typed as the class member (AuthManager['config'], …).
  • Every method goes as a late-bound closure ((...a) => this.m(...a)), so a double or spy set on the manager is still the one a body reaches. The verifier suites replace getApi with a key-set double, and verifyMcpAccessToken asks rereadKeyringForUnknownKey through the manager rather than calling the function directly.
  • config goes as a getter. The class reassigns it after construction (setRuntimeBaseUrl, applyConfigPatch), so it is read off the manager when a body reads it, as before.
  • unknownKeyReread goes as a get/set pair. rereadKeyringForUnknownKey stores the re-read it starts on the manager, so the floor and the read in flight stay the manager's, shared by every token it verifies.
  • verifyMcpAccessToken is no longer async. It returns the moved async function's own promise, so a caller awaits the same promise the body settles. Building the host cannot throw, so it does not now throw synchronously where it used to reject. rereadKeyringForUnknownKey was not async and stays so.
  • The cost: one small host object per call, on MCP bearer-token verification only, not on every request.
  • Nothing re-exports the new module, so the published surface does not move.

Path readers

No path reader needs migrating: none reads a moved line.

  • The tenant-audit census. No census site moves: the moved text has no engine write, no this.X.delete() and no elevation read. check-tenant-audit-census exits 0 at head with no --write: 238 sites at base and at head, compared per site with line numbers ignored, 0 differences, and 2 of them in auth-manager.ts at both. So neither census document is edited.
  • check-dispatcher-error-vocabulary.mjs and api-error-code.pin.test.ts's authManagerFiles floor: no new APIError( sits in the moved text. The gate reads 56 sites found and 56 classified at base and at head.
  • The plugin-factory scans in better-auth-schema-parity.test.ts and managed-extension-fields.test.ts match await import('better-auth/plugins…') and await import('@better-auth/…') only. The moved await import('jose') is neither, and the import lines that change are local modules.
  • check-auth-mount-ledger.mjs and auth-manager-base-path.test.ts: no base-path literal or declaration sits in the moved text. getAuthIssuer and getMcpResourceUrl stay on the class.
  • The system-context census reads 148 elevation read sites at base and at head.
  • scripts/adr-anchors/: the auth-manager.ts entry's invariant (ADR-0093, ADR-0108) is about the organization roles and the membership reconciler, not this text.
  • Callers through the manager. These suites drive the two methods through the class method, and all pass at head:
    • auth-manager.mcp-oauth.test.ts (local JWKS verification, fail-closed);
    • auth-manager.mcp-verifier-keyring.test.ts (the forced re-read, its floor and single flight; it reads UNKNOWN_SIGNING_KEY_REREAD_FLOOR_MS and retireHeldKeyrings from signing-key-read-cache.js itself);
    • auth-manager.oauth-consent-organization.test.ts (the organization claim end to end);
    • auth-manager.mcp-oauth-resource.test.ts.
  • Every symbol anchor into the file. Before the cut, every auth-manager.ts#symbol anchor in the tracked tree outside changelogs was mapped with symbolSegmentResolution from scripts/symbol-anchors.mjs. There are 29, and all 29 are declaration-class at base, with the moved text blanked, and at head. None names a moved method or readPublishedJwks. One names a token the moved text carries, and it resolves on the declaration that stays: #isMcpOAuthEnabled (docs/qa/platform-checklist/areas/ai.json:806; the moved verifier calls this.isMcpOAuthEnabled()).

The decision-letter layer does not move

The seat asks each cut's report for this count at both ends. check-adr-anchors' decision-letter layer reads 2,001 at base 2b7c331537 and 2,001 at head, and the gate exits 0 at both. Nothing this PR adds or moves cites an ADR-NNNN: not the moved text, not the new module's header, not the index.ts comment, and not the reworded sentence. So the number layer reads the same at both: 52,177 citations across 6,637 files. No anchor entry is added for the new module, as for cuts 1 to 8's modules.

Proof

Builds and suites ran through os-verify-lock, and every exit code was captured before any pipe. Base 2b7c331537, commit 1 b048a93241, head 619494870b. A full turbo run build ran first. Then plugin-auth was built and its suite run at base, built at commit 1, and built and its suite run at head, on the same dependency dists.

1. The moved text.

  • For each of the 2 methods, the base class body and the new module's function body are the same TypeScript token sequence (scanner tokens, kind and text, trivia skipped, each template literal re-scanned at its substitutions as the parser does).
  • Every line is the base line minus exactly two leading spaces, and the parameters and return type are the same text.
  • Each class method keeps its docblock and signature, with async dropped from verifyMcpAccessToken.
  • readPublishedJwks's 11 lines, docblock included, are verbatim in the module and absent from auth-manager.ts. Its 76 tokens are identical.
  • Result: 2 of 2 bodies and 1 of 1 declarations pass, 94 body lines plus 11.
moved lines tokens
verifyMcpAccessToken 74 434
rereadKeyringForUnknownKey 20 130
readPublishedJwks 11 76
  • Negative control: one token changed in the module (errors.JWKSNoMatchingKey → errors.JWKSNoMatchingKeys in verifyMcpAccessToken) makes that method fail (tokens and lines DIFFER), and the run exits 1. The module was restored afterwards, and cmp against the saved copy was clean.
  • An independent reading: git diff --color-moved=plain --color-moved-ws=allow-indentation-change b048a93241 619494870b over the two source files marks 105 of the 107 deleted lines and 120 of the 222 added lines as moved.
    • The other 2 deleted lines are const OAUTH_ORGANIZATION_CLAIM = … (now export const) and the async verifyMcpAccessToken( signature line.
    • The other added lines are the stubs' host literals, McpAccessTokenHost, the module header, the per-function pointer docblocks and the import blocks.

2. .d.ts and exports (ruling 6348891160 items 1 and 2).

file base commit 1 head raw diff lines vs base
dist/index.d.ts raw 12679e13f74973b0510551a65b50808e7c3936a2d273cf2f262a9196648c0737 same same 0 and 0
dist/index.d.ts normalised c7a9fa25f118cfec858d770b979767744d27d9757a9ea4063faeea6238c33c01 same same
dist/index.d.mts raw df57562ff950159e738d790cb7ee82a655ba0fffddafe4153bdcc50c4537336f same same 0 and 0
dist/index.d.mts normalised 68f824aea0947d9895b968ed46a7972eaae43ef0f2bda7e3ba9113002233ade6 same same
  • The normaliser, verbatim (the ruling's one-liner): node -e 'const s=require("fs").readFileSync(process.argv[1],"utf8");process.stdout.write(s.replace(/"[^"\n]*"(?:\s*\|\s*"[^"\n]*")+/g,r=>r.split(/\s*\|\s*/).sort().join(" | ")))' dist/index.d.ts | sha256sum.
  • The raw files are already byte-identical, so no union-order swap occurs in this cut: items 1(b) and 1(d) hold with nothing to account for.
  • Positive control: the head dist/index.d.ts with one private member made public (private rereadKeyringForUnknownKey; → rereadKeyringForUnknownKey;, line 3320, a one-line change) hashes raw 090e9f39924a2034bc496e4fded90d5f267d90ff88aa20a92619d04019ed471b and normalised dc9fc90b5a1699dcb01263f89e1c983da7367710ea2c0f6e17ec395a9d0da579. Both differ from the readings above.
  • Export lists: ESM dist/index.mjs and CJS dist/index.js each have 159 names at base, at commit 1 and at head, the same list (the sha256 of the sorted names is 3abb126f5babb701… on all six). OAUTH_ORGANIZATION_CLAIM, readPublishedJwks and the module's functions are not among them, and dist/index.d.ts names none of them.
  • The bundle: 18 files in dist/ at all three, the same list. From base to head, only index.js, index.mjs and their two .map files differ, as a move of code inside the bundle must. From base to commit 1, only the two .map files differ.

3. Tests and lint.

  • pnpm exec vitest run --maxWorkers=3 in packages/plugins/plugin-auth: base Test Files 189 passed (189), Tests 3580 passed | 10 skipped (3590), exit 0. Head: the same counts, exit 0.
  • pnpm --filter @objectstack/plugin-auth typecheck (both tsc projects and check:test-typecheck): exit 0. pnpm --filter @objectstack/runtime typecheck: exit 0.
  • eslint --no-inline-config (the root lint script's binary and flags) over the 4 source files: exit 0.

4. The censuses and the anchors, at base and at head.

  • The tenant-audit census, as above: 238 sites at both, 0 per-site differences, 0 unresolved and 0 unledgered at both, and every total the same. Only scannedSources (725 → 726, the new module) and measuredAt differ.
  • These checkers were run by hand at base and at head, because dispatch-gates does not derive the ADR one. All six exit 0 at both, with the same reading:
    • check-adr-symbol-anchors: 2,384 anchors across 142 records, 466 symbol (440 declaration, 26 literal);
    • check-adr-anchors: 80 anchored files; the decision-letter layer reads 2,001, as above;
    • check-scripts-symbol-anchors: 4,062 anchors;
    • check-spec-docblock-symbol-anchors: 5,075 anchors (both of these read in the same built tree);
    • check-system-context-census: 148 elevation read sites;
    • check-platform-checklist: 16 areas, 329 items.

5. Gates.

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 53 commands for the 4 paths. All 53 ran at 619494870b after the full build, and all 53 exited 0.
  • --ran over the record with each exit code: 53 derived, 53 run, 0 NOT-MEASURED, a derived zero.
  • check-governed-merges.mjs --branch HEAD: NOT governed, 359 changed lines.
  • Docs drift (node scripts/docs-audit/affected-docs.mjs --json 2b7c331537, exit 0): 1 page, content/docs/kernel/contracts/auth-service.mdx, which states the verifyMcpAccessToken contract signature. The class method keeps that signature, so no doc edit is owed. 0 release-owned pages.
  • Serial constraints (in the claim): 25 PRs are open, and none touches this cut's files or a reader above. origin/main moved to b2c0752900 during the run with fix(plugin-auth): degraded rate-limit warning names the cache registration that boots #25434, which touches otp-send-guard.ts and rate-limit-storage.ts and its test, none of them in this surface. git merge-tree of this branch onto b2c0752900 is clean.

Finding, outside this cut

scripts/measure-durability-swallow-family.mjs is a measurement, not a gate. Its prose at :625 and :775 names auth-manager.ts::verifyMcpAccessToken as the one outstanding DARK member. The census does not list it on base: its one auth-manager.ts DARK member is observeFirstMemberships. So that prose was already stale before this cut.

Its --json reading is the same at base and at head: 74 members at both, every member and quiet row the same (line numbers ignored), and every statistic the same except the scanned file count (3,449 → 3,450, the new module). Neither side names verifyMcpAccessToken or the new module. scripts/ is not edited, and the finding is for the seat to judge.

Changeset

None: skip-changeset, per ruling 6348891160 item 4. The published declarations and export lists are unchanged, and the bundle's bytes move only because code moved inside it.


Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_01LSXBc2GCBwiAL7vV4kWkyr

…x.ts

index.ts re-exported auth-manager.ts with export *, so any module-level
helper exported there for a module split out of it would be published.
It now names the 14 exports auth-manager.ts already has, in declaration
order, and a new export there is published only by adding it to the
list. The published declarations and both entry points' export lists
are unchanged.

The cut 5 module header said index.ts re-exports auth-manager.ts whole.
That sentence is reworded to say why its four declarations moved with
the bodies; it is a comment, and no token of the file changes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LSXBc2GCBwiAL7vV4kWkyr
…nto auth-manager-mcp-access-token.ts

Two method bodies move unedited: verifyMcpAccessToken, the local,
fail-closed check of an OAuth Bearer access token this deployment
minted, and rereadKeyringForUnknownKey, the one forced keyring re-read
a token signed by an unknown key earns. readPublishedJwks, which only
they read, moves with them unedited. The class keeps both methods,
their docblocks and signatures, and hands each body the members it
reads. OAUTH_ORGANIZATION_CLAIM stays in auth-manager.ts, where the
plugin assembly also reads it, and is exported there for the new module;
index.ts does not publish it.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LSXBc2GCBwiAL7vV4kWkyr
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-auth, touching 18 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/plugins/plugin-auth/src/auth-manager-email-sms-delivery.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/kernel/contracts/auth-service.mdx (via getApi (symbol, a field of interface McpAccessTokenHost), getMcpResourceUrl (symbol, a field of interface McpAccessTokenHost), verifyMcpAccessToken (symbol, a method of class AuthManager; a top-level function), getApi (literal, a string literal in getApi; a string literal in verifyMcpAccessToken), getMcpResourceUrl (literal, a string literal in getMcpResourceUrl; a string literal in verifyMcpAccessToken))
What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-auth/src/auth-manager-email-sms-delivery.ts) — pages documenting those are invisible to this run
  • 1 anchor(s) matched too much of the corpus to be a work list: organization_id (literal, 37 pages)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 19 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 17ef0327b2b266ddb2ed2e83e6227f64761201fe → packageMentionDocs.

Which tree this was computed on

This run read content/docs from a5524ffe1e7bbfb9154cc5fda4c782e14db0ce14 — the merge of head 619494870ba9fd8214734413771b262da597b7a8 into base 17ef0327b2b266ddb2ed2e83e6227f64761201fe, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin a5524ffe1e7bbfb9154cc5fda4c782e14db0ce14 && git checkout a5524ffe1e7bbfb9154cc5fda4c782e14db0ce14
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 17ef0327b2b266ddb2ed2e83e6227f64761201fe 619494870ba9fd8214734413771b262da597b7a8 && git checkout -B drift-repro 17ef0327b2b266ddb2ed2e83e6227f64761201fe && git merge --no-ff 619494870ba9fd8214734413771b262da597b7a8

node scripts/docs-audit/affected-docs.mjs --json 17ef0327b2b266ddb2ed2e83e6227f64761201fe

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 17ef0327b2b266ddb2ed2e83e6227f64761201fe → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · 2026-10-23T15:37Z

domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · card #25224 cut 9 (claim 6367866058; os-dev-report 6368531331; Ruling-ref: 6364006498) · reviewed head 619494870b · merge base 2b7c331537

  • Shape: two commits, 4 files, +247 / −112.
    • Commit 1, b048a93241: index.ts lists auth-manager.ts's published names by name, per ruling A. The auth-manager-email-sms-delivery.ts header sentence is reworded as a comment-only change; it has 0 ADR citations before and after, and its token stream is identical.
    • Commit 2, 619494870b: moves verifyMcpAccessToken and rereadKeyringForUnknownKey (token-identical bodies) into the new auth-manager-mcp-access-token.ts. readPublishedJwks moves verbatim and unexported.
  • .d.ts, ruling 6348891160 item 1, re-run by the seat in its own worktree. turbo run build --filter=@objectstack/plugin-auth ran at 2b7c331537 and at this head.
    • dist/index.d.ts: raw 12679e13f74973b0… and normalised c7a9fa25f118cfec… at both.
    • dist/index.d.mts: raw df57562ff950159e… and normalised 68f824aea0947d98… at both.
    • The raw diff is 0 lines.
    • The seat's positive control uses head line 1793, private buildJwtPlugin, made public: raw 0df245ad99718810… and normalised 927c1cef33786… both moved.
    • Export lists: 159 names at base, at commit 1 and at head (report). OAUTH_ORGANIZATION_CLAIM is neither exported nor named in the .d.ts.
  • Gates re-run by the seat, all exit 0 at base and at head:
    • check-adr-symbol-anchors: 2384 … 466 symbol at both.
    • check-tenant-audit-census: 238 sites at both, and no site moves.
    • check-adr-anchors.
    • check-dispatcher-error-vocabulary.
  • Decision-letter count, read by the seat: 2001 at base and 2001 at head. The 29 declaration-class anchors resolve. #isMcpOAuthEnabled resolves on the method that stays.
  • Tests and gates (report): plugin-auth 3580 passed and 10 skipped at both. 53 derived gates exit 0. The token-identity negative control exits 1.
  • CI on this head: 46 check-runs, 34 success and 12 expected skips, none failed.
  • Mergeable: git merge-tree onto today's main (0b8dbea00d) is clean. The dev's merge check onto 17ef0327b2 ran 8 checkers and 288 focused tests green.
  • Body: the seat added the attribution header and the os-sales reviewer through the relay. Both footers are present.
  • Declarations: refactor(plugin-auth), Clause-②: no, Metadata-protocol: none. No contract-review record or dogfood battery is owed.
  • Finding, judged by the seat: scripts/measure-durability-swallow-family.mjs:625 and :775 still name auth-manager.ts::verifyMcpAccessToken as the outstanding DARK member. That prose was already stale before this cut: the instrument's census JSON is identical at base and head (74 members), so the cut changes no reading. It is scripts/ prose with no public reproduction, outside the filing classes, and outside this split's move-only surface. It is left for the domain:devx lane's next pass on that instrument, not filed.
  • Landing: not governed (check-governed-merges --pr 25461: 359 lines). Ready + auto-merge through the relay. The card stays open and dispatched for the next cut.

Generated by Claude Code

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

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants