Skip to content

Commit de20633

Browse files
fix(qa-checklist): re-point thirteen identity-auth bad-citation anchors and drain their residual rows (#19196)
Part of #18104 Clause-②: no ## The slice The **second slice** of the `SHARED_RESOLVER_RESIDUAL` drain: **`areas/identity-auth.json` — 13 rows, 13 anchor occurrences.** It is the largest single-file block of the 38 `bad-citation` rows the first slice (#19181, landed at `82b322585`) left behind, and it is one file, so every judgement in it is made against one item ledger. ## ⚠️ This file is NOT empty of residual rows afterwards, and that is correct `areas/identity-auth.json` also carries **2 `accept-set` rows** — `packages/spec/src/kernel/public-auth-features.ts#sys_user` and `#sys_invitation`, both the `dotted-string-head` shape. **They are #18101's, not this card's**, and they stay exactly where they are. Reaching them means widening `scripts/symbol-anchors.mjs`, which is the red line #18104 / #18101 / #18107 share by name. After this slice the ledger carries **33 rows** — `bad-citation` 25 + `accept-set` 8 — and `areas/identity-auth.json` accounts for 2 of them. ## Per row: which kind it was (acceptance item 2) **All 13 are genuinely wrong citations, re-pointed. None is an `accept-set` case, so none belongs to #18101.** Each old symbol was put to `scripts/symbol-anchors.mjs#symbolSegmentResolution` directly and returns `null`; each new one returns `declaration`. | # | old anchor | what the old symbol actually was in the cited file | re-pointed to | |---|---|---|---| | 1 | `areas/access-security.json#access` | not a key that JSON declares at all | `#items` | | 2 | `seed-approval-demo.ts#PHONE_DEMO_USER` | IMPORTED — the constant lives elsewhere | `demo-personas.ts#PHONE_DEMO_USER` (the **path** moved, the symbol did not) | | 3 | `sys-member.object.ts#BUILTIN_MEMBERSHIP_ROLE_OPTIONS` | IMPORTED from `@objectstack/spec/identity` | `#SysMember` | | 4 | `sys-oauth-application.object.ts#OAuth` | the bare word, only inside `label` / `description` strings | `#SysOauthApplication` | | 5 | `auth-route-ledger.ts#bootstrapStatus` | CLIENT METHOD name, inside a dotted string value | `#AUTH_ROUTE_LEDGER` | | 6 | `auth-route-ledger.ts#linkSocial` | CLIENT METHOD name, inside a dotted string value | `#AUTH_ROUTE_LEDGER` | | 7 | `auth-route-ledger.ts#revokeOthers` | CLIENT METHOD name, inside a dotted string value | `#AUTH_ROUTE_LEDGER` | | 8 | `auth-route-ledger.ts#sendVerificationEmail` | CLIENT METHOD name, inside a dotted string value | `#AUTH_ROUTE_LEDGER` | | 9 | `auth-route-ledger.ts#setActive` | CLIENT METHOD name, inside a dotted string value | `#AUTH_ROUTE_LEDGER` | | 10 | `auth-route-ledger.ts#updateUser` | CLIENT METHOD name, inside a dotted string value | `#AUTH_ROUTE_LEDGER` | | 11 | `security-plugin.ts#__referentialFieldClear` | a CONTEXT KEY, read only as a member access on `opCtx.context` | `#SecurityPlugin` | | 12 | `membership-role-vocabulary.dogfood.test.ts#PermissionSet` | in a comment and an `it(...)` title | `#CLOSED_VOCABULARY` | | 13 | `rest-route-ledger.ts#describeDelegableScope` | CLIENT METHOD name, inside a `client:` string value | `#REST_ROUTE_LEDGER` | Six of them (5–10) are the first slice's reading applied again: a route ledger's `client` field is DATA the table carries, and the declaration the item means is the exported table. That spelling is already this corpus's own — `areas/api-backend.json` has read `auth-route-ledger.ts#AUTH_ROUTE_LEDGER` since before this card. Three needed a reading of their own: - **Row 1 is the `detector-artifact` row**, and it was repaired **citation-side**, per the PM's ruling in comment `5740561848`. The ledger's own fields say why: `detector-artifact` is the **`shape`** (why the withdrawn permissive rule used to resolve it), while the **`verdict`** has always read `bad-citation`. Reading the shape as the disposition sends the next author at the detector, which since #18107 IS `scripts/symbol-anchors.mjs` — the file this card forbids by name. And the truncation is not happening on today's bytes anyway: the citation's fragment is followed by a SPACE, so the symbol was simply what the author wrote. What they meant is the item id in the parenthetical, which the checklist JSON carries as a VALUE, never a key — so the citation now names the `items` block and the item id stays in the prose beside it. The ledger header records this so the next reader is not sent the same way. - **Row 2 is a MOVE, not a rename.** `seed-approval-demo.ts` says so in its own header: the demo identities "now live in `demo-personas.ts`, because the SEED needs them too". The file only imports the persona and provisions it; the constant, `phone_number` included, is declared next door. The path is what was stale, so the path is what moved. This is the one change that adds a cited source (309 → 310). - **Row 3 is the mirror of row 2 and went the other way**, deliberately. The same item ALREADY anchors `packages/spec/src/identity/membership-role.ts#BUILTIN_MEMBERSHIP_ROLES` two rows above, so re-pointing this one at the spec too would have been a duplicate. This citation is about the **object's role select**, and what `sys-member.object.ts` declares is the object. ## No `#symbol` was dropped, and no floor moved (acceptance item 3) `areas/identity-auth.json`'s census is **83** against a floor of **82** — one of headroom — so this was measured, not assumed. The per-file census is **identical before and after, 17/17 files**: ``` node scripts/check-platform-checklist.mjs --anchor-census before vs after: the 17 per-file counts are byte-identical; only the summary line moves 587/633 resolved, plus 46 on the named residual -> 600/633 resolved, plus 33 ``` That is the mechanism, not luck: the floor population is `resolved + residual`, so a repair moves an occurrence from one side to the other and leaves the per-file count where it was. The bare gate says it in its own words — **`17 file floors held`**. `scripts/checklist-symbol-anchor-baseline.json` is untouched. ## Rows left by repair, and the ceiling came down with them (acceptance items 1 and 4) `SHARED_RESOLVER_RESIDUAL` 46 rows → **33**; `SHARED_RESOLVER_RESIDUAL_CEILING` 46 → **33**, in the same edit. The header's tallies are re-counted off the surviving rows rather than adjusted by hand: `string-substring` 21 → 12, `import-only` 8 → 6, `member-access` 3 → 2, `detector-artifact` 1 → 0, `bad-citation` 38 → 25; `accept-set` stays **8** and is untouched. The `detector-artifact` block is kept at zero rows on purpose, carrying the ruling above — the shape reading is what a future author needs, and deleting it would delete the reason this row is not a detector bug. ## Positive control (acceptance item 3) — two legs, opposite directions Both legs mutate the **committed** tree, prove the mutation landed on disk before any verdict is read, restore with `git checkout HEAD -- PATH` under an `EXIT INT TERM` trap on an absolute path, and prove the restore by blob hash against HEAD plus an empty `git diff HEAD` — never by an exit code. Control run first: bare gate **exit 0**, zero `ABSENT SYMBOL` lines. **Leg A — a repaired anchor is still being judged, and it resolves through the shared resolver.** Row 1's repaired citation was re-pointed to a symbol `areas/access-security.json` does not declare (on-disk proof: target text before=1 after=0, injected marker before=0 after=1). Gate **exit 1**: ``` areas/identity-auth.json: ABSENT SYMBOL - `docs/qa/platform-checklist/areas/access-security.json#itemsAblationNotDeclared`: `itemsAblationNotDeclared` is not declared in docs/qa/platform-checklist/areas/access-security.json by `scripts/symbol-anchors.mjs#symbolResolutionClass` ``` Restored (blob `f6baec3c...` == HEAD, `git diff HEAD` empty), gate back to **exit 0**. So the green on these citations is the shared resolver answering `declaration`, not the gate having gone quiet on them. **Leg B — an unrelated row on THIS SAME FILE still reds.** One of the two `accept-set` rows this slice deliberately leaves behind (`public-auth-features.ts#sys_user`) was deleted from the ledger without repairing its citation (on-disk proof: row before=1, after=0). Gate **exit 1** with `ABSENT SYMBOL` naming that anchor; restored (blob `4ae200e4...` == HEAD, `git diff HEAD` empty), back to **exit 0**. So `areas/identity-auth.json` is still swept and its residual rows still fire — the 13 left this ledger **by repair**, not because the document went dark. ## Gates `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` re-derived against the real changed set (2 committed paths, `+42/-33`) yields **31 families** — the same count as the first slice, on a different path set. `scripts/check-platform-checklist.mjs` is itself a gate, so **both halves were run separately**, not only the aggregate: - bare invocation **exit 0** — `OK — 15 areas, 264 items … symbol anchors: 600/633 resolved … 33 on the named residual, 17 file floors held` - `--self-test` **exit 0** — 221 assertions - `pnpm check:platform-checklist` (which chains `checklist-select --self-test` in front of both) **exit 0** One family reported **exit 3 — PREREQUISITE NOT MET**, which is not a finding: `@objectstack/lint run check:doc-formula-expressions` wants `@objectstack/formula` and `@objectstack/lint` built. No import relationship changed and no TypeScript program's view moved — the diff is one ESM gate script's data and comments plus one JSON document, neither of which any `tsconfig` includes — so no per-package `typecheck` is owed beyond what the derivation already places. **"All 31 derived families green" is not "CI green".** The derivation names what sits outside those 31: 53 artifact-roster families, 11 declared-wide-population families, 14 families that apply once a changeset exists, 2 families taking a value from the workflow, and 1 path-scheduled CI job. CI is the authority on those. ## Changeset No changeset: nothing published moves. Measured rather than assumed — the diff touches only repo-root `scripts/` and `docs/qa/`, neither of which is inside any package directory, so no package manifest's `files[]` can ship either path. `skip-changeset` applies. ## Acceptance notes - **The baseline JSON's `$comment` is still inaccurate, and this PR deliberately does not fix it.** It reads "Each entry is the count of anchors that RESOLVED in that family file"; since #16898 an entry is resolved + residual, which this gate's own `--anchor-census` footer states outright. `scripts/checklist-symbol-anchor-baseline.json` line 3 declares itself `⛔ MAINTAINER-ONLY`. Reported, not touched — a one-sentence maintainer edit, already recorded on the card. - **The card's original repair instruction for the `detector-artifact` row is left standing as history**, with the PM's correction under it. This PR follows the correction. --- _Generated by [Claude Code](https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 877dc03 commit de20633

2 files changed

Lines changed: 42 additions & 33 deletions

File tree

‎docs/qa/platform-checklist/areas/identity-auth.json‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
"source": [
137137
"#3358 §6",
138138
"#3408",
139-
"examples/app-showcase/src/security/seed-approval-demo.ts#PHONE_DEMO_USER (PHONE_DEMO_USER)",
139+
"examples/app-showcase/src/security/demo-personas.ts#PHONE_DEMO_USER (PHONE_DEMO_USER — re-pointed #18104: seed-approval-demo.ts only IMPORTS this persona and provisions it; the constant, phone_number included, is declared in demo-personas.ts, the one registry the seed and the approval bootstrap share)",
140140
"packages/spec/src/system/auth-config.zod.ts#phoneNumber (phoneNumber plugin: unique phone_number + phone_number_verified columns)",
141141
"packages/spec/src/kernel/public-auth-features.ts#phoneNumber (phoneNumber gates sys_user.actions.create_user.params.phoneNumber — #2871)"
142142
],
@@ -355,7 +355,7 @@
355355
"source": [
356356
"packages/qa/dogfood/test/delegated-admin-invite.dogfood.test.ts (ADR-0105 D8 / #3697; the escalation chain the role cap blocks)",
357357
"packages/spec/src/identity/organization.zod.ts#InvitationSchema (InvitationSchema, InvitationStatus enum)",
358-
"packages/rest/src/rest-route-ledger.ts#describeDelegableScope (GET /api/v1/security/my-delegable-scope — security.describeDelegableScope, ADR-0090 D12 / ADR-0105 D8, self-scoped read half of the delegated-admin gate)",
358+
"packages/rest/src/rest-route-ledger.ts#REST_ROUTE_LEDGER (GET /api/v1/security/my-delegable-scope — security.describeDelegableScope, ADR-0090 D12 / ADR-0105 D8, self-scoped read half of the delegated-admin gate — re-pointed #18104: describeDelegableScope is a CLIENT METHOD name, carried in this file only inside a string value)",
359359
"packages/spec/src/contracts/security-service.ts#DelegableScope (DelegableScope: isTenantAdmin, scopes, placeableBusinessUnitIds, assignablePositions — no invitation-role field, which is why the scope read cannot be the invite picker's allowlist)",
360360
"packages/spec/src/kernel/public-auth-features.ts#sys_invitation (organization feature gates sys_invitation invite/cancel/resend actions)"
361361
],
@@ -477,7 +477,7 @@
477477
"packages/spec/src/system/auth-config.zod.ts (admin plugin: endpoint list, sys_user role/banned/ban_reason/ban_expires, sys_session.impersonated_by)",
478478
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#BETTER_AUTH_MOUNTED_SURFACE (BETTER_AUTH_MOUNTED_SURFACE admin/* rows: list-users, create-user, set-role, remove-user, revoke-user-session(s))",
479479
"packages/plugins/plugin-auth/src/admin-user-endpoints.ts#resolvePassword (create-user resolvePassword: explicit password wins over generatePassword — #3031/#3033; leaves sys_user + credential sys_account)",
480-
"packages/plugins/plugin-security/src/security-plugin.ts#__referentialFieldClear (§A5 #3023 EXEMPTION: __referentialFieldClear owner_id-null cascade rides a server-derived context, the owner-anchor guard must not veto it) + security-plugin.test.ts '[#3023] … engine referential FK clear … is exempt'",
480+
"packages/plugins/plugin-security/src/security-plugin.ts#SecurityPlugin (§A5 #3023 EXEMPTION: __referentialFieldClear owner_id-null cascade rides a server-derived context, the owner-anchor guard must not veto it — re-pointed #18104: __referentialFieldClear is a CONTEXT KEY this file only reads off opCtx.context, a member access; the guard that honours it is in the SecurityPlugin class this file declares) + security-plugin.test.ts '[#3023] … engine referential FK clear … is exempt'",
481481
"packages/spec/src/kernel/public-auth-features.ts#sys_user (admin flag gates the sys_user lifecycle actions; SCIM forces it on — ADR-0134)",
482482
"packages/qa/dogfood/test/admin-identity-audit-trail.dogfood.test.ts",
483483
"packages/plugins/plugin-auth/src/anonymous-session-refusal.ts#ANONYMOUS_SESSION_REFUSAL_STATUS (since #17881 an anonymous or revoked /get-session answers 401 with the ADR-0112 refusal envelope, code UNAUTHENTICATED derived from that status; a live session still answers 200 with { user, session }. Both legs are driven end to end in packages/plugins/plugin-auth/src/anonymous-session-refusal.test.ts, and the body-not-status discipline for a revoke is kept in packages/plugins/plugin-auth/src/session-of-record.test.ts)"
@@ -574,7 +574,7 @@
574574
],
575575
"traps": ["wrong-persona", "shared-browser-tab"],
576576
"source": [
577-
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#revokeOthers (GET list-sessions=auth.sessions.list, POST revoke-session=auth.sessions.revoke, revoke-other-sessions=auth.sessions.revokeOthers, revoke-sessions=auth.sessions.revokeAll)",
577+
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (GET list-sessions=auth.sessions.list, POST revoke-session=auth.sessions.revoke, revoke-other-sessions=auth.sessions.revokeOthers, revoke-sessions=auth.sessions.revokeAll — re-pointed #18104: revokeOthers is a CLIENT METHOD name, carried in this file only inside a dotted string value)",
578578
"packages/platform-objects/src/identity/sys-session.object.ts#user_id (mine view filter user_id={current_user_id}; all_sessions admin view; revoked_at/revoke_reason fields ADR-0069 D4; revoke_session action recordIdParam:'token'; apiMethods ['get','list'] — writes 405 before 403, #1591/ADR-0092 D2)",
579579
"packages/platform-objects/src/apps/setup-nav.contributions.ts#nav_sessions (nav_sessions → Setup Sessions, objectName sys_session)"
580580
],
@@ -741,7 +741,7 @@
741741
"traps": ["hydration-race", "stale-console-bundle"],
742742
"source": [
743743
"objectui apps/console/src/pages/system/ProfilePage.tsx (updateUser name/image; useUpload avatar; PasswordCard changePassword vs setInitialPassword gated on hasLocalPassword; email immutable; data-testids profile-avatar-file/-upload-btn/-remove-btn)",
744-
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#updateUser (POST /api/v1/auth/update-user=auth.updateUser, POST /api/v1/auth/change-password=auth.changePassword, GET /api/v1/auth/get-session=auth.me)",
744+
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (POST /api/v1/auth/update-user=auth.updateUser, POST /api/v1/auth/change-password=auth.changePassword, GET /api/v1/auth/get-session=auth.me — re-pointed #18104: updateUser is a CLIENT METHOD name, carried in this file only inside a dotted string value)",
745745
"packages/platform-objects/src/identity/sys-account.object.ts#previous_password_hashes (previous_password_hashes ring — ADR-0069 D1 reuse-prevention backs change-password)"
746746
],
747747
"history": [
@@ -832,8 +832,8 @@
832832
"packages/plugins/plugin-auth/src/auth-route-ledger.ts (organization family: update-member-role, remove-member, update, create-team, add-team-member, list-members/teams/invitations, get-active-member, get-full-organization)",
833833
"packages/spec/src/identity/membership-role.ts#BUILTIN_MEMBERSHIP_ROLES (BUILTIN_MEMBERSHIP_ROLES / BUILTIN_MEMBERSHIP_ROLE_OPTIONS — THE role vocabulary: owner/admin/delegated_admin/member, ADR-0108; 'nothing widens these at boot any more')",
834834
"docs/adr/0108-membership-grade-is-not-a-capability-channel.md (why the list is closed: a grade decides what you can REACH, never a bundle of what you may do)",
835-
"packages/qa/dogfood/test/membership-role-vocabulary.dogfood.test.ts#PermissionSet (both enforced selects offer exactly the four; a declared position or PermissionSet name is refused at better-auth's role check — ROLE_NOT_FOUND — before any insert)",
836-
"packages/platform-objects/src/identity/sys-member.object.ts#BUILTIN_MEMBERSHIP_ROLE_OPTIONS + sys-invitation.object.ts (role select options: [...BUILTIN_MEMBERSHIP_ROLE_OPTIONS])",
835+
"packages/qa/dogfood/test/membership-role-vocabulary.dogfood.test.ts#CLOSED_VOCABULARY (both enforced selects offer exactly the four; a declared position or PermissionSet name is refused at better-auth's role check — ROLE_NOT_FOUND — before any insert — re-pointed #18104: PermissionSet survives in this file only inside a comment and an it(...) title; the four this item means are what CLOSED_VOCABULARY declares)",
836+
"packages/platform-objects/src/identity/sys-member.object.ts#SysMember + sys-invitation.object.ts (role select options: [...BUILTIN_MEMBERSHIP_ROLE_OPTIONS] — re-pointed #18104: this file IMPORTS that constant from the spec, which the membership-role.ts citation two rows up already anchors; what sys-member.object.ts declares is the object carrying the select)",
837837
"packages/platform-objects/src/identity/sys-team-member.object.ts#team_id (add_team_member/remove_team_member actions → organization/add-team-member; unique team_id+user_id; requiresFeature organization)"
838838
],
839839
"history": [
@@ -914,7 +914,7 @@
914914
"packages/platform-objects/src/identity/sys-team-member.object.ts#team_id (add_team_member/remove_team_member → organization/add-team-member|remove-team-member; unique team_id+user_id)",
915915
"packages/platform-objects/src/identity/sys-business-unit.object.ts#parent_business_unit_id (canonical BU tree ADR-0057 D2; kind enum; parent_business_unit_id self-ref; org_chart tree view; managedBy 'platform' — writable over the data API)",
916916
"packages/platform-objects/src/identity/sys-business-unit-member.object.ts#function_in_business_unit (user↔BU placement: function_in_business_unit member/lead/deputy, is_primary)",
917-
"docs/qa/platform-checklist/areas/access-security.json#access (access-security.scope-depth-asymmetry — the depth matrix this cross-references for the tree-widening geometry)",
917+
"docs/qa/platform-checklist/areas/access-security.json#items (access-security.scope-depth-asymmetry — the depth matrix this cross-references for the tree-widening geometry — re-pointed #18104: access is not a key this JSON declares; a cross-area citation names the items block, and the item id stays in this parenthetical)",
918918
"examples/app-showcase/src/security/sharing-rules.ts#share_new_inquiries_with_field_ops (`share_new_inquiries_with_field_ops` — the shipped BU-consuming geometry: expands the bu_field_ops subtree onto showcase_inquiry)",
919919
"examples/app-showcase/src/data/seed/index.ts#sys_business_unit (the sys_business_unit tree is seeded with explicit ids; user↔unit membership — sys_business_unit_member — and position assignments are NOT seeded, they stay runtime admin actions)"
920920
],
@@ -1088,7 +1088,7 @@
10881088
"packages/types/src/env.ts#isMcpServerEnabled (isMcpServerEnabled — unset means TRUE; explicit false/0/off/no opts out)",
10891089
"objectui apps/console/src/App.tsx (/oauth/consent → OAuthConsentPage) + apps/console/src/pages/auth/OAuthConsentPage.tsx",
10901090
"packages/platform-objects/src/identity/sys-oauth-consent.object.ts#apiEnabled (row implies consent for listed scopes — consent_given removed; apiEnabled:false so verify via get-consents, not the data API)",
1091-
"packages/platform-objects/src/identity/sys-oauth-application.object.ts#OAuth + setup-nav.contributions.ts (nav_oauth_apps → Setup OAuth Applications)"
1091+
"packages/platform-objects/src/identity/sys-oauth-application.object.ts#SysOauthApplication + setup-nav.contributions.ts (nav_oauth_apps → Setup OAuth Applications — re-pointed #18104: the bare word OAuth is carried in this file only inside label and description strings)"
10921092
],
10931093
"history": [
10941094
{ "revision": 1, "date": "2026-08-08", "change": "new item: OAuth client registration (secret once) + authorization-code consent loop (approve mints tokens + consent record, deny mints none, recorded consent short-circuits), mine-view scoped; blocked(fixture) pending a configured oidcProvider flow (PENDING-GAPS §C)", "ref": "claude/platform-test-checklist-ocwugl" },
@@ -1161,7 +1161,7 @@
11611161
"traps": ["wrong-persona", "dispatcher-vs-hono-route", "hydration-race"],
11621162
"source": [
11631163
"packages/platform-objects/src/identity/sys-account.object.ts#user_id (link_social type:'url' → /api/v1/auth/sign-in/social?provider=&callbackURL=; unlink_account → /api/v1/auth/unlink-account accountId=row id; mine view user_id={current_user_id} vs all_links; provider options; apiMethods ['get','list'])",
1164-
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#linkSocial (POST link-social=auth.accounts.linkSocial, GET list-accounts=auth.accounts.list, POST unlink-account=auth.accounts.unlink)",
1164+
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (POST link-social=auth.accounts.linkSocial, GET list-accounts=auth.accounts.list, POST unlink-account=auth.accounts.unlink — re-pointed #18104: linkSocial is a CLIENT METHOD name, carried in this file only inside a dotted string value)",
11651165
"packages/platform-objects/src/apps/setup-nav.contributions.ts#nav_accounts (nav_accounts → 'Identity Links', objectName sys_account)"
11661166
],
11671167
"history": [
@@ -1684,7 +1684,7 @@
16841684
"objectui apps/console/src/components/SetupRoute.tsx (one URL, two surfaces — first-run wizard vs platform-admin deep link, objectui#2794) + setupEntry.ts (the latched verdict: fresh only from an unauthenticated probe)",
16851685
"objectui apps/console/src/pages/auth/SetupPage.tsx (renders only at hasOwner:false; creates owner + names the auto-provisioned personal org) + (why both exits are FULL-PAGE navigations — objectui#4181) + handleSubmit (rename-not-create, refreshOrganizations poll, slug guard)",
16861686
"packages/plugins/plugin-auth/src/auth-plugin.ts#dataEngine (bootstrap-status exempt from the auth wall) + (the route: hasOwner from dataEngine.count('sys_user'))",
1687-
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#bootstrapStatus (GET /api/v1/auth/bootstrap-status = auth.bootstrapStatus, objectstack-mount)",
1687+
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (GET /api/v1/auth/bootstrap-status = auth.bootstrapStatus, objectstack-mount — re-pointed #18104: bootstrapStatus is a CLIENT METHOD name, carried in this file only inside a dotted string value)",
16881688
"packages/plugins/plugin-auth/src/auth-manager.ts#isBootstrapCreation (the bypass's contract comment) + (the before-hook: isBootstrapCreation flips disableSignUp for this request — [#11767] fixed the inert probe) + (isBootstrapCreation: human rows, fail-closed on a full page)",
16891689
"packages/plugins/plugin-auth/src/audience-posture.ts#isHumanUserRow (isHumanUserRow) + (decideAudienceAdmission isBootstrap arm) + (undeclared audience ⇒ invite_only, maintainer ruling 2026-08-24)",
16901690
"packages/cli/src/commands/dev.ts,339 (seed-admin defaults ON — why a zero-user boot needs --no-seed-admin)"
@@ -1863,7 +1863,7 @@
18631863
"source": [
18641864
"packages/plugins/plugin-auth/src/auth-manager.ts#requireEmailVerification (requireEmailVerification wiring — [#11739]: a self-registration-permitting posture FORCES it on; otherwise config passthrough) + (emailVerification block: sendOnSignUp/sendOnSignIn/autoSignInAfterVerification/expiresIn passthrough; sendVerificationEmail via template auth.verify_email, failures thrown into the log) + (getPublicConfig mirrors the forced flag)",
18651865
"packages/plugins/plugin-auth/src/audience-posture.ts#entry (entry validation refuses the permitting-posture + explicit-false contradiction)",
1866-
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#sendVerificationEmail (POST /api/v1/auth/send-verification-email = auth.sendVerificationEmail) + (GET /api/v1/auth/verify-email = auth.verifyEmail)",
1866+
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (POST /api/v1/auth/send-verification-email = auth.sendVerificationEmail) + (GET /api/v1/auth/verify-email = auth.verifyEmail) — re-pointed #18104: sendVerificationEmail is a CLIENT METHOD name, carried in this file only inside a dotted string value",
18671867
"objectui apps/console/src/App.tsx (/verify-email + /verify-email-prompt routes)",
18681868
"objectui apps/console/src/pages/auth/VerifyEmailPage.tsx (consumes ?token= via the POST variant — GET 302s, POST returns JSON so the SPA controls the post-verify UX)",
18691869
"objectui apps/console/src/pages/auth/VerifyEmailPromptPage.tsx (shown after sign-up or an EMAIL_NOT_VERIFIED-blocked sign-in; resend via useAuth().sendVerificationEmail)",
@@ -1954,7 +1954,7 @@
19541954
"objectui packages/app-shell/src/layout/CurrentOrganizationIndicator.tsx (objectui#5287: read-only name for exactly-one membership, gated on postureHasOrgWall — single posture renders nothing by design; no click target)",
19551955
"objectui packages/app-shell/src/hooks/useTenancyPosture.ts (postureHasOrgWall restated locally for bundle size, spec-parity test-locked)",
19561956
"objectui packages/app-shell/src/providers/MetadataProvider.tsx (objectui#4486: an org change drops the whole metadata cache — one organization's metadata never survives into another organization's reads; the reloading switch paths and the SPA-internal path both covered)",
1957-
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#setActive (POST /api/v1/auth/organization/set-active = organizations.setActive, requires organization)",
1957+
"packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (POST /api/v1/auth/organization/set-active = organizations.setActive, requires organization — re-pointed #18104: setActive is a CLIENT METHOD name, carried in this file only inside a dotted string value)",
19581958
"packages/plugins/plugin-auth/src/auth-manager.ts#multiOrgEnabled (multiOrgEnabled = postureEnforcesWall(effectiveTenancyPosture()) — the SAME call the org-create gate makes, #5233/#5261) + area (features advertised)",
19591959
"packages/types/src/env.ts#resolveTenancyPosture (resolveTenancyPosture: OS_TENANCY_POSTURE, invalid value refuses boot; unset falls back to `single` unless legacy multi-org env)"
19601960
],

0 commit comments

Comments
 (0)