Skip to content

refactor(plugin-auth): move AuthManager's database and auth secret inputs into auth-manager-database-secret.ts (#25224 cut 7) - #25404

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

objectstack-fleet[bot] merged 1 commit 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

The basis for the Clause-②: no line: this is a move. No accept set, export, route, refusal, code or answer changes. The .d.ts bar is ruling 6348891160 item 1 (on #25222, covering this card). @objectstack/plugin-auth's published dist/index.d.ts and dist/index.d.mts are raw byte-identical to base (0 diff lines, so the union-order normalisation has nothing to do), with the ruling's positive control. Its entry exports the same 159 names under ESM and CJS (measured below).

Cut 7 of the auth-manager.ts split: the database and the auth secret createAuthInstance hands better-auth. Three AuthManager method bodies (97 lines) move unedited, re-indented one level, into one new module, packages/plugins/plugin-auth/src/auth-manager-database-secret.ts. #25224 stays open for the later cuts.

This follows the amended claim 6363170079, which amends 6361212912 on the file cut 6 left (#25400, landed note 6362338361). The shape is cuts 1 to 6's, which is #23050's.

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

auth-manager.ts goes from 8,971 to 8,909 lines. The cut is +192 / −91 over 2 files: 283 changed lines, under the 3,000-line line. It is not a governed surface (check-governed-merges.mjs --branch HEAD: 0 of the 2 paths hit the register).

Why this seam

These are the two inputs createAuthInstance reads from the manager when it builds the better-auth instance (secret: this.resolveAuthSecret() and database: await this.createDatabaseConfig()), and the environment read behind the first:

  • createDatabaseConfig: the ObjectQL adapter factory, with the created-record callback that stages the id of a user the current endpoint call created, or, with no data engine, better-auth's in-memory store keyed by model name and the warning that it is not for production;
  • resolveAuthSecret: the auth secret, resolved once per manager and memoised in resolvedAuthSecret;
  • generateSecret: the secret from OS_AUTH_SECRET (or its two legacy spellings), the refusal to boot production without one, and the development fallback with its warning.

What stays, and why:

  • createAuthInstance stays. Its body reads readDisableSignUpEnv, a module-level function that auth-manager.ts does not export and that getPublicConfig also reads. index.ts re-exports auth-manager.ts whole (export * from './auth-manager.js'), so exporting it there would publish it. Per the landed note 6360455119, a body that reads an unexported module helper comes back as needs_decision before it is cut.
  • buildPluginList and resolvePasswordHasher stay for the same reason (readBooleanEnv, isWebContainerRuntime).
  • stageUserCreatedInRequest stays: it writes the request-scoped record of created users that the session seam reads, part of the membership area, a later cut.

What moved

method base signature line body lines members it reads
createDatabaseConfig :4670 66 config, stageUserCreatedInRequest
resolveAuthSecret :4741 6 config, generateSecret, resolvedAuthSecret (read and written)
generateSecret :4748 25 none

Lines are base 860f002f8b. 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. No body reads a static (AuthManager.X) or a module-level declaration of auth-manager.ts. The one assignment to a this member is resolveAuthSecret's to resolvedAuthSecret.

Imports. No import leaves auth-manager.ts. The new module imports readEnvWithDeprecation from @objectstack/types and createObjectQLAdapterFactory from ./objectql-adapter.js, the places auth-manager.ts imports them from. auth-manager.ts keeps both import lines unchanged:

  • readEnvWithDeprecation for its other read (:3024, the CORS origin);
  • createObjectQLAdapterFactory because a docblock that stays links it ({@link createObjectQLAdapterFactory}, :895), and TypeScript resolves that link through the import. The same import line brings withSystemContext and withSystemReadContext, which the file still calls.

Evaluation order. Nothing moves. Both modules the new one imports are imported by auth-manager.ts above the new module's import line, so they are evaluated before it, as before. The new module's top level is three imports (one type-only), an interface and three function declarations, so the point at which it is evaluated cannot be observed.

The dynamic import. createDatabaseConfig's callback reads tryGetCurrentAuthEndpointContext through await import('@better-auth/core/context'), at call time. It moves with the body, unedited. A bare specifier resolves the same from both files: they sit in the same directory and are bundled into the same entry.

The shape

  • The class keeps all three 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 DatabaseSecretHost, plus .call. generateSecret reads no member, so its method calls the moved function directly.
  • DatabaseSecretHost lives in the new module. It names the 4 members the bodies read, each typed as the class member (AuthManager['config'], …). The module imports AuthManager as a type only, so there is no runtime cycle.
  • stageUserCreatedInRequest and generateSecret go as late-bound closures ((...a) => this.stageUserCreatedInRequest(...a)). The adapter's created-record callback runs stageUserCreatedInRequest inside every creating endpoint call, long after the factory was built, and still reaches the method on the manager, so a spy or double set there is still the one it reaches.
  • 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. The adapter factory reads this.config.dataEngine when createDatabaseConfig runs, as before.
  • resolvedAuthSecret goes as a get/set pair. resolveAuthSecret stores the secret on the manager, so every consumer still reads the one memo, and a manager resolves its secret once.
  • createDatabaseConfig is no longer async. It returns the moved async function's own promise, so createAuthInstance awaits the same promise the body settles. Building the host cannot throw, so the method does not now throw synchronously where it used to reject. resolveAuthSecret and generateSecret were synchronous and stay so: generateSecret's production refusal still throws synchronously from the method.
  • The cost: one small host object per call. Both methods with a host run when the auth instance is built (resolveAuthSecret also from buildPluginList's SCIM arm), not per request.
  • Nothing re-exports the new module, so the published surface does not move.

Path readers

None needs migrating: no reader keys on a moved line. Measured as reading no moved line:

  • Plugin-factory scans in better-auth-schema-parity.test.ts and managed-extension-fields.test.ts. The moved text carries one dynamic import their pattern matches: const { tryGetCurrentAuthEndpointContext } = await import('@better-auth/core/context'). Both scans skip every @better-auth/core specifier ("runtime utilities … not plugin factories, and they declare no schema"), so the factory set they derive from auth-manager.ts and auth-manager-actor-guards.ts is the same at base and head, and the new module is not added to their file lists.
  • check-dispatcher-error-vocabulary.mjs's file-scoped import bindings (guard ③, which reads the dynamic const { … } = await import(…) form). tryGetCurrentAuthEndpointContext leaves auth-manager.ts's binding set. A binding matters to the gate only as the object of a member expression in an APIError argument, and neither the moved text nor the new module has a new APIError(. The gate reads 56 sites found and 56 classified at base and at head; its scope grows by the one new file (3,394 → 3,395 non-test source files).
  • api-error-code.pin.test.ts's authManagerFiles floor: no new APIError( sits in the moved bodies, so the floor reads the same sites over the same files at base and head.
  • check-auth-mount-ledger.mjs and auth-manager-base-path.test.ts: no base-path literal or declaration sits in the moved text.
  • The tenant-audit census and its two documents: the moved text holds no engine write. Compared per site, base and head read the same 238 sites with the same totals (below), so neither document is regenerated.
  • The system-context census: the moved text holds no isSystem read. The census reads 148 elevation read sites at base and at head.
  • Callers through the manager: the suites that drive the three methods call each through the class method, and all pass at head (below):
    • auth-manager.test.ts: "createDatabaseConfig – adapter wrapping", and "generateSecret – production secret guard (P0-1)", which calls generateSecret() on the manager (the boot refusal in production without a secret, the ephemeral development secret, and OS_AUTH_SECRET used even in production);
    • user-created-in-request.test.ts (ADR-0093 D7), which awaits createDatabaseConfig() on the manager and drives the created-record callback;
    • auth-route-ledger.conformance.test.ts, on the in-memory fallback.
  • The staging the callback reaches: first-session-membership-ordering.test.ts drives stageUserCreatedInRequest on the manager directly. That method stays, and it is the one the callback's closure reaches, so the test reads the same member at base and head.
  • 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, in ADR-0127, ADR-0134, ADR-0135 and four platform-checklist areas, and all 29 are declaration-class at base, with the 3 bodies blanked, and at head. None names a moved method. One names a token the moved text also carries: #AuthManager (ADR-0135), in the in-memory warning's text. It resolves on the class declaration, which stays.

The decision-letter layer drops by one

The seat asks each cut's report for this count at both ends.

  • check-adr-anchors' decision-letter layer checks ADR-NNNN Dk citations only in anchored files. auth-manager.ts is anchored; the new module is not, as cuts 1 to 6's modules are not.
  • createDatabaseConfig's callback comment cites ADR-0093 D7 (the adapter as the one place that sees the created user's id inside the creating endpoint call). It moves with the body, so the layer reads one citation fewer: 2,015 at base 860f002f8b and 2,014 at head. On origin/main 2dfeb1a772 (below) it reads 2,005 alone and 2,004 with this cut. The gate exits 0 at both.
  • auth-manager.ts's anchor entry names ADR-0108 and ADR-0093, and its invariant describes the role map and the D2 membership seams, not D7. Its required text stays in auth-manager.ts, and the entry still holds.
  • No anchor entry is added for the new module. An entry would need new invariant text, which a move-only cut does not add; the seat ruled the same for cut 5's ADR-0131 D7.

Proof

Builds and suites ran through os-verify-lock, and every exit code was captured before any pipe. Base 860f002f8b, head 83f5b0249e. A full turbo run build ran first. Then plugin-auth was built and its suite run at base, then built and run at head, on the same dependency dists.

1. The moved text.

  • For each of the 3 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 createDatabaseConfig.
  • Result: 3 of 3 pass, 97 body lines.
method body lines tokens
createDatabaseConfig 66 192
resolveAuthSecret 6 32
generateSecret 25 79
  • Negative control: one token changed in the module ('sys_user' → 'sys_users' in createDatabaseConfig's created-record callback) makes that method fail (tokens and lines DIFFER), and the run exits 1. Restored afterwards; cmp against the saved copy was clean.
  • An independent reading: git diff --color-moved=plain --color-moved-ws=allow-indentation-change 860f002f8b 83f5b0249e over the two source files marks 90 of the 91 deleted lines and 100 of the 192 added lines as moved.
    • The one other deleted line is createDatabaseConfig's async signature line.
    • The other added lines are the stubs' host literals, DatabaseSecretHost, the module header, the per-function pointer docblocks and the import blocks.

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

file raw base raw head raw diff lines normalised base normalised head
dist/index.d.ts 12679e13f74973b0510551a65b50808e7c3936a2d273cf2f262a9196648c0737 12679e13f74973b0510551a65b50808e7c3936a2d273cf2f262a9196648c0737 0 c7a9fa25f118cfec858d770b979767744d27d9757a9ea4063faeea6238c33c01 c7a9fa25f118cfec858d770b979767744d27d9757a9ea4063faeea6238c33c01
dist/index.d.mts df57562ff950159e738d790cb7ee82a655ba0fffddafe4153bdcc50c4537336f df57562ff950159e738d790cb7ee82a655ba0fffddafe4153bdcc50c4537336f 0 68f824aea0947d9895b968ed46a7972eaae43ef0f2bda7e3ba9113002233ade6 68f824aea0947d9895b968ed46a7972eaae43ef0f2bda7e3ba9113002233ade6
  • 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 createDatabaseConfig; → createDatabaseConfig;, line 1842, a one-line change) hashes raw 4def12da7d94e4d585fad40a829795f80a7fdfeec9d8d4936f68d770a8e3e53d and normalised f98f154135c7fb43f7716274364a3263a4a40d749febc84653c2ad97a4e6f19d. Both differ from the readings above.
  • Export lists: ESM dist/index.mjs and CJS dist/index.js each have 159 names at base and at head, the same list (the sha256 of the sorted names is 3abb126f5babb701… on all four).
  • The bundle: 18 files in dist/ on both sides, the same list. Only index.js, index.mjs and their two .map files differ, as a move of code inside the bundle must.

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), VERDICT command-exit 0. Head: the same counts, VERDICT command-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 2 files: exit 0.
  • The plugin-factory scan, run as both tests run it over auth-manager.ts and auth-manager-actor-guards.ts: 16 factories at base and the same 16 at head. The @better-auth/core imports it skips are 3 at base and 2 at head; the one that left is tryGetCurrentAuthEndpointContext, now in the new module.

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

  • The tenant-audit census (node scripts/tenant-audit-census.mjs --json), compared per site with the new module's file name mapped back to auth-manager.ts: 238 sites on both sides, 0 in the new module, 0 per-site differences in object, verb, tenancy, context and elevation, 0 unresolved and 0 unledgered on both, and every total the same.
  • 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:
    • check-adr-symbol-anchors: 2,384 anchors across 142 records, 466 symbol (440 declaration, 26 literal), at both.
    • check-adr-anchors: 80 anchored files at both. The decision-letter layer reads 2,015 at base and 2,014 at head, as above. The number layer reads 52,147 citations at both, across 6,630 files at base and 6,631 at head (the new module carries the moved ADR-0093 D7).
    • check-scripts-symbol-anchors (4,061 anchors), check-spec-docblock-symbol-anchors (5,071 anchors, both read in the same built tree), check-system-context-census (148 elevation read sites) and check-platform-checklist (16 areas, 329 items): the same reading at both.
  • check-dispatcher-error-vocabulary: 56 found and 56 classified at both.

5. Gates.

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 53 commands for the 2 paths. All 53 ran at 83f5b0249e 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, 283 changed lines.
  • Docs drift (node scripts/docs-audit/affected-docs.mjs --json 860f002f8b, exit 0): 11 pages, 3 of them release-owned. Every one is listed through a literal the moved text carries unchanged: OS_AUTH_SECRET, AUTH_SECRET and BETTER_AUTH_SECRET in generateSecret, and sys_oauth_resource in a comment in createDatabaseConfig. No page restates a rule this move changes, so no doc edit is owed.
  • Serial constraints (in the claim): before the run, none of the 13 open PRs touched plugin-auth/src or a reader above. Since then refactor(plugin-security): move the RLS filter layers out of security-plugin.ts (#25223 cut 7) #25401 (plugin-security only) merged, and origin/main is 2dfeb1a772. On that tree with this cut applied (no conflict):
    • the move proof against 2dfeb1a772 passes 3 of 3;
    • check-tenant-audit-census, check-adr-anchors, check-adr-symbol-anchors, check-platform-checklist, check-system-context-census, check-auth-mount-ledger and check-dispatcher-error-vocabulary exit 0;
    • the decision-letter layer reads 2,005 alone and 2,004 with this cut;
    • the seven suites that drive the moved methods, the staging they reach, or read the file pass (397 tests).

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

…puts into auth-manager-database-secret.ts

Three method bodies move unedited: createDatabaseConfig, which hands
better-auth the ObjectQL adapter factory or, with no data engine, the
in-memory store keyed by model name; resolveAuthSecret, which resolves
the auth secret once per manager; and generateSecret, which reads it
from the environment and refuses to boot production without one. The
class keeps all three methods, their docblocks and signatures, and
hands each body the members it reads.

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 13 documentable anchor(s).

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

  • content/docs/deployment/backup-restore.mdx (via OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/deployment/cli.mdx (via AUTH_SECRET (literal, a string literal in generateSecret), OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/deployment/environment-variables.mdx (via AUTH_SECRET (literal, a string literal in generateSecret), BETTER_AUTH_SECRET (literal, a string literal in generateSecret), OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/deployment/self-hosting.mdx (via AUTH_SECRET (literal, a string literal in generateSecret), OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/deployment/single-project-mode.mdx (via OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/permissions/authentication.mdx (via OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/permissions/sso.mdx (via AUTH_SECRET (literal, a string literal in generateSecret), BETTER_AUTH_SECRET (literal, a string literal in generateSecret), OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/upgrading.mdx (via OS_AUTH_SECRET (literal, a string literal in generateSecret))

⛔ 3 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-3.mdx (via sys_oauth_resource (literal, a string literal in a comment in createDatabaseConfig))
  • content/docs/releases/v18/18-0.mdx (via AUTH_SECRET (literal, a string literal in generateSecret), OS_AUTH_SECRET (literal, a string literal in generateSecret))
  • content/docs/releases/v18/index.mdx (via OS_AUTH_SECRET (literal, a string literal in generateSecret))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 1 anchor(s) matched too much of the corpus to be a work list: sys_user (literal, 42 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 2dfeb1a77254d984c701d7b4b8f1e3892f489686 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from abd798bee12e780fd948be172d9d302a133afce3 — the merge of head 83f5b0249eca67550fce142918146599a1835200 into base 2dfeb1a77254d984c701d7b4b8f1e3892f489686, 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 abd798bee12e780fd948be172d9d302a133afce3 && git checkout abd798bee12e780fd948be172d9d302a133afce3
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 2dfeb1a77254d984c701d7b4b8f1e3892f489686 83f5b0249eca67550fce142918146599a1835200 && git checkout -B drift-repro 2dfeb1a77254d984c701d7b4b8f1e3892f489686 && git merge --no-ff 83f5b0249eca67550fce142918146599a1835200

node scripts/docs-audit/affected-docs.mjs --json 2dfeb1a77254d984c701d7b4b8f1e3892f489686

⚠️ 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 2dfeb1a77254d984c701d7b4b8f1e3892f489686 → 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-23T11:29Z

domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · card #25224 cut 7 (amended claim 6363170079, Ruling-ref: 6348891160; os-dev-report 6363718705; card session branch claude/project-thread-lg3wrj) · reviewed head 83f5b0249eca67550fce142918146599a1835200 · merge base 860f002f8b

  • Shape: the database and secret inputs of createAuthInstance (97 lines) move unedited into auth-manager-database-secret.ts, in cut 1's shape: createDatabaseConfig, resolveAuthSecret and generateSecret. No import leaves auth-manager.ts. createObjectQLAdapterFactory stays imported because a staying docblock links it. No path reader needs to move. 2 files, +192 / −91.
  • Move proof (report): 3 of 3 bodies are token-identical, with a failing negative control.
  • .d.ts, ruling 6348891160 item 1, re-run by the seat in its own worktree. turbo run build --filter=@objectstack/plugin-auth ran at 860f002f8b and at this head, and the hashes are the same at base and head:
    • dist/index.d.ts: raw 12679e13f74973b0510551a65b50808e7c3936a2d273cf2f262a9196648c0737, normalised c7a9fa25f118cfec858d770b979767744d27d9757a9ea4063faeea6238c33c01.
    • dist/index.d.mts: raw df57562ff950159e738d790cb7ee82a655ba0fffddafe4153bdcc50c4537336f, normalised 68f824aea0947d9895b968ed46a7972eaae43ef0f2bda7e3ba9113002233ade6.
    • The raw diff is 0 lines.
    • Seat's positive control: head line 1793, private buildJwtPlugin, made public. Raw 0df245ad99718810… and normalised 927c1cef33786… both moved.
    • Export lists: 159 = 159 (report).
  • Gates re-run by the seat, all exit 0 at base and at head:
    • check-adr-symbol-anchors: 2384 … 466 symbol.
    • check-tenant-audit-census: 238 sites.
    • check-dispatcher-error-vocabulary
    • check-adr-anchors: the decision-letter count reads 2015 at base and 2014 at head. The one ADR-0093 D7 citation in the createDatabaseConfig callback comment leaves the anchored file. As with 6360020819, no anchor entry is added.
    • Report merge check on 2dfeb1a772: 2005 → 2004.
  • Self-correction (report): the claim listed first-session-membership-ordering.test.ts as driving the moved methods. It drives stageUserCreatedInRequest only. The PR body and the report say so.
  • Tests and gates (report): plugin-auth 189 files, 3580 pass at both ends. dispatch-gates --ran 53 / 53. CI on this head: 38 success and 15 expected skips, none failed or pending. Mergeable clean, and git merge-tree onto today's main is clean.
  • Body: the seat added the attribution header and requested os-sales through the relay (read back identical).
  • Declarations: refactor(plugin-auth), Clause-②: no, Metadata-protocol: none, skip-changeset. No contract-review record or dogfood battery is owed. Out-of-scope findings: none.
  • Landing: not governed (check-governed-merges --pr 25404: 283 lines). Ready + auto-merge through the relay. The card stays open and dispatched.
  • Cut 8 scope, agreed by the seat: validateAudienceAdmission, sendExistingAccountSignUpNotice, settleSelfRegistrationGrant, landSelfRegistrationGrant, reportUngrantedSelfRegistrant and settleMembership.
    • Bodies that read private static fields stay in the class. Reading those through a host would change the bodies.
    • Those bodies and the unexported-shared-helper area go to the coordinator together in one A/B/C needs_decision.

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