Skip to content

Commit 67ab712

Browse files
refactor(plugin-auth): drop AuthManager's 12 counted query-options any assertions and ratchet the erasure baseline (#25224) (#25326)
<!-- 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: 6351993113 The basis for the `Clause-②: no` line: dropping a type assertion widens no accept set and no public surface, and a type assertion has no emitted byte. Measured below: `@objectstack/plugin-auth`'s `dist/index.js`, `dist/index.mjs`, `dist/index.d.ts` and `dist/index.d.mts` are byte-identical to base. **The sweep PR of ruling `6351993113` item 1**, between cut 2 (PR #25307, landed note `6354354210`) and the cut(s) that move the nine methods these sites sit in. It follows the amended claim `6354594310`. #25224 stays open for the later cuts. `scripts/query-options-erasure-baseline.json` grandfathered `auth-manager.ts` at 12 engine query-options `any`-erasures. This PR drops all 12 in place and ratchets the baseline down, so the nine methods can later move into new modules without carrying a counted site into a file the baseline does not list. Nothing else changes: +12 / −13 over 2 files. Branch: `claude/project-thread-lg3wrj`, the harness-pinned branch for this session, restarted from `origin/main` `9dc1f42d50` after #25307 merged. It names no issue, so the card relation is this body's first line. ## What changes 1. **`packages/plugins/plugin-auth/src/auth-manager.ts`**: 12 lines. Each counted closer `} as any);` becomes `});`. Each one closes the options literal (argument 1) of an `engine.findOne`, `engine.find` or `engine.count` call that carries `context: SYSTEM_CTX`. The edit was made from the AST: for each call ESLint reports, the script removed exactly the text ` as any` between the literal's `}` and the call's `);`, and refused any site where those 7 characters were anything else. 2. **`scripts/query-options-erasure-baseline.json`**: exactly what `pnpm check:query-options-erasure --update` writes. The file's key leaves (one line). This is a `scripts/` ledger, and `scripts/` gate files are `domain:spec`'s by the anchoring exception. **Cross-lane, declared:** the edit is the gate's own prescribed ratchet output, not a gate edit. ⛔ Not in this PR (ruling item 1): - the 13 `engine.update(…, { context: SYSTEM_CTX } as any)` casts, which the ratchet does not count; - any `as unknown as EngineQueryOptions` or `const opts: EngineQueryOptions` rewrite; - any other erasure in the file; - `eslint.config.mjs` or any `scripts/*.mjs`; - any method move. ## The twelve sites Re-located by shape at base `9dc1f42d50`: ESLint's `query-options/no-any-erasure`, run on the file's text with the grandfathering lifted, reports exactly 12, the baseline's count. These are the ruling's twelve sites in the ruling's nine methods; only their line numbers have moved since `49185cdb`. | method | call (line) | closer line | |---|---|---| | `stampIdentitySource` | `engine.findOne` `:8854` · `engine.count` `:8864` | `:8856` · `:8867` | | `refreshMustChangeCacheIfStale` | `engine.count` `:9007` | `:9009` | | `refreshOrgMfaCacheIfStale` | `engine.count` `:9035` | `:9037` | | `resolveUserAuthGates` | `engine.findOne` `:9184` · `engine.findOne` `:9193` | `:9188` · `:9195` | | `assertPasswordNotReused` | `engine.findOne` `:9374` | `:9378` | | `recordPasswordHistory` | `engine.findOne` `:9421` | `:9425` | | `unlockUser` | `engine.findOne` `:9689` · `engine.find` `:9703` | `:9691` · `:9705` | | `enforceSessionControls` | `engine.findOne` `:9748` | `:9752` | | `enforceConcurrentCap` | `engine.find` `:9832` | `:9837` | ## Report block (ruling `6351993113` item 2) Base `9dc1f42d50`, head `32f94b8b70`. Every exit code was captured before any pipe. Builds and suites ran through `os-verify-lock`. - **Typecheck.** `pnpm --filter @objectstack/plugin-auth typecheck` (both `tsc` projects and `check:test-typecheck`): **exit 0**, after `turbo run build --filter='@objectstack/plugin-auth^...'`. - **ESLint.** `node --stack-size=4000 node_modules/eslint/bin/eslint.js --no-inline-config packages/plugins/plugin-auth/src/auth-manager.ts` (the root `lint` script's binary and flags): **exit 0**. The file's key is gone, so the rule now lints it at `error`, and it flags nothing. - **The ratchet.** - With the 12 closers dropped and the baseline untouched, `pnpm check:query-options-erasure` exits **1**: `packages/plugins/plugin-auth/src/auth-manager.ts: baselined file is clean/gone (was 12) — ratchet DOWN: run pnpm check:query-options-erasure --update and commit the baseline.` - `pnpm check:query-options-erasure --update` exits 0 (`baseline updated: 50 non-test site(s) in 15 file(s)`), and the baseline diff is that one line. - Re-run: **exit 0**, `ratchet holds: 50 unswept non-test site(s) in 15 file(s), none new, and every file measured parsed`, and `baseline key set verified against 9dc1f42: no files added`. - **The bundle.** `pnpm run build` in `packages/plugins/plugin-auth`, at base and at head, on the same dependency dists. 18 files in `dist/` on both sides, the same list; 16 of them are byte-identical: | file | sha256 at base and at head | |---|---| | `dist/index.js` | `6f45fdf90839b0de47090a92e75f0309c0baa628ed838956a2522c2fad40f034` | | `dist/index.mjs` | `2cb04450a30b102aac0df38ebded7bd138b16968cf01dd65e11214269e27712f` | | `dist/index.d.ts` | `4bc04c66f724c79782493249820b1b7d9bff7c826931ce6b362d325af8797891` | | `dist/index.d.mts` | `d70d7d8063053de2d39bd0dbae06423bbe0ef1dcecf5130b867c6f4d79a0c8cd` | The only files that differ are `index.js.map` and `index.mjs.map`, and in each only the `mappings` key differs (`version`, `sources` and `names` are equal). - These maps carry no `sourcesContent`, which `check:sourcemap-no-sources-content` enforces. So the cause is not the one the ruling expected (embedded source text). It is the source positions. - Decoded, each map holds the same number of segments on both sides (67,009 and 67,083). Exactly 12 differ in each map: one on each of the 12 closer lines, at the same generated position, with a source column 7 lower. That is the width of ` as any`, so it is the `)` after the literal. - **Tests.** `pnpm exec vitest run --maxWorkers=3` in `packages/plugins/plugin-auth`: base `Test Files 187 passed (187)`, `Tests 3525 passed | 10 skipped (3535)`, VERDICT command-exit 0; head the same counts, VERDICT command-exit 0. - **Positive control.** One of the 12 restored (`:8856` back to `} as any);`), nothing else: - `pnpm check:query-options-erasure` exits **1**: `packages/plugins/plugin-auth/src/auth-manager.ts: NEW engine query-options erasure (1 site(s)). … This file is not grandfathered, and the baseline never grows.` - The same ESLint command exits **1** at `8854:52` (`query-options/no-any-erasure`). - Restored with `git checkout --` afterwards; `git diff HEAD` was empty. ## Gates - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derives 63 commands for the 2 paths. All 63 ran at `32f94b8b70` after a full `turbo run build`, and all 63 exited 0. - `--ran`: 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN. - `check-governed-merges.mjs --branch HEAD`: NOT governed, 25 changed lines. - Serial constraints are in the claim. Of the open PRs, only #25309 touches `auth-manager.ts`: an import line and the public-config literal near `:8011`, none of the 12 lines. `git merge-tree` of this branch with #25309's head is clean. ## Changeset None: `skip-changeset`, per ruling `6348891160` item 4, as ruling `6351993113` item 1 reads it. The emitted bundle and declarations are byte-identical, so this PR publishes nothing. --- _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 3e51491 commit 67ab712

