Repository navigation
Commit 19d3720
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuMjbPDrsigsyqoKsV4WZQMz)_
Part of #25224
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6348891160, 6364006498
The basis for the `Clause-②: no` line: this is a move plus two
path-reader migrations. No accept set, route, refusal, code or answer
changes, and the published surface is measured unchanged:
- `@objectstack/plugin-auth`'s `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). The positive control is the one ruling
`6348891160` asks for.
- Its ESM and CJS entries export the same 159 names at base 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. This is the
fifth cut it applies to.
Cut 13 of the `auth-manager.ts` split: **the global before-hook of the
better-auth instance**. It is the second of the three
`createAuthInstance` slices the seat set (`hooks.after`, then
`hooks.before`, then the rest of the method). #25224 stays open for the
later cuts.
This follows the amended claim `6376168919`, which amends `6374301142`
on the file cut 12 left (#25536, landed note `6375260860`). The shape is
cut 12's: #23050's, applied to a closure. The seat ruled that in scope
at 19:56Z, with the bars listed below.
Branch: `claude/project-thread-lg3wrj`, the harness-pinned branch for
this session, restarted from `origin/main` `93a6ba4136` after #25536
merged. It names no issue, so the card relation is this body's first
line.
`auth-manager.ts` goes from 8,362 to 7,800 lines. The cut is +734 / −597
over 4 files: 1,331 changed lines, under the 3,000-line line. Two of the
four files are path readers outside the move, so
`check-governed-merges.mjs --test` ran on the final file list before the
claim: NOT governed (0 of 4 paths hit the register), and `--branch HEAD`
agrees. One commit: `3ec293d86a` `refactor(plugin-auth): move the
better-auth global before-hook into auth-manager-before-hook.ts`.
## The move
| moved | base lines | proof lines | tokens | members it reads |
|---|---|---:|---:|---:|
| the `hooks.before` arrow body in `createAuthInstance` |
`:2246`–`:2827` | 584 | 1,326 | 18 methods, 1 field |
The lines are base `93a6ba4136`. The 584 proof lines are the body with
its braces (`:2245`'s `{` to `:2828`'s `}`).
- **What it is:** `createAuthInstance` (`:1695`, private, annotated
`Promise<Auth<any>>`) builds one config literal for better-auth. Its
`hooks.before` is `createAuthMiddleware(async (ctx: any) => {BODY})`:
the before-hook every better-auth endpoint's request passes through
before the endpoint runs.
- **What BODY does, in order** (all of it moves, with its comments): the
actor resolver handed to the attribution scope, the refresh skip for a
minted principal session, the per-number OTP send guard, the password
complexity and reuse checks, the change-email capture, the
remove-member, organization-delete and no-record revoke refusals, the
held-caller refusal on the admin plugin's role-scalar actions, the
no-record admin revoke refusal, the held-caller refusal on rewriting or
deleting an identity provider, the identity-provider registration gate,
the cloud-as-IdP authorization gate, the break-glass
last-local-credential refusal, the audience posture and uniqueness
refusal on password sign-up, the cloud-managed invite-member refusal,
the account lockout gate, and the first-user `disableSignUp` flip.
- **Where it goes:** a new module,
`packages/plugins/plugin-auth/src/auth-manager-before-hook.ts` (696
lines). BODY becomes the body of `export async function
globalBeforeHook(this: BeforeHookHost, ctx: any,
setShouldSkipSessionRefresh: typeof
import('better-auth/api').setShouldSkipSessionRefresh)`, re-indented
eight spaces (four levels) and otherwise unedited. The module header
gives the reasoning, in the form the twelve earlier `auth-manager-*.ts`
modules use.
- **What stays:** `createAuthInstance` keeps its place, docblock and
signature, and `hooks.before` keeps its place in the literal. Its arrow
is now:
```ts
// [#25224 cut 13] The body moved to `auth-manager-before-hook.ts`; this
// arrow hands it the members it reads (`BeforeHookHost`) and the one
// local it read, `setShouldSkipSessionRefresh`.
before: createAuthMiddleware((ctx: any) => {
const readConfig = () => this.config;
const host: BeforeHookHost = {
assertAccountNotLocked: (...a) => this.assertAccountNotLocked(...a),
// … one closure per method, alphabetical, 18 in all, and:
get config() { return readConfig(); },
};
return globalBeforeHook.call(host, ctx, setShouldSkipSessionRefresh);
}),
```
Nothing else in `createAuthInstance` changes.
## The seat's bars
**Body.**
- BODY is the same TypeScript token sequence at base and in
`globalBeforeHook`: 584 lines, 1,326 tokens. Every line is the base line
minus exactly eight spaces. The first parameter (`ctx: any`) is the same
text; the second is the captured local, below. Neither side has a return
annotation.
- **`async` moves from the arrow to the function.** The head arrow is
not `async`, and it returns `globalBeforeHook.call(host, ctx,
setShouldSkipSessionRefresh)`, the function's own promise, unchanged.
better-auth's `createAuthMiddleware` is better-call 1.4.4's
`createMiddleware`, whose handler wrapper runs `const response = await
_handler(internalContext);` inside its `try` (`dist/middleware.mjs:15`).
So it awaits the same promise BODY settles, with the same value or
rejection, and its `catch` sees the same error. The reader closure, the
host literal and the `.call` cannot throw before that promise exists.
- **No `arguments`, `new.target` or `super`** (0 of each), where an
arrow and a function differ. There is no bare `this`: BODY's only `this`
uses are 28 member reads, `this.X`.
**One captured local, now a parameter.** Unlike cut 12's body, this one
read a `createAuthInstance` local: `setShouldSkipSessionRefresh`, once
(`:2273`, `if (carriesPrincipalSession(ctx)) await
setShouldSkipSessionRefresh(true);`).
- The method binds it once, `const { createAuthMiddleware,
setShouldSkipSessionRefresh } = await import('better-auth/api');` at
`:1697`, before it builds the literal, and never reassigns it.
- It becomes the function's second parameter, under the same name, typed
`typeof import('better-auth/api').setShouldSkipSessionRefresh`. The head
arrow passes the same binding on every call. The base arrow read that
`const` when the hook ran, and the head arrow reads it at the same
moment and hands it on, so BODY calls the same function object.
- None of the method's other locals declared before the literal
(`betterAuth`, `createAuthMiddleware`, `plugins`, `passwordHasher`) is
read in BODY. The binding proof below finds no other identifier in BODY
bound in the method.
**Receiver.**
- BODY's `this` was the `AuthManager` instance, the arrow's lexical
receiver. It is now the host.
- `BeforeHookHost` names exactly the 19 members BODY reads, no more,
each typed as the class member (`AuthManager['x']`).
- 18 are methods, so each goes as a late-bound closure, `(...a) =>
this.x(...a)`. The method runs on the manager and is looked up when BODY
calls it, so a spy or double set on the manager is still the one BODY
reaches: `assertAccountNotLocked`, `assertActorNotHeld`,
`assertAdminRevokeUserSessionIdentifiesRecord`,
`assertOrganizationDeletable`, `assertPasswordComplexity`,
`assertPasswordNotReused`, `assertPhoneOtpSendAllowed`,
`assertRemoveMemberPermitted`, `assertRevokeSessionIdentifiesRecord`,
`existingAddressSignUpAnswersSuccess`, `hasExistingUserFor`,
`isAuthGateActive`, `isBootstrapCreation`, `isOperatorProvisioning`,
`isPlatformAdminUserId`, `resolveActor`, `resolvePasswordChangeUserId`
and `validateAudienceAdmission`.
- One is a field: `config`. The class reassigns it after construction
(`setRuntimeBaseUrl` at `:4549`, `applyConfigPatch` at `:4630`), so it
goes as a getter over a reader closure (`const readConfig = () =>
this.config;` and `get config() { return readConfig(); }`), the shape
cut 6's stubs use. BODY reads the manager's current object each time. It
is `readonly` on the interface, and BODY never writes it.
- **A function-valued member, disclosed** (the way #25516 disclosed
`resolveKernelService`): BODY calls `this.config.oidcAuthorizeGate({…})`
(`:2546`, after the presence check at `:2536`), an optional function on
the config object (`AuthManagerOptions`, `:789`). Its receiver is
`this.config`, which the getter returns as the manager's current object,
so the gate is looked up and called on the same object, at the same
moment, with the same `this`, as before.
- `hasExistingUserFor` and `isBootstrapCreation` read private statics.
They stay in the class, per ruling A, and BODY reaches them as members.
**One static read, a value import.** BODY reads
`AuthManager.OPERATOR_PROVISIONING_TICKET_FIELD` once (base `:2820`,
module `:688`), a public `static readonly` string (`:4844`). The module
imports the class by value from `./auth-manager.js`, as cut 8's
`auth-manager-membership-admission.ts` does. The one read is inside the
function, at call time, so the cycle is never read during evaluation
(below).
**Host lifetime.** The host is built inside the arrow, once per run of
the hook: each time better-auth runs `hooks.before` on a request. This
is what every method stub in this series does. Nothing BODY reads is
captured early: the 18 closures look each method up on the manager at
call time, and the getter reads `config` when BODY reads it.
**Readers.** The decision letters are read on the merge base and on the
head below: 10 drop, as expected. No anchor entry is owed. Tenant census
and symbol-anchor output are byte-identical at both ends, and the full
plugin-auth suite passes at both ends. The two path readers that read
the moved lines are migrated in this commit.
## Imports and evaluation order
Nine names leave `auth-manager.ts`, because BODY was their last reader
there:
- `setAuthActorResolver` (its import line goes);
- `SIGN_IN_EMAIL_PATH` (cut 12 left BODY its last reader here; the block
keeps `type AuthEventAuditSurface`);
- `VENDOR_ROLE_SCALAR_ADMIN_PATHS`, `carriesPrincipalSession` and
`ORGANIZATION_DELETE_PATH` (each block keeps its other names);
- the whole `last-local-credential.js` block:
`isLastLocalCredentialHolder`, `LAST_LOCAL_CREDENTIAL_CODE` and
`LAST_LOCAL_CREDENTIAL_MESSAGE`.
`isCloudManaged`, `CLOUD_MANAGED_REFUSAL_CODE` and
`CLOUD_MANAGED_REFUSAL_MESSAGES` have other readers in
`auth-manager.ts`, so both files import them. One import line is added
after cut 12's, with a comment in the same form: `import {
globalBeforeHook, type BeforeHookHost } from
'./auth-manager-before-hook.js'`.
esbuild drops a type-only import, so a module whose last value import
leaves `auth-manager.ts` can now be evaluated later. The order was
measured rather than argued:
- **The ES modules, at run time.** A loader hook logged each ES module
as its body ran while `dist/index.mjs` loaded, at base and at head. 171
modules evaluate at both, in the same order, except one:
`@better-auth/core/dist/utils/ip.mjs` now runs just after
`@objectstack/platform-objects`' `identity` entry instead of just before
it. Its own dependencies (`env/env-impl.mjs`, `zod`) run much earlier at
both, unchanged. Its top level is two `zod` schema objects (`z.ipv4()`,
`z.ipv6()`), constants and function declarations, and it registers
nothing.
- **The CommonJS entry.** A `Module._load` log for `dist/index.js` gives
127 first loads at both, the same apart from that one module, which now
loads last.
- **plugin-auth's own modules.** A walk of the bundle's top level and
its eager `init_*` calls finds two that run later:
`auth-session-audit.ts`, whose one value import in `auth-manager.ts` was
`SIGN_IN_EMAIL_PATH`, and `last-local-credential.ts`. Their top levels
are string and regex constants and function declarations, with no side
effect. `auth-session-audit.ts`'s one import is `getIP` from that `ip`
module, which is why the `ip` module moves with it. No importer reads
either module's bindings at load time: all 24 references in the 5
importing files are inside functions, and `index.ts` re-exports both.
- `auth-actor-attribution.ts`, whose `setAuthActorResolver` leaves, is
an `__esm`-wrapped module that another importer initialises earlier, at
both, so it does not move. The other modules keep a value import in
`auth-manager.ts`.
- The new module's own top level is imports, one interface and one
function declaration. Its value import of `auth-manager.ts`, for the
static, and `auth-manager.ts`'s import of it form a cycle with nothing
read at load time.
## The decision-letter layer: −10, as expected
`check-adr-anchors`, measured on the merge base and on the head. The
gate exits 0 at both.
| point | anchored files | citations | files | decision letters |
|---|---:|---:|---:|---:|
| merge base `93a6ba4136` | 84 | 52,274 | 6,681 | 1,955 |
| head `3ec293d86a` | 84 | 52,274 | 6,682 | 1,945 |
- The ten letters are in BODY's comments: ADR-0095 D3 (`:2258`),
ADR-0069 D1 (`:2292`, `:2308`), ADR-0069 D3 (`:2406`, `:2445`, `:2492`),
ADR-0135 D6 and ADR-0068 D4 (`:2463`), ADR-0068 D4 (`:2481`) and
ADR-0069 D2 (`:2787`). They leave `auth-manager.ts`, which is anchored,
for a module that is not. Their citations still resolve, so the citation
count does not move.
- **No entry is owed.** The `auth-manager.ts` entry has two paragraphs:
ADR-0108 (better-auth's organization roles map) and ADR-0093 D2
(`settleMembership` and its two seams, `user.create.after` and
`session.create.before`, which are database hooks, not `hooks.before`).
Neither describes this hook, and no other entry names it. So, per the
seat's bar, no entry is added for the new module.
## Path readers
Two readers outside the move read the moved lines by path, and both
follow BODY in this commit:
- **`api-error-code.pin.test.ts`**: `authManagerFiles` gains
`'auth-manager-before-hook.ts'`. BODY carries 5 of the auth manager's
`new APIError(` sites (`:2505`, `:2552`, `:2651`, `:2691`, `:2781`).
Without the entry the floor would still pass, silently, at 25 against `≥
24`. With it the count stays 30, as at base.
- **`scripts/check-dispatcher-error-vocabulary.mjs`**:
`APIERROR_ARGUMENT_POSITION_CENSUS.liveMemberFile` now names
`packages/plugins/plugin-auth/src/auth-manager-before-hook.ts`, where
`BASE_ERROR_CODES.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL`
(`APIError.from`, base `:2752`) now lives, with a two-line comment that
the counts stay the reading at `measuredOn`. The three comments that
name the file the idiom lives in say the new module too. No count,
pattern or verdict changes. The gate exits 0 at both: 56 sites found and
56 classified, and only its scanned-file count moves (3,424 → 3,425).
`--self-test` passes (11 shapes, 396 assertions).
Read, and not edited:
- **The tenant-audit census.** No census site moves: BODY has no engine
write (its one `adapter.findOne` is in a comment, `:2802`), no
`this.X.delete()` and no elevation read. `check-tenant-audit-census`
exits 0 at both with no `--write`, and its output is byte-identical. The
`--json` document has 238 sites at both and 0 per-site differences with
line numbers ignored. 2 sites are in `auth-manager.ts` at both (each 562
lines earlier at head, the cut's net), and 0 are in the new module. Only
`scannedSources` (747 → 748) and `measuredAt` differ, so neither census
document is edited.
- **`scripts/measure-durability-swallow-family.mjs`** (a measurement,
not a gate): 77 members and 84 quiet rows at both. The members are the
same with line numbers ignored (one member's write line, in
`observeFirstMemberships`, which stays, moves 5,739 → 5,177), and the
quiet rows are identical. Only the scanned file count moves (3,474 →
3,475, the new module). `tryStatements` (3,640), `droppedNotAwaited`
(235) and every other statistic are the same: BODY's `try` blocks move
whole.
- **`check-auth-mount-ledger.mjs`** reads only the `basePath`
declaration in `auth-manager.ts`, which stays.
**`auth-manager-base-path.test.ts`** reads `auth-manager.ts` for code
lines carrying `'/api/v1/auth'`; BODY has none.
- **The plugin-factory scans** in `better-auth-schema-parity.test.ts`
and `managed-extension-fields.test.ts` match `const { X } = await
import('better-auth/plugins…' | '@better-auth/…')`. BODY's dynamic
imports are `better-auth/api` and `@better-auth/core/error`, and
`@better-auth/core` is excluded, so none is a factory. Both suites pass
at head.
- **`rate-limit-storage-isolation.test.ts`** walks the import graph from
`rate-limit-storage.ts`, which reaches neither file. It passes at head.
- **The system-context census** reads 149 elevation read sites at both,
with byte-identical output.
- **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, at base with BODY blanked, and at head. Two
of their symbols occur as a token on a line of BODY: `AuthManager`
(ADR-0135 `:104`; BODY `:2820`, the static read) and
`isBootstrapCreation` (the identity-auth checklist area `:1810`; BODY
`:2823`, a member call). Each resolves to its declaration, which stays,
at all three readings.
## Proof
Builds and suites ran through `os-verify-lock`, and every exit code was
captured before any pipe. Base `93a6ba4136`. A full `turbo run build`
ran first. Then `plugin-auth` was built and its suite run at base, and
built and run again at head, on the same dependency dists.
**1. The moved text.**
- **Token identity:** the base arrow body and the module 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): 584 lines and 1,326 tokens, each line the base line
minus eight spaces.
- **The head arrow's shape**, checked by the same run: not `async`, the
same first parameter, the reader closure for `config`, one host literal
whose keys are exactly `BeforeHookHost`'s, whose 18 method values are
each `(...a) => this.<key>(...a)` and whose `config` is the getter over
the reader, then `return globalBeforeHook.call(host, ctx,
setShouldSkipSessionRefresh)`, and nothing else.
- **Binding identity:** a second proof walks all 356 identifiers of BODY
at base and in the module, in order, and resolves each with the
TypeScript checker (the module's `./auth-manager.js` resolved to the
base file). All 356 resolve the same way at both ends:
- 69 to a parameter: `ctx`, and the captured local, which the proof is
told about;
- 119 to a declaration inside BODY, the same declaring identifier by
position;
- 29 to the class's members: the 28 receiver reads (`AuthManager` at
base, `BeforeHookHost` at head) and the one static;
- 12 to imports with the same specifier and imported name, the class
itself among them;
- 2 to the same declaration in the base file: `oidcAuthorizeGate` on
`AuthManagerOptions`, twice;
- 125 to no declaration: globals and property names on untyped values.
None resolves to any other `createAuthInstance` local or to an
unexported top-level declaration of either file.
- **Negative controls:** each proof reads the module text, and each
control changes it in memory only; the file is untouched.
- Token proof: `setShouldSkipSessionRefresh(true)` changed to `(false)`
fails the token and line checks, and the run exits 1.
- Binding proof: the module's `last-local-credential` import pointed at
another specifier gives 3 differences, and the run exits 1. Run without
being told about the captured local, it reports that local, and exits 1.
- **An independent reading:** `git diff --color-moved=plain
--color-moved-ws=allow-indentation-change 93a6ba4 3ec293d` over
the two source files marks 588 of the 593 deleted lines and 596 of the
727 added lines as moved.
- The 5 unmoved deletions are four import-name lines
(`SIGN_IN_EMAIL_PATH,`, `VENDOR_ROLE_SCALAR_ADMIN_PATHS,`,
`carriesPrincipalSession,` and `ORGANIZATION_DELETE_PATH,`, each now on
its own line in the module) and the `before: createAuthMiddleware(async
(ctx: any) => {` line (now without `async`).
- The other added lines are the module header, its import lines, the
host interface and its docblock, the function signature and docblock,
the arrow's comment, reader, host literal and `return`, and the new
import comment and line.
**2. `.d.ts` and exports (ruling `6348891160` items 1 and 2).**
| file | base and head | raw diff lines |
|---|---|---:|
| `dist/index.d.ts` raw |
`1b3a48357d137155de33104277667a922aab62df73b418b03894c56faaacd0ba` | 0 |
| `dist/index.d.ts` normalised |
`cee7303ccdfe72794efd588c85b628419d4253d730b5a0c5a3f1cdb8dddb4443` | |
| `dist/index.d.mts` raw |
`b5e8dc982b634f0a5108b1b533626a68767f2da5a56f72dba801059b149e2872` | 0 |
| `dist/index.d.mts` normalised |
`562d0a4ce656f97aeb937541482cdf531b61d7c75a005918784bf0a52d032dfc` | |
- 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 byte-identical, so no union-order swap occurs: 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 createAuthInstance;` →
`createAuthInstance;`, line 1712, a one-line change) hashes raw
`35b18682171cd394898c9e56bc8d5272ccf20aeff0d1966fc568cb5e566a08df` and
normalised
`e69c1b0157b45e48bbc16bd64eb939abf9be33ccb31553485df93ef05aac6fc3`. 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). `globalBeforeHook` and
`BeforeHookHost` are not among them, and `dist/index.d.ts` names
neither.
- **The bundle:** the same 18 files in `dist/` at both, plus the two
`.build-input-hash` stamps the build writes from its inputs. Only
`index.js`, `index.mjs` and their two `.map` files differ, as a move of
code inside the bundle must. `tsup` bundles the new module into the root
entry (`splitting: false`).
**3. Tests and lint.**
- `pnpm exec vitest run --maxWorkers=3` in
`packages/plugins/plugin-auth`: base `Test Files 191 passed (191)`,
`Tests 3607 passed | 10 skipped (3617)`, exit 0. Head: the same counts,
exit 0. The pin test's `authManagerFiles` sum is 30 at both.
- `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 files: exit 0.
**4. The censuses, the measurement and the anchors, at base and at
head.**
- The tenant-audit census, as above: byte-identical gate output, 238
sites at both, 0 per-site differences line-blind, 0 unresolved and 0
unledgered at both.
- The durability measurement, as above.
- 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.
Five print byte-identical output at both (`cmp` clean):
- `check-adr-symbol-anchors`: 2,384 anchors across 142 records, 466
symbol (440 declaration, 26 literal);
- `check-scripts-symbol-anchors`: 4,070 anchors;
- `check-spec-docblock-symbol-anchors`: 5,076 anchors;
- `check-system-context-census`: 149 elevation read sites;
- `check-platform-checklist`: 16 areas, 329 items.
The sixth, `check-adr-anchors`, differs only in the file count and the
decision letters, as in the table above.
**5. Gates.**
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derives 80 commands for the 4 paths. All 80
ran at head after the full build, and all 80 exited 0.
- `--ran` over the record with each exit code: 80 derived, 80 run, 0
NOT-MEASURED, a derived zero. `--tier`: no path-derived mandate.
- `check-governed-merges.mjs`: `--test` on the final file list before
the claim and `--branch HEAD` after the commit both read NOT governed (0
of 4 paths hit the register), 1,331 changed lines.
- **Docs drift** (`node scripts/docs-audit/affected-docs.mjs --json
93a6ba4`, exit 0): 2 pages, both name matches only.
`content/docs/kernel/contracts/auth-service.mdx:39` is the auth service
contract's `isAuthGateActive?()`, which the class implements unchanged;
`BeforeHookHost` only names the member.
`content/docs/permissions/system-context.mdx:172` cites
`plugin-approvals`' `approval-service.ts#resolveActor`, another symbol.
0 release-owned pages, so no doc edit is owed.
- **Serial constraints** (in the claim): 11 PRs are open. One, #25541
(another account's, on a base before cut 12), touches `auth-manager.ts`:
a comment inside the `hooks.after` body, which cut 12 already moved out,
and one property in `externalDirectoryDoorDeps`, which stays. Neither is
in BODY or in an import line this cut edits, and it touches no reader
named above. The Version Packages PR #24876 touches `plugin-auth`'s
`package.json`, its `CHANGELOG.md` and changesets only. `origin/main`
has moved 4 merges past this base, to `4df174bcc4` (#25539, #25538,
#25528, #25543); none touches `plugin-auth`, `scripts/adr-anchors/` or a
reader named above.
## 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](https://claude.ai/code/session_01LSXBc2GCBwiAL7vV4kWkyr)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01LSXBc2GCBwiAL7vV4kWkyr
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 51e804c commit 19d3720
4 files changed
Lines changed: 734 additions & 597 deletions
File tree
- packages/plugins/plugin-auth/src
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
| 184 | + | |
184 | 185 | | |
185 | 186 | | |
186 | 187 | | |
| |||
0 commit comments