diff --git a/.changeset/20596-plugin-auth-provenance-anchors.md b/.changeset/20596-plugin-auth-provenance-anchors.md new file mode 100644 index 00000000000..2a5a7d2441c --- /dev/null +++ b/.changeset/20596-plugin-auth-provenance-anchors.md @@ -0,0 +1,10 @@ +--- +'@objectstack/plugin-auth': patch +--- + +Provenance comments in `plugin-auth` were re-anchored + +Comment and docblock lines under `src/` that cited tracker numbers which no +longer resolve on GitHub now cite the commit in this repository's history that +decided the matter, and say in their own words what was decided. Comments +only: no type, schema, export, log or refusal text, or runtime behaviour changes. diff --git a/packages/plugins/plugin-auth/src/account-identity-preflight.test.ts b/packages/plugins/plugin-auth/src/account-identity-preflight.test.ts index b196d6dc889..c37085455a5 100644 --- a/packages/plugins/plugin-auth/src/account-identity-preflight.test.ts +++ b/packages/plugins/plugin-auth/src/account-identity-preflight.test.ts @@ -18,7 +18,7 @@ * declaration without the constraint. That population is real and reachable: * `syncDeclaredIndexes` logs a plain UNIQUE whose CREATE fails on existing * duplicates onto the durability channel and lets the boot continue - * (#14902 / #15479), deliberately, so one dirty table cannot take a deployment + * (commit 61821e54c / #15479), deliberately, so one dirty table cannot take a deployment * down. `SYS_ACCOUNT_NO_UNIQUE` below is that deployment, spelled as a fixture * — the same shape with the unique index absent. * @@ -51,7 +51,7 @@ const SYSTEM = { context: { isSystem: true } } as never; /** * `sys_account` as a deployment whose declared `(provider_id, account_id)` - * UNIQUE was never physically created — the #14902 / #15479 population. Only + * UNIQUE was never physically created — the commit 61821e54c / #15479 population. Only * the columns the probe reads are spelled. */ const SYS_ACCOUNT_NO_UNIQUE = { diff --git a/packages/plugins/plugin-auth/src/account-identity-preflight.ts b/packages/plugins/plugin-auth/src/account-identity-preflight.ts index 52e3127d37b..4a1b8e246f7 100644 --- a/packages/plugins/plugin-auth/src/account-identity-preflight.ts +++ b/packages/plugins/plugin-auth/src/account-identity-preflight.ts @@ -31,7 +31,7 @@ import { keysetWalk } from '@objectstack/types'; * * ⚠️ "Declared" is not "present". `syncDeclaredIndexes` logs a plain UNIQUE * whose CREATE fails on existing duplicates onto the durability channel and - * lets the boot continue (#14902 / #15479) — deliberately, so one dirty table + * lets the boot continue (commit 61821e54c / #15479) — deliberately, so one dirty table * cannot take a deployment down. A database that ever held duplicates therefore * carries the declaration and not the constraint, and can still hold the class * today. diff --git a/packages/plugins/plugin-auth/src/admin-has-permission-endpoint.ts b/packages/plugins/plugin-auth/src/admin-has-permission-endpoint.ts index e45d9f9ab45..4dd07af94d3 100644 --- a/packages/plugins/plugin-auth/src/admin-has-permission-endpoint.ts +++ b/packages/plugins/plugin-auth/src/admin-has-permission-endpoint.ts @@ -26,7 +26,7 @@ * who is a platform admin under ADR-0068 (`isPlatformAdminUser`, the same * predicate every shaded `/admin/*` mount trusts) sending a body the vendor's * own handler would EVALUATE. Every other caller and every other body shape - * is DELEGATED through `AuthManager.handleRequest` — the #12029 gate-then- + * is DELEGATED through `AuthManager.handleRequest` — commit 6dd3e6968's gate-then- * delegate seam — so the vendor's native bytes stand: an anonymous caller * still gets the enveloped 401, a plain member still gets its own * `200 {"error":null,"success":false}` negative (pinned by the non-admin diff --git a/packages/plugins/plugin-auth/src/admin-remove-user-gate-ordering.test.ts b/packages/plugins/plugin-auth/src/admin-remove-user-gate-ordering.test.ts index 279f02a8890..ec83f09f556 100644 --- a/packages/plugins/plugin-auth/src/admin-remove-user-gate-ordering.test.ts +++ b/packages/plugins/plugin-auth/src/admin-remove-user-gate-ordering.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// #11477 — ORDERING PIN: on `/admin/remove-user` the break-glass guard must run +// commit 6dd3e6968 — ORDERING PIN: on `/admin/remove-user` the break-glass guard must run // AFTER authorization, and the whole `/admin/*` family must agree on that order. // // ── The defect this pins, and why a pin is half the fix ───────────────────── diff --git a/packages/plugins/plugin-auth/src/auth-email-locale.test.ts b/packages/plugins/plugin-auth/src/auth-email-locale.test.ts index 5880a0f42d7..c17b00487ba 100644 --- a/packages/plugins/plugin-auth/src/auth-email-locale.test.ts +++ b/packages/plugins/plugin-auth/src/auth-email-locale.test.ts @@ -8,7 +8,7 @@ * caller's own `Accept-Language` first (only when it names a locale in * `AUTH_EMAIL_TEMPLATE_LOCALES`), and the deployment default second. The * 2026-08-13 ruling had made the deployment default the whole answer and - * rejected `Accept-Language` outright. #14762 then added the rung ABOVE both, + * rejected `Accept-Language` outright. Commit 35e94c96b then added the rung ABOVE both, * per the #14788 option-D ruling of 2026-09-03: the recipient's own * `sys_user.locale` (#13881) when the account holds one. * @@ -479,7 +479,7 @@ describe('#14319 — authEmailLocaleFromRequest', () => { }); }); -// ── #14762 — the stored rung ─────────────────────────────────────────────── +// ── commit 35e94c96b — the stored rung ───────────────────────────────────── /** * #14788 was ruled option D on 2026-09-03 (maintainer verbatim 「同意」): diff --git a/packages/plugins/plugin-auth/src/auth-manager.test.ts b/packages/plugins/plugin-auth/src/auth-manager.test.ts index bdf68e0bd15..2187b74b567 100644 --- a/packages/plugins/plugin-auth/src/auth-manager.test.ts +++ b/packages/plugins/plugin-auth/src/auth-manager.test.ts @@ -1553,7 +1553,7 @@ describe('AuthManager', () => { }); }); - // #10366 — the localhost-wildcard trio is a DEVELOPMENT convenience and is + // commit bbe643c08 — the localhost-wildcard trio is a DEVELOPMENT convenience and is // gated on `NODE_ENV !== 'production'`. Before the gate the condition tested // only emptiness, so a production deployment whose trusted-origin list // resolved empty silently CSRF-trusted every `localhost` / `*.localhost` @@ -2530,7 +2530,7 @@ describe('AuthManager', () => { expect(sms.sent[0].body).toContain('verification code'); }); - // ── #14762 — the recipient's own `sys_user.locale` as the top rung ────── + // ── commit 35e94c96b — the recipient's own `sys_user.locale` as the top rung // // #14788 was ruled option D on 2026-09-03: `sys_user.locale` when set → // the request's `Accept-Language` → the deployment default. There is no @@ -2651,7 +2651,7 @@ describe('AuthManager', () => { // ── #14641 — the SMS INVITE path gets the same rung ────────────────── // - // Its OWN describe, sibling to #14762 above rather than nested inside it: + // Its OWN describe, sibling to commit 35e94c96b's above, not nested inside it: // the reporter path is what the next reader greps, and these pins answer // for #14641, not for the card that gave the OTP send its rung. describe("#14641 — the invitation SMS reads the invitee's own locale", () => { @@ -2858,7 +2858,7 @@ describe('AuthManager', () => { expect(data.acceptUrl).toBe('http://localhost:3000/_console/accept-invitation/tok456'); }); - // #11741 — the invitation producer HOLDS an organization (the invitation + // commit b706af987 — the invitation producer HOLDS an organization (the invitation // row's own organizationId), so it threads that exact value into // SendTemplateInput for the sys_email.organization_id stamp. Auth mail // that genuinely has no organization (password reset / verification / @@ -4086,15 +4086,15 @@ describe('AuthManager', () => { expect(written).toEqual(['hash:current', 'hash:old1']); // prepend + trim to 2 }); - // ---- #8676: the same control, against an engine that actually STRIPS ---- + // ---- commit d6e80b28b: the same control, against an engine that actually STRIPS ---- // // ⚠️ Every test above uses `makeEngine`, which hands back the stored object // untouched. That is a faithful model of a strip-less engine — and it is - // precisely why those tests carry NO information about #8676: once + // precisely why those tests carry NO information about commit d6e80b28b: once // `sys_account.password` and `previous_password_hashes` are `internal: // true`, the REAL engine omits both from this read, with no `isSystem` // carve-out and in spite of the explicit projection (#7728's design; - // measured against a real ObjectQL engine + stub driver on #8676, which + // measured against a real ObjectQL engine + stub driver for commit d6e80b28b, which // returned `{"id":"a1"}` for the exact query at `assertPasswordNotReused`). // `compareList` then empties, the loop never runs, `PASSWORD_REUSE` is // never thrown, and the method's own `catch { return undefined }` means @@ -4188,7 +4188,7 @@ describe('AuthManager', () => { }); it('⛔ the recovery is LOAD-BEARING: drop the accessor and the control provably dies', async () => { - // The falsification arm. This is the pre-#8676 shape — a stripping + // The falsification arm. This is the shape before commit d6e80b28b — a stripping // engine with no privileged accessor — and it is what every assertion // in this block would look like if the recovery were removed. Pinned so // the four tests above can never pass vacuously: if the strip stopped diff --git a/packages/plugins/plugin-auth/src/auth-manager.ts b/packages/plugins/plugin-auth/src/auth-manager.ts index 2aba10ba3a7..c0bdef025a3 100644 --- a/packages/plugins/plugin-auth/src/auth-manager.ts +++ b/packages/plugins/plugin-auth/src/auth-manager.ts @@ -127,7 +127,7 @@ import { interpolatePhoneSms, loadPhoneSmsTemplateBody, } from './phone-sms-texts.js'; -// #14762 — the stored rung of the ruled locale ladder reuses the messaging +// commit 35e94c96b — the stored rung of the ruled locale ladder reuses the messaging // seam's normalizer rather than growing a second one. `normalizeRecipientLocale` // is the platform's ONE reader of a value at rest in `sys_user.locale`, and its // refusal of the stringified-nothing literals (`"undefined"`, `"null"`) is part @@ -1691,7 +1691,7 @@ export class AuthManager { // background-task handling (see sendVerificationEmail) and the // forget-password route always returns {status:true}, so this never // leaks whether an address exists nor turns the request into a 500. - // #14762 — the ladder's stored rung. It matters most HERE: an + // commit 35e94c96b — the ladder's stored rung. It matters most HERE: an // admin-initiated reset (`admin-import-users.ts` calls // `requestPasswordReset`) reaches this callback with the ADMIN's // request, so without this rung the user's mail carries the admin's @@ -1756,7 +1756,7 @@ export class AuthManager { // template/loader errors, and returns status:'failed' on transport // errors — surface both so resend is honest and signup stays // resilient via better-auth's background-task error handling. - // #14762 — the stored rung, same ladder as the reset above. An + // commit 35e94c96b — the stored rung, same ladder as the reset above. An // admin re-triggering verification for a user is the same // requester-is-not-the-recipient shape. const storedLocale = await this.storedRecipientLocale({ id: user.id }); @@ -2164,7 +2164,7 @@ export class AuthManager { // guard itself now lives in ONE module both call sites share — // `last-local-credential.ts`, whose header records this trap. // - // ⚠️ `/admin/remove-user` IS ALSO SHADED NOW (#11477) — and it DOES + // ⚠️ `/admin/remove-user` IS ALSO SHADED NOW (commit 6dd3e6968) — and it DOES // still reach this hook, which is the opposite of the line above // and is the point. Its mount only runs `gateAdmin` and then // RE-DISPATCHES the request through `handleRequest`, so it re-enters @@ -2575,7 +2575,7 @@ export class AuthManager { // default root domain — see project-provisioning.ts) pass CSRF checks // without operators having to configure trustedOrigins manually. // - // NON-PRODUCTION ONLY (#10366). This substitution is a development + // NON-PRODUCTION ONLY (commit bbe643c08). This substitution is a development // convenience and is now gated on the same `NODE_ENV` dev signal used // by the fallback auth secret and the dev Origin synthesis below, so // the boundary this comment claims is the boundary that is enforced. @@ -3369,7 +3369,7 @@ export class AuthManager { // `routes/crud-invites.mjs`, so an existing account being invited // elsewhere reaches this callback normally). Their column is a // language they chose for themselves — the same authority the - // reset / verification sends read since #14762. + // reset / verification sends read since commit 35e94c96b. // 2. NO row — a genuinely new invitee. Their language is still truly // unknown at invitation time, so the deployment default stands, // exactly as before. @@ -3411,7 +3411,7 @@ export class AuthManager { }, relatedObject: 'sys_invitation', relatedId: invitation.id, - // #11741 — the invitation HOLDS its organization; thread it so + // commit b706af987 — the invitation HOLDS its organization; thread it so // the sys_email row is stamped. Org-less auth mail (reset / // verification / magic link) deliberately threads nothing. ...(invitation.organizationId @@ -5157,7 +5157,7 @@ export class AuthManager { } /** - * [#11640] Whether an outbound email transport is wired RIGHT NOW. + * [commit bf8d129b5] Whether an outbound email transport is wired RIGHT NOW. * * The one public read of the fact every verification link depends on: with * no transport the `sendVerificationEmail` callback has nowhere to send, so @@ -5198,7 +5198,7 @@ export class AuthManager { * entirely and `EmailService`'s ladder resolves its documented `en-US` * default exactly as before. * - * #14762 layered the per-recipient stored preference on TOP of both rungs: + * Commit 35e94c96b layered the per-recipient stored preference on TOP of both rungs: * `sys_user.locale` (#13881, ruling 2026-09-01) when the account holds one, * then this request's `Accept-Language`, then the deployment default. The * request rung did not lose its argument — it is still what answers for an @@ -5222,7 +5222,7 @@ export class AuthManager { // address that would actually land. const target = newEmail.trim().toLowerCase(); if (!target) return; - // #14762 — the stored rung on top of the #14319 ladder. The recipient is + // commit 35e94c96b — the stored rung on top of the #14319 ladder. The recipient is // the account holder, so their own column outranks the header the // request happened to carry. const storedLocale = from.id ? await this.storedRecipientLocale({ id: from.id }) : undefined; @@ -5343,7 +5343,7 @@ export class AuthManager { // one provider template covers sign-in and reset, and the SMS reveals // nothing about what the code unlocks. // - // #14762 — the recipient of an OTP IS the user, so the locale is theirs to + // commit 35e94c96b — the recipient of an OTP IS the user, so the locale is theirs to // name: `sys_user.locale` first, the deployment default underneath. // // ⚠️ The row is looked up here rather than taken from the callback: the @@ -5460,7 +5460,7 @@ export class AuthManager { * `kernel:ready` and on every settings change (same pattern as * {@link setAppName}). Unset ⇒ the built-in English text. * - * #14762 — this is now the SECOND rung, not the whole answer. The OTP send + * Commit 35e94c96b — this is now the SECOND rung, not the whole answer. The OTP send * reads the recipient's own `sys_user.locale` first (#13881, ruling * 2026-09-01, the same column the messaging channels resolve per recipient) * and falls here when the account holds none. #14641 gave the SMS INVITE @@ -5513,7 +5513,7 @@ export class AuthManager { * * Per-user locale EXISTS since #13881 (maintainer ruling 2026-09-01): * `sys_user.locale`, resolved per recipient by service-messaging for - * notification mail (`recipient-locale.ts`). #14762 layered it on top of + * notification mail (`recipient-locale.ts`). Commit 35e94c96b layered it on top of * this ladder for the sends that hold a recipient row — reset, verification * and the change-email notice — so the order is stored → request → this * rung, per the #14788 option-D ruling of 2026-09-03. Nothing here changed: @@ -5530,7 +5530,7 @@ export class AuthManager { private emailLocale?: string; /** - * #14762 — the ladder's TOP rung: the recipient's own `sys_user.locale`, + * Commit 35e94c96b — the ladder's TOP rung: the recipient's own `sys_user.locale`, * read best-effort off the identity row. * * Returns `undefined` for every shape that cannot name a language — no data @@ -5545,7 +5545,7 @@ export class AuthManager { * The read is one row on an indexed predicate, projected to the single * column, under a system context — the recipient's own language must resolve * regardless of who triggered the send, which is exactly the - * admin-initiated case #14762 was about, and the INVITER-triggered case + * admin-initiated case commit 35e94c96b fixed, and the INVITER-triggered case * #14641 added. Three predicates, one per caller shape: `sys_user.id` (the * sends that hold a user row), the unique `phone_number` (the SMS sends, * which are handed a number and nothing else), and the unique `email` (the @@ -5580,7 +5580,7 @@ export class AuthManager { * what the ladder's "no locale means the DOCUMENTED default" contract is * written against. * - * #14762 — three rungs now, in the order ruled for #14788 on 2026-09-03 + * Commit 35e94c96b — three rungs now, in the order ruled for #14788 on 2026-09-03 * (option D): the recipient's own **stored** `sys_user.locale` → the * **request**'s `Accept-Language` (#14319) → the **deployment** default * (#8195). The recorded reasoning is that a value the user chose is stronger @@ -5615,7 +5615,7 @@ export class AuthManager { * one exists, else the built-in bilingual text. Template lookups are * best-effort — an outage must never block an OTP send. * - * #14762 — `storedLocale` is the recipient's own `sys_user.locale` when the + * Commit 35e94c96b — `storedLocale` is the recipient's own `sys_user.locale` when the * caller could resolve one ({@link storedRecipientLocale}); the deployment * default stands underneath it. There is NO request rung on this surface: * the ruled ladder's middle rung is the request's `Accept-Language`, and an @@ -5626,7 +5626,7 @@ export class AuthManager { * row as {@link phoneSmsLocaleChain}'s terminal floor exactly as before. * * A caller that passes nothing — or one whose recipient resolves no row — - * gets exactly the pre-#14762 deployment-default behaviour. #14641 made the + * gets exactly the deployment default, as before commit 35e94c96b. #14641 made the * SMS invite path a passer rather than an abstainer; it is no longer the * standing example of a caller that names nothing. */ @@ -7551,10 +7551,10 @@ export class AuthManager { * (this file, ~line 671) declares `{ info?; warn }` and NO `error`, and it is * re-exported from the package `index.ts`, so adding `error?` is a * published-shape change. #12981's ruling routes that LEVEL question to - * #13398 and tells this batch to fix the SILENCE only — the same split - * batches 1 and 2 landed for `plugin-security`'s two exported sinks. `warn` - * is the guaranteed channel here and the lowest level a reader still reads as - * a failure, so nothing is lost but loudness. + * the published-sink ruling (commit e238c79f0) and tells this batch to fix the + * SILENCE only — the same split batches 1 and 2 landed for `plugin-security`'s + * two exported sinks. `warn` is the guaranteed channel here and the lowest + * level a reader still reads as a failure, so nothing is lost but loudness. * * ⛔ Call `warn` through the PROPERTY, never through an extracted reference — * `@objectstack/core`'s `ObjectLogger` is class-based and its `warn` reaches @@ -8023,7 +8023,7 @@ export class AuthManager { fields: ['id', 'password', 'previous_password_hashes'], context: SYSTEM_CTX, } as any); - // [#8676] Both columns are `internal: true`, so the engine's read path + // [commit d6e80b28b] Both columns are `internal: true`, so the engine's read path // omits them from the row above — with no `isSystem` carve-out and in // spite of the explicit projection (#7728's design). Recover them // through the privileged accessor, or `compareList` below is empty and @@ -8071,7 +8071,7 @@ export class AuthManager { context: SYSTEM_CTX, } as any); if (!account?.id) return; - // [#8676] As above — the flagged column is omitted from the read, so + // [commit d6e80b28b] As above — the flagged column is omitted from the read, so // recover it before extending the ring. Without this the ring is rebuilt // from an empty history on every change and never grows past one entry. await recoverInternalFieldsForSystemRead( diff --git a/packages/plugins/plugin-auth/src/auth-plugin-walled-owner-verification-path.test.ts b/packages/plugins/plugin-auth/src/auth-plugin-walled-owner-verification-path.test.ts index 92516b59f46..cdc3e2b7051 100644 --- a/packages/plugins/plugin-auth/src/auth-plugin-walled-owner-verification-path.test.ts +++ b/packages/plugins/plugin-auth/src/auth-plugin-walled-owner-verification-path.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#11640] The boot-time warning for a walled deployment that declares a + * [commit bf8d129b5] The boot-time warning for a walled deployment that declares a * platform owner it can never verify — maintainer ruling 2026-08-25 (option * A, verbatim 「全部同意」). * @@ -229,7 +229,7 @@ describe('#11640 — controls: every neighbouring shape stays SILENT', () => { it('a dev/harness boot that seeds THIS owner verifies it at startup ⇒ no warning', () => { // The dev-admin seed provisions the declared owner and stamps it - // `email_verified` (#11343), which is a verification path even with no + // `email_verified` (commit c0714eb5d), which is a verification path even with no // mailbox anywhere — the verify harness boots exactly this shape. The // seed acts on an empty store, and the harness boots that cannot probe // one hand in 'unknown' — both stay silent. diff --git a/packages/plugins/plugin-auth/src/auth-plugin.test.ts b/packages/plugins/plugin-auth/src/auth-plugin.test.ts index 8ff8861281e..f941b6d845e 100644 --- a/packages/plugins/plugin-auth/src/auth-plugin.test.ts +++ b/packages/plugins/plugin-auth/src/auth-plugin.test.ts @@ -1391,7 +1391,7 @@ describe('AuthPlugin', () => { expect(ql.insert).not.toHaveBeenCalled(); }); - // [#11973 / #11663 L3] The trigger set widened to the #11343 `sys_user` + // [#11973 / #11663 L3] The trigger set widened to commit c0714eb5d's `sys_user` // arms: a config-anchored administrator comes into standing through a // `sys_user` insert (operator-provisioned, arrives verified) or a // verifying/email update — with no grant insert ever firing post-L4. diff --git a/packages/plugins/plugin-auth/src/auth-plugin.ts b/packages/plugins/plugin-auth/src/auth-plugin.ts index 45e547d5392..47baa218ef2 100644 --- a/packages/plugins/plugin-auth/src/auth-plugin.ts +++ b/packages/plugins/plugin-auth/src/auth-plugin.ts @@ -1003,7 +1003,7 @@ export class AuthPlugin implements Plugin { }); } - // [#11640] The walled deployment that declares an owner it can never + // [commit bf8d129b5] The walled deployment that declares an owner it can never // verify — maintainer ruling 2026-08-25 (option A): warn loudly, by name, // at boot; NEVER refuse. The whole decision (and why it must run here // rather than in `init()`, where no email transport is resolvable yet) @@ -1134,7 +1134,7 @@ export class AuthPlugin implements Plugin { ctx.hook('kernel:ready', runEnsure); // [#11973 / #11663 L3] Re-run after every write that can move the // population answer, judged by the ONE exported trigger predicate: a - // `sys_user` insert or email/email_verified update (the #11343 trigger + // `sys_user` insert or email/email_verified update (commit c0714eb5d's trigger // set — how a CONFIG-anchored admin comes into standing), and the // legacy `sys_user_permission_set` insert (how `single`-posture // first-user promotion lands standing, Choice 4A — retired with the @@ -1932,10 +1932,10 @@ export class AuthPlugin implements Plugin { * OS_SEED_ADMIN=0 (or false/off/no). */ private async maybeSeedDevAdmin(ctx: PluginContext): Promise { - // [#11640] Both clauses (and the seeded address below) are resolved by + // [commit bf8d129b5] Both clauses (and the seeded address below) are resolved by // `walled-owner-verification-path.ts`, because the boot check there treats // this seed as a verification path — it stamps the seeded account - // `email_verified` (#11343). That is only true while the two agree on when + // `email_verified` (commit c0714eb5d). That is only true while the two agree on when // the seed is armed and which address it provisions, so they read one // resolution rather than two copies of the same env parsing. if (!isDevAdminSeedArmed()) return; @@ -2028,7 +2028,7 @@ export class AuthPlugin implements Plugin { } finally { this.authManager.clearOperatorProvisioning(email); } - // [#11343] Stamp the seeded admin's address VERIFIED. This account is + // [commit c0714eb5d] Stamp the seeded admin's address VERIFIED. This account is // provisioned by the deployment's own boot command with operator-known // credentials — it is not an unknown self-registrant, which is the class // the verified-elevation invariant exists to refuse. Under walled @@ -2109,7 +2109,7 @@ export class AuthPlugin implements Plugin { { context: { isSystem: true } }, ) .catch(() => []); - // [#8676] `sys_account.password` is `internal: true`, so the row above + // [commit d6e80b28b] `sys_account.password` is `internal: true`, so the row above // arrives without it — the engine's strip has no `isSystem` carve-out. // Recover it through the privileged accessor; otherwise this probe reads // `undefined` on every boot and the dev credential hint silently stops @@ -2633,7 +2633,7 @@ export class AuthPlugin implements Plugin { } }); - // ── #11477: /admin/remove-user — AUTHORIZATION BEFORE THE GUARD ────── + // ── commit 6dd3e6968: /admin/remove-user — AUTHORIZATION BEFORE THE GUARD ── // // The break-glass last-local-credential guard is a global // `hooks.before` in auth-manager.ts keyed on `ctx.path`. A better-auth @@ -2735,8 +2735,8 @@ export class AuthPlugin implements Plugin { // // Ledger: `POST /api/v1/auth/admin/has-permission` stays a // `BETTER_AUTH_MOUNTED_SURFACE` row; `check:auth-mount-ledger` accounts - // for this mount as "shadowing a vendor-declared path" (the #12029 - // worked reading — a shadow is accounted for, not a new row). + // for this mount as "shadowing a vendor-declared path" (as it read commit + // 6dd3e6968's remove-user mount — a shadow is accounted for, not a new row). // // Pinned by `admin-has-permission-endpoint.test.ts` (both directions, // full table) and the two dogfood sweeps (admin standing + non-admin diff --git a/packages/plugins/plugin-auth/src/better-auth-schema-parity.test.ts b/packages/plugins/plugin-auth/src/better-auth-schema-parity.test.ts index 931ce643984..9f4b4f4dd51 100644 --- a/packages/plugins/plugin-auth/src/better-auth-schema-parity.test.ts +++ b/packages/plugins/plugin-auth/src/better-auth-schema-parity.test.ts @@ -151,7 +151,7 @@ const PLATFORM_OBJECTS: Record = Object.fromEntries( SysTwoFactor, SysDeviceCode, SysJwks, // Bridged at the adapter layer rather than via a plugin `schema` option — // see the sso/scim block at the bottom of this file (#3653). (The rc.1-era - // `SysScimProvider` backed no stable model; it retired under #11757.) + // `SysScimProvider` backed no stable model; it retired under commit 4d25d22d4.) SysSsoProvider, SysScimConnectionBinding, SysScimGroup, SysScimGroupMember, SysScimIdentityTombstone, SysScimProjectionGrant, SysScimSubject, diff --git a/packages/plugins/plugin-auth/src/boot-sign-in-reachability.test.ts b/packages/plugins/plugin-auth/src/boot-sign-in-reachability.test.ts index c423ff9bf4a..0d50e092281 100644 --- a/packages/plugins/plugin-auth/src/boot-sign-in-reachability.test.ts +++ b/packages/plugins/plugin-auth/src/boot-sign-in-reachability.test.ts @@ -15,7 +15,7 @@ * one does, so each neighbouring shape is pinned SILENT: an account exists, no * humans exist, and either fact unanswerable. * - * The other load-bearing half is INDEPENDENCE. The neighbouring [#11640] + * The other load-bearing half is INDEPENDENCE. The neighbouring [commit bf8d129b5] * walled-owner reporter only runs when all four of {no email transport, no * federated sign-in, walled tenancy posture, declared platform owner} hold. * This report shares that hook but none of those preconditions, and the @@ -592,7 +592,7 @@ describe('#14353 — the emitter logs ONCE, at `error`, and survives a broken si }); it('a sink that declares only `warn` still HEARS this — the fallback is explicit', () => { - // The #13398-class ruling forbids growing `error?` onto a published sink + // The sink ruling (commit e238c79f0) forbids growing `error?` onto a published sink // that lacks it. A bare `error?.(…)` against such a sink emits NOTHING, // which would make this report silent on exactly the hosts that publish // the narrower shape; the explicit branch is what stops that. diff --git a/packages/plugins/plugin-auth/src/boot-sign-in-reachability.ts b/packages/plugins/plugin-auth/src/boot-sign-in-reachability.ts index b0be40fade9..cfd837372f2 100644 --- a/packages/plugins/plugin-auth/src/boot-sign-in-reachability.ts +++ b/packages/plugins/plugin-auth/src/boot-sign-in-reachability.ts @@ -106,7 +106,7 @@ * line — ① the consequence, concretely, including that the system will keep * looking healthy, and ② the fix — and the message carries both. * - * The #13398-class ruling caps this, and is satisfied rather than dodged: + * The sink ruling (commit e238c79f0) caps this, and is satisfied rather than dodged: * what it forbids is GROWING `error?` onto a published sink that lacks it. * {@link BootDiagnosticLogger} declares `error?` AND a required `warn` from * birth and nothing is widened — in particular the neighbouring @@ -117,7 +117,7 @@ * * ## Why `kernel:ready`, and why it shares the neighbour's hook * - * Same hook site as the [#11640] walled-owner verification-path reporter, and + * Same hook site as the [commit bf8d129b5] walled-owner verification-path reporter, and * for a stronger reason than symmetry: both questions are answered from ONE * bounded human-population page read, performed here * ({@link probeHumanUsersPresence}) and handed to @@ -509,7 +509,7 @@ export function resolveNoSignInAccountReport( /** * The `error` channel this report needs, with the `warn` fallback the - * #13398-class ruling requires of a sink that may not declare `error`. + * published-sink ruling (commit e238c79f0) requires of a sink that may not declare `error`. * * `warn` is REQUIRED and `error` is optional, which is the #9754 shape * (`check:optional-error-sink`): the fallback channel a durability report diff --git a/packages/plugins/plugin-auth/src/dev-admin-seed-credential-gate.test.ts b/packages/plugins/plugin-auth/src/dev-admin-seed-credential-gate.test.ts index 22c75968c77..c7e60fd30e2 100644 --- a/packages/plugins/plugin-auth/src/dev-admin-seed-credential-gate.test.ts +++ b/packages/plugins/plugin-auth/src/dev-admin-seed-credential-gate.test.ts @@ -188,7 +188,7 @@ async function readRows(engine: ObjectQL, object: string): Promise const seeded = users.find((u) => String(u.email).toLowerCase() === SEED_EMAIL); expect(seeded, 'the seed address must exist as a user').toBeTruthy(); expect(accounts[0].user_id).toBe(seeded!.id); - // …and the row the account belongs to is stamped verified (#11343). + // …and the row the account belongs to is stamped verified (commit c0714eb5d). expect(seeded!.email_verified).toBeTruthy(); // The banner the CLI prints reads this. expect(manager.devSeedResult).toEqual({ email: SEED_EMAIL, password: SEED_PASSWORD }); @@ -511,7 +511,7 @@ describe('[#14157] the dev-admin seed gates on a LOGIN, not on user rows', () => // IS admitted — the fix narrows admission to the ticket holder, it // does not also break the seed's own path. This calls `signUpEmail` // directly (as `maybeSeedDevAdmin` does), not the seed's OWN separate - // post-creation `email_verified` write (#11343, a step in + // post-creation `email_verified` write (commit c0714eb5d, a step in // `auth-plugin.ts` outside the admission gate this card touches), so // admission is what this proves — creation, and that the credential // actually authenticates. diff --git a/packages/plugins/plugin-auth/src/durability-swallow-repair.test.ts b/packages/plugins/plugin-auth/src/durability-swallow-repair.test.ts index 3cc3a493a46..6908d41c9e6 100644 --- a/packages/plugins/plugin-auth/src/durability-swallow-repair.test.ts +++ b/packages/plugins/plugin-auth/src/durability-swallow-repair.test.ts @@ -33,11 +33,11 @@ * `warn` for the `AuthManager` seams and `error` for the two `AuthPlugin` * seams, and the split is deliberate: `AuthManagerOptions.logger` is re-exported * from the package `index.ts` and declares no `error`, so #12981's ruling routes - * that LEVEL question to #13398 and leaves the SILENCE here. `AuthPlugin` logs - * through the kernel `Logger`, whose `error` is required, so those two get the - * level AGENTS.md → "Degradation log levels" actually calls for. The assertions - * below pin each site to the channel it ships on, so a later level change is a - * deliberate edit here rather than a silent drift. + * that LEVEL question to the published-sink ruling (commit e238c79f0) and leaves + * the SILENCE here. `AuthPlugin` logs through the kernel `Logger`, whose `error` + * is required, so those two get the level AGENTS.md → "Degradation log levels" + * actually calls for. The assertions below pin each site to the channel it ships + * on, so a later level change is a deliberate edit here rather than a silent drift. */ import { describe, it, expect, vi, beforeEach } from 'vitest'; @@ -45,7 +45,7 @@ import { assertEngineFindOnePredicate, assertEngineUpdateDispatch } from '@objec import { AuthManager } from './auth-manager'; import { AuthPlugin } from './auth-plugin'; import type { PluginContext } from '@objectstack/core'; -// [#14998] The two admin endpoint module graphs are loaded HERE, at module top, +// [commit f1e91595f] The two admin endpoint module graphs are loaded HERE, at module top, // and NOT with an `await import(...)` inside each case — which is how batch 6's // seven cases used to reach them. // @@ -59,7 +59,7 @@ import type { PluginContext } from '@objectstack/core'; // `admin-import-users.ts` pulls in `@objectstack/rest` (`prepareImportRequest`, // `runImport`) — so under a loaded CI shard the first sibling's cold load ate // the 10 s and the case failed with `Test timed out in 10000ms`, reddening PRs -// that touch nothing this file reads (#14998, #15603). +// that touch nothing this file reads (the flake commit f1e91595f fixed, #15603). // // Loading at module top is not a widened budget, it removes the clock: vitest's // `collectTests()` awaits `runner.importFile(filepath, 'collect')` bare and only @@ -524,9 +524,9 @@ describe('#12981 batch 5 — plugin-auth durability swallows report instead of v * `export * from './admin-user-endpoints.js'` and `export *` for * `./admin-import-users.js`). Neither declares `error`, so raising the level * means widening a published sink — refused as actively harmful by the - * maintainer's #13398 ruling, which routes that question there and leaves the - * SILENCE here. The assertions below pin the channel, so a later level change - * is a deliberate edit rather than a drift. + * maintainer's published-sink ruling (commit e238c79f0), which keeps that question + * and leaves the SILENCE here. The assertions below pin the channel, so a later + * level change is a deliberate edit rather than a drift. */ describe('#12981 batch 6 — the plugin-auth admin-audit swallows report instead of vanishing', () => { const AUDIT_REFUSAL = new Error('write refused: no permission on sys_audit_log'); diff --git a/packages/plugins/plugin-auth/src/ensure-default-organization.ts b/packages/plugins/plugin-auth/src/ensure-default-organization.ts index a17950806fd..affaa356c02 100644 --- a/packages/plugins/plugin-auth/src/ensure-default-organization.ts +++ b/packages/plugins/plugin-auth/src/ensure-default-organization.ts @@ -197,7 +197,7 @@ function oldestFirst(a: any, b: any): number { * operator-provisioned account (`walled-owner-operator-stamp.ts`) or a * trusted-IdP insert arrives ALREADY VERIFIED, so the row that confers * standing can exist the moment it is created. - * - **`sys_user` update touching `email` / `email_verified`** — the #11343 + * - **`sys_user` update touching `email` / `email_verified`** — commit c0714eb5d's * trigger set (design §2 step 5): the declared owner's verifying update is * exactly the moment `matchesConfiguredPlatformAdmin` starts answering * `true`, and on a fresh walled rig it is the ONLY write that ever will — diff --git a/packages/plugins/plugin-auth/src/find-envelope-limb-removal.test.ts b/packages/plugins/plugin-auth/src/find-envelope-limb-removal.test.ts index fcba18dd43a..2046e674412 100644 --- a/packages/plugins/plugin-auth/src/find-envelope-limb-removal.test.ts +++ b/packages/plugins/plugin-auth/src/find-envelope-limb-removal.test.ts @@ -44,8 +44,8 @@ * * ## The fifteenth case is a different defect * - * `settleSelfRegistrationGrant` also carried #15092's DROP shape, and it is - * fixed in the OPPOSITE direction — see the `describe` at the end of the file. + * `settleSelfRegistrationGrant` also carried the silent-DROP shape, and commit + * 9e9f03abe fixed it in the OPPOSITE direction — see the last `describe` in the file. */ import { describe, it, expect, afterEach } from 'vitest'; @@ -446,7 +446,7 @@ describe('#15597 — the blocks driven through their real production entry point }); /** - * ## The fifteenth block: #15092's DROP shape, fixed in the OPPOSITE direction + * ## The fifteenth block: the silent-DROP shape, fixed the OPPOSITE way (commit 9e9f03abe) * * `settleSelfRegistrationGrant` filtered its permission-set candidates with * `r?.active !== false && typeof r?.id === 'string' && r.id`. The first clause diff --git a/packages/plugins/plugin-auth/src/internal-field-readback.test.ts b/packages/plugins/plugin-auth/src/internal-field-readback.test.ts index 82be0a9fa0d..7855b599b66 100644 --- a/packages/plugins/plugin-auth/src/internal-field-readback.test.ts +++ b/packages/plugins/plugin-auth/src/internal-field-readback.test.ts @@ -1,6 +1,6 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // -// #7823 + #7987 + #8676 — the internal-field READBACK seams, unit-pinned from +// #7823 + #7987 + commit d6e80b28b — the internal-field READBACK seams, unit-pinned from // both directions. // // The engine's `internal: true` read strip removes the flagged column from @@ -23,7 +23,7 @@ // silent no-op and an OAuth refresh into a 400, so it must never pass // quietly. // -// [#8676] The module now owns TWO seams and this file pins both. The adapter +// [commit d6e80b28b] The module now owns TWO seams and this file pins both. The adapter // seam above is reachable only from `objectql-adapter.ts`; plugin-auth's own // raw-engine readers (the ADR-0069 D1 password-reuse ring, the dev seed-admin // probe) bypass it entirely and are recovered by @@ -153,7 +153,7 @@ describe('#7987 reattachInternalFieldsOnRead — sys_account OAuth columns', () expect(rows[0].refresh_token).toBe('rt-1'); expect(rows[0].id_token).toBe('it-1'); expect(rows[1].refresh_token).toBe('rt-2'); - // FOUR columns (#8676 added `password`), two rows ⇒ FOUR reads, not eight. + // FOUR columns (commit d6e80b28b added `password`), two rows ⇒ FOUR reads, not eight. // The accessor resolves one field per call by contract (#8118); the // batching that matters is per-page. expect(resolveInternalField).toHaveBeenCalledTimes(4); @@ -219,7 +219,7 @@ describe('#7987 reattachInternalFieldsOnRead — sys_account OAuth columns', () it('[#8676] re-attaches `password` — better-auth\'s sign-in verifier reads it off the row', async () => { // `internalAdapter.findCredentialAccount(userId)` returns the row whose // `password` the verifier compares the submitted one against. Under the - // #8676 flag that row arrives stripped, so without this entry password + // commit d6e80b28b flag, that row arrives stripped, so without this entry password // sign-in fails for every user. const resolveInternalField = resolver({ a1: { password: 'argon2:stored' } }); const row: any = ACCOUNT_ROW(); @@ -229,7 +229,7 @@ describe('#7987 reattachInternalFieldsOnRead — sys_account OAuth columns', () it('⛔ [#8676] never re-attaches `previous_password_hashes` — better-auth has ZERO readers', async () => { // The bound on the table, and the half of the old scope guard that - // SURVIVES #8676. The reuse ring is an ObjectStack-only column read solely + // SURVIVES commit d6e80b28b. The reuse ring is an ObjectStack-only column read solely // by `auth-manager.ts` off the RAW engine, which never passes through this // adapter seam — so a row here would be dead code, and re-attaching it // would hand better-auth a credential column nothing asked for. Pinned so a diff --git a/packages/plugins/plugin-auth/src/internal-field-readback.ts b/packages/plugins/plugin-auth/src/internal-field-readback.ts index 05fea5f9fc5..d25556376fb 100644 --- a/packages/plugins/plugin-auth/src/internal-field-readback.ts +++ b/packages/plugins/plugin-auth/src/internal-field-readback.ts @@ -52,12 +52,12 @@ * empty string. That is the risk #7987 was parked on, and the reason the * mechanism is a readback rather than a bare flag. * - * **`sys_account.password`** (#8676) — the credential hash. better-auth's + * **`sys_account.password`** (commit d6e80b28b) — the credential hash. better-auth's * sign-in verifier reads it off an adapter result row * (`internalAdapter.findCredentialAccount(userId)`), so it belongs to this * seam for the same reason the OAuth columns do. * - * ## TWO seams, not one — this module owns both (#8676) + * ## TWO seams, not one — this module owns both (commit d6e80b28b) * * The table above serves better-auth's storage adapter, which is the only * importer of {@link reattachInternalFieldsOnRead}. plugin-auth also has @@ -162,12 +162,12 @@ interface ReadbackColumn { */ const READBACK_FIELDS: Readonly> = { [SystemObjectName.SESSION]: [{ field: 'token', absenceProvesStrip: true }], - // [#7987] All three OAuth credential columns, plus [#8676] `password`. + // [#7987] All three OAuth credential columns, plus [commit d6e80b28b] `password`. // // `password` is here because better-auth's sign-in verifier reads it OFF an // adapter result row: `internalAdapter.findCredentialAccount(userId)` returns // the row whose `password` is then compared against the submitted one. Under - // the #8676 flag that row comes back without the column, so without this row + // the commit d6e80b28b flag that row comes back without the column, so without this row // password sign-in would fail for every user. `absenceProvesStrip: false` // because `sys_account.password` is `required: false` and genuinely empty on // OAuth-only accounts — see the field's own doc above for why that @@ -228,7 +228,7 @@ export async function reattachInternalFieldsOnRead( } /** - * [#8676] Recover flagged columns for one of plugin-auth's OWN raw-engine + * [commit d6e80b28b] Recover flagged columns for one of plugin-auth's OWN raw-engine * reads — the second seam, and the reason a bare flag was not enough. * * ## Why this exists beside {@link reattachInternalFieldsOnRead} diff --git a/packages/plugins/plugin-auth/src/last-admin-guard.ts b/packages/plugins/plugin-auth/src/last-admin-guard.ts index 9edd5ceda38..f288319664b 100644 --- a/packages/plugins/plugin-auth/src/last-admin-guard.ts +++ b/packages/plugins/plugin-auth/src/last-admin-guard.ts @@ -739,7 +739,7 @@ export const PERMISSION_SET_STANDING_KEYS = ['name', 'active'] as const; export const USER_STANDING_KEYS = ['email', 'email_verified'] as const; /** - * [#8734] The three lists above, keyed by the table each one judges — the shape + * [commit f8eb73601] The three lists above, keyed by the table each one judges — the shape * the correspondence gate consumes. * * The gate (`last-admin-standing-keys.test.ts`) reads @@ -763,7 +763,7 @@ export const STANDING_KEYS_BY_TABLE: Readonly> }; /** - * [#8734] Columns the resolver reads that this guard deliberately does NOT + * [commit f8eb73601] Columns the resolver reads that this guard deliberately does NOT * treat as standing-bearing, each with the reason it cannot empty the * administrator population. * diff --git a/packages/plugins/plugin-auth/src/last-admin-standing-keys.test.ts b/packages/plugins/plugin-auth/src/last-admin-standing-keys.test.ts index 6083e653a4f..34664d8bc21 100644 --- a/packages/plugins/plugin-auth/src/last-admin-standing-keys.test.ts +++ b/packages/plugins/plugin-auth/src/last-admin-standing-keys.test.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#8734] The SECOND of the two links that bind this guard's standing-key lists + * [commit f8eb73601] The SECOND of the two links that bind this guard's standing-key lists * to what the authorization resolver actually reads. * * Link 1 lives in `@objectstack/core` diff --git a/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts b/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts index dbd83a9cee0..85e99a18fe2 100644 --- a/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts +++ b/packages/plugins/plugin-auth/src/managed-extension-fields.test.ts @@ -235,7 +235,7 @@ const UNMAPPED_MANAGED_OBJECTS: Record = { + 'better-auth-schema-parity.test.ts.', }, // (The rc.1-era `sys_scim_provider` exemption retired with its object under - // #11757 — the stale-entry assertion below is what forced it out.) + // commit 4d25d22d4 — the stale-entry assertion below is what forced it out.) // The stable @better-auth/scim 1.7.x model set (#3653). Same bridge shape as // sys_sso_provider: SCIMOptions still accepts no `schema`/`modelName`/`fields` // option on the installed 1.7.1 (re-measured 2026-08-27), so getAuthTables() diff --git a/packages/plugins/plugin-auth/src/manifest.ts b/packages/plugins/plugin-auth/src/manifest.ts index 626f093657e..dcb1408eec1 100644 --- a/packages/plugins/plugin-auth/src/manifest.ts +++ b/packages/plugins/plugin-auth/src/manifest.ts @@ -72,7 +72,7 @@ export const authIdentityObjects: any[] = [ // Stable @better-auth/scim 1.7.x model set (#3653): seven library-managed // tables plus the ObjectStack-owned credential store for the app-owned // verifyBearerToken route. The rc.1-era SysScimProvider retired under - // #11757. + // commit 4d25d22d4. SysScimConnectionBinding, SysScimConnectionCredential, SysScimGroup, diff --git a/packages/plugins/plugin-auth/src/member-role-canonical.test.ts b/packages/plugins/plugin-auth/src/member-role-canonical.test.ts index b784e366e9d..5b907d05ddd 100644 --- a/packages/plugins/plugin-auth/src/member-role-canonical.test.ts +++ b/packages/plugins/plugin-auth/src/member-role-canonical.test.ts @@ -396,7 +396,7 @@ type MemoryEngineHandles = { * green suite into no suite at all on exactly the write this pass performs. * * It DECLARES `IDataEngine` so `check:engine-double-contract` can see that pin - * and ratchet it (#11626's declaration route). The double spells one engine + * and ratchet it (commit a6eca9223's declaration route). The double spells one engine * sibling (`find`), which is below the inference threshold, so before the * declaration the `assertEngineUpdateDispatch` call above was real protection * that no ledger row named — drop it tomorrow and nothing reddens. The diff --git a/packages/plugins/plugin-auth/src/objectql-adapter.ts b/packages/plugins/plugin-auth/src/objectql-adapter.ts index 36ddc338d1a..7e7ae46afc9 100644 --- a/packages/plugins/plugin-auth/src/objectql-adapter.ts +++ b/packages/plugins/plugin-auth/src/objectql-adapter.ts @@ -59,7 +59,7 @@ export const AUTH_MODEL_TO_PROTOCOL: Record = { // (OS_SSO_ENABLED / OS_SCIM_ENABLED). See ADR-0135 D6 / ADR-0134. ssoProvider: 'sys_sso_provider', // (rc.1's one scim model, `scimProvider` → `sys_scim_provider`, retired - // under #11757: stable 1.7.x no longer derives that model.) + // under commit 4d25d22d4: stable 1.7.x no longer derives that model.) // The stable @better-auth/scim 1.7.x model set (#3653). Verified against the // installed 1.7.1: `SCIMOptions` still declares no `schema` / `modelName` / // `fields` member, so the adapter bridge remains scim's ONLY naming route. diff --git a/packages/plugins/plugin-auth/src/phone-sms-texts.ts b/packages/plugins/plugin-auth/src/phone-sms-texts.ts index 084a06f5847..42a2818cabc 100644 --- a/packages/plugins/plugin-auth/src/phone-sms-texts.ts +++ b/packages/plugins/plugin-auth/src/phone-sms-texts.ts @@ -14,7 +14,7 @@ * no template row resolves (fresh env, missing table, exotic locale). * * The recipient locale reaching this module is resolved by the caller - * (`AuthManager.renderPhoneSmsBody`), and #14762 gave the OTP send a rung + * (`AuthManager.renderPhoneSmsBody`), and commit 35e94c96b gave the OTP send a rung * above the deployment default: the recipient's own `sys_user.locale` * (#13881, ruling 2026-09-01 — the same column the messaging channels read * per recipient), then the DEPLOYMENT default (`localization.locale` diff --git a/packages/plugins/plugin-auth/src/sys-session-ttl-sweep.test.ts b/packages/plugins/plugin-auth/src/sys-session-ttl-sweep.test.ts index a43e036e1ac..4ff09cc5cf2 100644 --- a/packages/plugins/plugin-auth/src/sys-session-ttl-sweep.test.ts +++ b/packages/plugins/plugin-auth/src/sys-session-ttl-sweep.test.ts @@ -227,7 +227,7 @@ describe('[#7826] sys_session TTL sweep — real declaration, real Reaper, live }); it('ABLATION — without `onlyWhen` the same sweep reaps the tombstone too', async () => { - // The declaration minus its filter: the naive policy #10165 existed to + // The declaration minus its filter: the naive policy commit 801296050 existed to // make avoidable. This is the case the sparing control has to discriminate // against, so the control is not vacuous. const { driver, service } = await seeded({ diff --git a/packages/plugins/plugin-auth/src/tenancy-service.ts b/packages/plugins/plugin-auth/src/tenancy-service.ts index 9db367209c2..a74fb7a84dd 100644 --- a/packages/plugins/plugin-auth/src/tenancy-service.ts +++ b/packages/plugins/plugin-auth/src/tenancy-service.ts @@ -246,7 +246,7 @@ const SINGLE_POSTURE_MANY_ORGANIZATIONS = 'single_posture_holds_many_organizatio /** * The `error` channel this census needs, with the `warn` fallback the - * #13398-class ruling requires of a sink that may not declare `error`. + * published-sink ruling (commit e238c79f0) requires of a sink that may not declare `error`. * * Declared HERE, at birth, with `error?` beside a REQUIRED `warn` — the #9754 * shape `check:optional-error-sink-contract` is satisfied by. Field shapes are @@ -254,8 +254,8 @@ const SINGLE_POSTURE_MANY_ORGANIZATIONS = 'single_posture_holds_many_organizatio * host sink that satisfies one satisfies the other. * * ⛔ {@link TenancyServiceDeps.logger} is NOT widened to carry this. Growing - * `error?` onto a published sink that lacks it is exactly what the #13398-class - * ruling forbids, and that sink's `warn` is OPTIONAL — widening it in place + * `error?` onto a published sink that lacks it is exactly what the sink ruling + * (commit e238c79f0) forbids, and that sink's `warn` is OPTIONAL — widening it in place * would mint the "an optional `error` with no declared alternative" shape the * gate above exists to refuse. {@link asTenancyBootDiagnosticSink} narrows the * declared sink to this one at RUNTIME instead, proving the required member diff --git a/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.test.ts b/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.test.ts index 03e1255ff3b..8c8d64fc622 100644 --- a/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.test.ts +++ b/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.test.ts @@ -20,7 +20,7 @@ * engine (the `audience-bootstrap-seam` harness shape): the declared * owner's operator-provisioned row is BORN `email_verified`, and every * "never" cell of the matrix stays unverified through the same pipeline. - * The verified read-back uses the shared [#11343] allow-list + * The verified read-back uses the shared [commit c0714eb5d] allow-list * (`isEmailVerifiedUserRow`) — the predicate the derivation itself * refuses on — so a green here IS "`resolve-authz-context.ts` §6b-config * would resolve PLATFORM_ADMIN for this row", without booting @@ -450,7 +450,7 @@ describe('#12751 — the stamp lands through the REAL creation pipeline', () => it('…and the seed’s own server-side lane (api.signUpEmail) lands the same way — the walled dev boot keeps working', async () => { // The dev-admin seed calls `api.signUpEmail` in-process and then applies - // its own #11343 stamp. With #12751 the row is already BORN verified on a + // its own commit c0714eb5d stamp. With #12751 the row is already BORN verified on a // walled boot (this lane), so the seed's later update is an idempotent // no-op — same terminal state, no behaviour change. process.env.NODE_ENV = 'development'; diff --git a/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.ts b/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.ts index de2ea501c44..3eaf5905630 100644 --- a/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.ts +++ b/packages/plugins/plugin-auth/src/walled-owner-operator-stamp.ts @@ -11,7 +11,7 @@ * stamped email-verified at creation. The trust anchor is the operator's * env-var declaration PLUS the operator-executed creation — not a mailbox * round-trip; SMTP stays required only for inviting OTHERS. This extends the - * #11343 precedent (the dev-boot seeded admin, `auth-plugin.ts` + * commit c0714eb5d precedent (the dev-boot seeded admin, `auth-plugin.ts` * `maybeSeedDevAdmin`: "provisioned by the deployment's own boot command with * operator-known credentials — not an unknown self-registrant") to * production walled boots, whose owner previously had NO in-product way to @@ -54,7 +54,7 @@ * dead for its owner). The ruling accepts the env declaration + the * creation act as the anchor. * - **`self-serve` class WITHOUT the carve-out**: NEVER qualifies — a - * self-registrant typing the owner's address proves nothing (#11343's + * self-registrant typing the owner's address proves nothing (commit c0714eb5d's * whole point), and that includes an invitation-admitted registration * (the invitation carve-out admits the CREATION; it does not verify the * mailbox). @@ -78,7 +78,7 @@ * owner address inherits nothing: the decision is staged from the * creation-time admission gate and consumed once by the `user.create` * before-hook, a seam an update can never traverse. - * - Dev-boot behaviour (#11343's seed stamp) is unchanged: on a walled dev + * - Dev-boot behaviour (commit c0714eb5d's seed stamp) is unchanged: on a walled dev * boot whose declared owner is the seeded address, this module stamps the * same account the seed would have stamped a moment later — idempotent by * construction. diff --git a/packages/plugins/plugin-auth/src/walled-owner-verification-path.ts b/packages/plugins/plugin-auth/src/walled-owner-verification-path.ts index 9a670a20f37..ed5591a9fc0 100644 --- a/packages/plugins/plugin-auth/src/walled-owner-verification-path.ts +++ b/packages/plugins/plugin-auth/src/walled-owner-verification-path.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. /** - * [#11640] The walled deployment that declares an owner it can never verify. + * [commit bf8d129b5] The walled deployment that declares an owner it can never verify. * * Maintainer ruling 2026-08-25 (decision-inbox batch 5, verbatim: 「全部同意」 * accepting option **A**): at boot, a walled deployment with @@ -25,7 +25,7 @@ * * ## Why the deployment is a dead end * - * #11343 made walled platform-admin standing require a VERIFIED owner-email + * Commit c0714eb5d made walled platform-admin standing require a VERIFIED owner-email * match (the string alone proves nothing — anyone who knows the address could * register it first), and the #11663 re-anchor kept the requirement while * retiring the elevation write: the verified match is now read at request @@ -129,7 +129,7 @@ const env = (): Record => /** * The address `AuthPlugin.maybeSeedDevAdmin` provisions. Exported so the seed * and this check read ONE resolution: the check treats the seed as a - * verification path (it stamps the seeded account `email_verified`, #11343), + * verification path (it stamps the seeded account `email_verified`, commit c0714eb5d), * which is only true while both agree on which address gets stamped. */ export function devSeedAdminEmail(): string { @@ -213,7 +213,7 @@ export interface VerificationPathWiring { * owner lookup (both the lowercased and the verbatim spelling, matches * re-checked through the shared predicates — the same two-spelling read * `plugin-security`'s `resolvePlatformAdminStanding` serves the audit surface - * with). The verified answer is the shared [#11343] allow-list + * with). The verified answer is the shared [commit c0714eb5d] allow-list * (`isEmailVerifiedUserRow`) — the SAME predicate the derivation site reads * ([#11973]: `resolve-authz-context.ts` §6b-config, where an unverified * declared address resolves non-admin), so this probe can never forecast a @@ -303,7 +303,7 @@ export interface WalledOwnerVerificationLogger { * of the declared owner is stamped verified at creation, so a fresh * walled boot with nothing wired is no longer a dead end. Two dev-boot * sub-shapes keep their pre-#12751 answers: a seed armed for the - * declared owner's own address was already `null` (#11343's seed stamp), + * declared owner's own address was already `null` (commit c0714eb5d's seed stamp), * and a seed armed for some OTHER address still WARNS — the seed will * spend the bootstrap carve-out on a non-owner account at `kernel:ready`, * before the owner can ever be first. @@ -337,7 +337,7 @@ export function resolveWalledOwnerVerificationPathWarning( if (state === 'owner-verified') return null; // The dev-admin seed provisions the declared owner AND stamps it verified - // (#11343) — but only ever on an EMPTY store, so it rescues exactly the + // (commit c0714eb5d) — but only ever on an EMPTY store, so it rescues exactly the // shapes where the store is empty or unknowable (the verify-harness boots // that probe nothing). An owner account that already exists unverified, or // a populated store with no owner account, is past the seed's reach and