2 files changed

Lines changed: 12 additions & 13 deletions

File tree

‎packages/plugins/plugin-auth/src/auth-manager.ts‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8853,7 +8853,7 @@ export class AuthManager {
88538853
// managed (avoids a no-op history row on every local signup).
88548854
const u = await engine.findOne('sys_user', {
88558855
where: { id: userId }, fields: ['id', 'source'], context: SYSTEM_CTX,
8856-
} as any);
8856+
});
88578857
if (u && u.source === 'idp_provisioned') {
88588858
await engine.update('sys_user', { id: userId, source: 'env_native' }, { context: SYSTEM_CTX } as any);
88598859
}
@@ -8864,7 +8864,7 @@ export class AuthManager {
88648864
const credentialCount = await engine.count('sys_account', {
88658865
where: { user_id: userId, provider_id: 'credential' },
88668866
context: SYSTEM_CTX,
8867-
} as any);
8867+
});
88688868
if (typeof credentialCount === 'number' && credentialCount > 0) return;
88698869
await engine.update('sys_user', { id: userId, source: 'idp_provisioned' }, { context: SYSTEM_CTX } as any);
88708870
} catch (e) {
@@ -9006,7 +9006,7 @@ export class AuthManager {
90069006
const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] };
90079007
const n = await engine.count('sys_user', {
90089008
where: { must_change_password: true }, context: SYSTEM_CTX,
9009-
} as any);
9009+
});
90109010
this._mustChangeCache = { value: typeof n === 'number' && n > 0, at: Date.now() };
90119011
} catch {
90129012
// leave the prior value; try again after the TTL
@@ -9034,7 +9034,7 @@ export class AuthManager {
90349034
const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] };
90359035
const n = await engine.count('sys_organization', {
90369036
where: { require_mfa: true }, context: SYSTEM_CTX,
9037-
} as any);
9037+
});
90389038
this._orgMfaCache = { value: typeof n === 'number' && n > 0, at: Date.now() };
90399039
} catch {
90409040
// leave the prior value; try again after the TTL
@@ -9185,14 +9185,14 @@ export class AuthManager {
91859185
where: { id: userId },
91869186
fields: ['password_changed_at', 'two_factor_enabled', 'mfa_required_at', 'must_change_password'],
91879187
context: SYSTEM_CTX,
9188-
} as any);
9188+
});
91899189

91909190
// Effective MFA requirement: global floor OR the active org's require_mfa.
91919191
let mfaRequired = mfaGlobal;
91929192
if (!mfaRequired && orgMaybeRequires) {
91939193
const org = await engine.findOne('sys_organization', {
91949194
where: { id: activeOrgId }, fields: ['require_mfa'], context: SYSTEM_CTX,
9195-
} as any);
9195+
});
91969196
mfaRequired = org?.require_mfa === true || org?.require_mfa === 1;
91979197
}
91989198

@@ -9375,7 +9375,7 @@ export class AuthManager {
93759375
where: { user_id: userId, provider_id: 'credential' },
93769376
fields: ['id', 'password', 'previous_password_hashes'],
93779377
context: SYSTEM_CTX,
9378-
} as any);
9378+
});
93799379
// [commit d6e80b28b] Both columns are `internal: true`, so the engine's read path
93809380
// omits them from the row above — with no `isSystem` carve-out and in
93819381
// spite of the explicit projection (#7728's design). Recover them
@@ -9422,7 +9422,7 @@ export class AuthManager {
94229422
where: { user_id: userId, provider_id: 'credential' },
94239423
fields: ['id', 'previous_password_hashes'],
94249424
context: SYSTEM_CTX,
9425-
} as any);
9425+
});
94269426
if (!account?.id) return;
94279427
// [commit d6e80b28b] As above — the flagged column is omitted from the read, so
94289428
// recover it before extending the ring. Without this the ring is rebuilt
@@ -9688,7 +9688,7 @@ export class AuthManager {
96889688
const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] };
96899689
const u = await engine.findOne('sys_user', {
96909690
where: { id: userId }, fields: ['id'], context: SYSTEM_CTX,
9691-
} as any);
9691+
});
96929692
if (!u?.id) return false;
96939693
await engine.update(
96949694
'sys_user',
@@ -9702,7 +9702,7 @@ export class AuthManager {
97029702
try {
97039703
const enrolments = await engine.find('sys_two_factor', {
97049704
where: { user_id: String(userId) }, fields: ['id'], context: SYSTEM_CTX,
9705-
} as any);
9705+
});
97069706
for (const row of (enrolments ?? []) as Array<{ id?: string }>) {
97079707
if (!row?.id) continue;
97089708
await engine.update(
@@ -9749,7 +9749,7 @@ export class AuthManager {
97499749
where: { id: sessionId },
97509750
fields: ['id', 'created_at', 'last_activity_at', 'revoked_at'],
97519751
context: SYSTEM_CTX,
9752-
} as any);
9752+
});
97539753
if (!srow?.id || srow.revoked_at) return;
97549754
const now = Date.now();
97559755
let reason: string | undefined;
@@ -9834,7 +9834,7 @@ export class AuthManager {
98349834
fields: ['id', 'created_at', 'expires_at', 'revoked_at'],
98359835
limit: 200,
98369836
context: SYSTEM_CTX,
9837-
} as any);
9837+
});
98389838
const now = Date.now();
98399839
const live = (Array.isArray(rows) ? rows : [])
98409840
.filter((sn: any) => !sn.revoked_at && (!sn.expires_at || new Date(sn.expires_at).getTime() > now))

‎scripts/query-options-erasure-baseline.json‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"packages/plugins/plugin-approvals/src/approver-org-scope.ts": 2,
4141
"packages/plugins/plugin-approvals/src/lifecycle-hooks.ts": 4,
4242
"packages/plugins/plugin-auth/src/admin-import-users.ts": 1,
43-
"packages/plugins/plugin-auth/src/auth-manager.ts": 12,
4443
"packages/plugins/plugin-sharing/src/share-link-routes.ts": 3,
4544
"packages/plugins/plugin-sharing/src/share-link-service.ts": 5,
4645
"packages/runtime/src/action-execution.ts": 1,

0 commit comments

Comments
 (0)