Skip to content

docs(qa): re-anchor three approvals knownGaps on the sys_account.issuer retirement - #19213

Merged
os-try-charles merged 1 commit into
mainfrom
claude/issue-17453-approvals-knowngap-citations
Sep 19, 2026
Merged

os-try-charles merged 1 commit into
mainfrom
claude/issue-17453-approvals-knowngap-citations

Conversation

@os-try-charles

Copy link
Copy Markdown
Collaborator

Fixes #17453

What this changes

Three knownGap texts in docs/qa/platform-checklist/areas/approvals.json cited
packages/plugins/plugin-auth/src/backfill-account-issuer.ts, CREDENTIAL_ISSUER. That module
retired with sys_account.issuer when better-auth 1.7.3 rolled the issuer-scoped account identity
back (#17440, closed 2026-09-12), so the citation names a file that is not on the tree and a reader
who follows it cannot tell whether the gap is closed or the citation merely rotted.

The file's convention is explicit — the gap text stays because it carries the reason — so this is
not a path substitution, and there is nothing to substitute anyway:

  • backfill-account-issuer.ts is gone. Positive control: ls packages/plugins/plugin-auth/src/
    lists 176 files, so the empty grep backfill is a reading, not a broken instrument.
  • CREDENTIAL_ISSUER survives only as history — as a retired symbol named in
    packages/spec/src/migrations/entries/semantic/18.sys-account-issuer-retired.ts (and its copy in
    the generated packages/spec/src/migrations/registry.ts), and as the deliberately renamed test
    constant LEGACY_CREDENTIAL_ISSUER in packages/plugins/plugin-auth/src/account-issuer-upgrade-path.test.ts.
    There is no live symbol to re-point the three citations at.

So each text keeps the reason it exists to carry — a password hash alone was not enough; the failure
was a silent lockout whose User not found warn pointed at the sys_user row rather than at the
account — and now records that the trap retired with the column, anchored on the retirement's
own migration entry, which is a durable record rather than a module that can be deleted.

The clauses the retirement also falsified

The card's second claim measured true, and this pass fixes it in the same edit. The governing text
is the repo's own, in examples/app-showcase/src/security/seed-approval-demo.ts:

1.7.3 rolled that model back and sys_account.issuer retired with it, so the derivation, its
failure branch and the whole class of silent lockout behind it are gone. (provider_id, account_id)
is the key, and internalAdapter.createAccount supplies both.

Withdrawn accordingly:

text falsified clause now reads
approvals.per-group-signoff "the issuer READ OFF the dev admin's own credential row rather than re-spelled" the seed provisions the account through better-auth's own $context; there is no issuer to read
approvals.viewer-gating-submitter-side "derives that issuer from the dev admin's own credential row and stamps it"; "pins both the issuer and the sign-in" nothing is derived or stamped; the dogfood test pins the account under the key sign-in resolves on and asserts nothing still writes the retired field
approvals.ooo-delegation-reroute "(issuer derived from the dev admin's own row)" delegate B is constructible with nothing about her issuer to get right

Each of the three items bumps revision and appends a history entry, per the checklist's
change lifecycle (docs/qa/platform-checklist/README.md).

One bounded in-place fix, declared

approvals.ooo-delegation-reroute's steps carried the same dead requirement one field below the
gap text it points at: "provision B as a real login (see knownGaps: the credential account's issuer
must be local:credential)"
. Left alone it would have contradicted the rewritten knownGap three
lines above it and still sent a runner looking for a column that no longer exists — a replayed
instruction, not prose. It is corrected to "a stock boot already does it, see knownGaps".

It is declared here because it sits outside the three texts the dispatch named, and it is inside
every other boundary: same file (the declared file surface), same defect class, mechanical, no new
verification surface, and no other claim holds this file.

Measurements

Base origin/main @ 24d622b94; gates re-run on the final commit.

The three citations were at :23, :259, :662 — no drift from the card.

node scripts/pm/dispatch-gates.mjs --commands prescribes 12 commands for this surface. All 12 are
green (EXIT=0), including pnpm check:platform-checklist. Two needed prerequisites first
(pnpm install in the fresh worktree; turbo run build --filter=@objectstack/formula --filter=@objectstack/lint for check:doc-formula-expressions) — their first exit 3 was
PREREQUISITE NOT MET, not a finding.

The zero-headroom surface did not move. Census line before and after the edit are identical:

check-platform-checklist: OK — 15 areas, 264 items (264 active, 0 planned); coverage: 38 kinds mapped,
1 waived; traps: 19 documented, 19 in use; provisioning: 5 area recipes, 8 item references resolved
(1 area-qualified), 5/5 recipes referenced; meta-URL spelling: 19 `call` strings scanned against 34
folded spellings; line citations: 0 survive across 20 swept documents; symbol anchors: 600/633 resolved
by `symbol-anchors.mjs` across 20 swept documents against 310 cited sources, 33 on the named #16898
residual, 17 file floors held

That is the expected reading rather than luck: the three citations were bare paths, not
path#symbol anchors, so they were never in the anchor population the floors count — and the new
anchor is written bare and without a line number, which also keeps the file:line limb at 0.
No floor and no baseline JSON was touched.

Acceptance notes

  • docs/qa/platform-checklist/areas/approvals.json history entries at revisions 4 and 5 of the three
    items still narrate the issuer trap in the past tense ("issuer derived from the dev admin's own
    row"). They are left alone on purpose: history is the append-only record of what the item said
    when a run was pinned against it, and rewriting it would destroy the thing that makes old run
    records interpretable.
  • scripts/check-platform-checklist.mjs carries a bad-citation ledger row for this file
    (seed-approval-demo.ts#AUDITOR_DEMO_USER, shape: import-only). It is a different citation from
    the three changed here and is untouched; noted, not filed.

Generated by Claude Code

…er retirement

Three knownGap texts in the approvals area cited
`packages/plugins/plugin-auth/src/backfill-account-issuer.ts, CREDENTIAL_ISSUER`.
That module retired with `sys_account.issuer` when better-auth 1.7.3 rolled the
issuer-scoped account identity back, so the citation names a file that is not
there and a reader cannot tell whether the gap is closed or the citation rotted.

There is no successor symbol to re-point at: `CREDENTIAL_ISSUER` survives only as
history, in the retirement's migration entry and as a deliberately renamed test
constant. So the texts keep the reason they exist to carry -- a password hash
alone was not enough, and the failure was a silent lockout whose `User not found`
warn pointed at the `sys_user` row rather than at the account -- and record that
the trap retired with the column, anchored on
`packages/spec/src/migrations/entries/semantic/18.sys-account-issuer-retired.ts`.

The same pass withdraws the clauses the retirement falsified: the seed no longer
derives the issuer from the dev admin's own row (nothing to derive), and the
dogfood test no longer pins an issuer -- it pins the account under
`(provider_id, account_id)` and asserts nothing still writes the retired field.
One runner step in the same item told a runner to check `issuer=local:credential`
when provisioning delegate B; it is withdrawn with them.

Each item bumps `revision` and appends a `history` entry, per the checklist's
change lifecycle.

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
@os-try-charles os-try-charles added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 19, 2026 — with Claude
@os-try-charles
os-try-charles marked this pull request as ready for review September 19, 2026 23:44
@os-try-charles
os-try-charles added this pull request to the merge queue Sep 19, 2026
Merged via the queue into main with commit 0046a41 Sep 19, 2026
37 checks passed
@os-try-charles
os-try-charles deleted the claude/issue-17453-approvals-knowngap-citations branch September 19, 2026 23:56
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 28, 2026
…carriers (objectstack-ai#19826)

Fixes objectstack-ai#19217
Clause-②: no

## What changed

Two QA-checklist carriers still required or cited `sys_account.issuer`,
a column that retired with better-auth 1.7.3 (durable record:
`packages/spec/src/migrations/entries/semantic/18.sys-account-issuer-retired.ts`).
Docs/QA only; no code, no published package source.

1. `docs/qa/platform-checklist/areas/identity-auth.json`, item
`identity-auth.linked-accounts-social`: the ORACLE. The step 「issuer
stamped」 and the first acceptance clause's verify 「issuer is stamped」
are both withdrawn. The same shape PR objectstack-ai#19213 used for `approvals.json`:
the reason is kept (the step now says `(provider_id, account_id)` is the
whole account identity and names the retirement's migration entry), and
the verify says an issuer-less row is the healthy shape, never a FAIL.
`revision` 1 -> 2 with an appended `history` entry; revision 1's history
entry is untouched.
2. `docs/qa/platform-checklist/FOLLOW-UPS.md` section 6, the "second
signed-up (non-admin) user in seeds" row: the closing-evidence clause
"issuer derived from the dev admin's own row" is withdrawn. The file's
own rule is append-never-rewrite, so the correction is made visibly in
place (the pattern section 10's E2 row already uses): the row says what
the seed does today (`ensureCredentialAccount` -> better-auth
`internalAdapter.createAccount`, keyed on `(provider_id, account_id)`,
read at `examples/app-showcase/src/security/seed-approval-demo.ts`
`ensureCredentialAccount` and the comment above its call site), and
records that it used to claim an issuer derivation, withdrawn with this
card.

## Premise, re-measured on `c1185240` (branch base)

- `identity-auth.json` step at `:1119` and verify at `:1128` carried the
dead requirement (card said `:1118` / `:1127`).
- `FOLLOW-UPS.md:151` carried the falsified clause.
- The corroboration still holds:
`packages/qa/dogfood/test/showcase-demo-personas-loginable.dogfood.test.ts:133-138`
asserts the admin's account row has NO `issuer` own-property
("sys_account.issuer retired with better-auth 1.7.3 — nothing should
still be writing it"); only its header comment changed.
- Left untouched on purpose, each read: the other `issuer` hits in
`identity-auth.json` are the OIDC discovery-document `issuer` (`:178`,
`:233`, `:235`, `:250`, `:275`) and the TOTP otpauth label `issuer +
account` (`:1287`, `:1302`) — different concepts, correct.
`areas/approvals.json`'s hits are all in `history` entries or
closed-by-fixture `knownGaps` text — the correct steady state, not in
scope. `areas/ai.json:697/719` is the OAuth issuer URL in a boot-log
warning — unrelated.

## Verification (at `f7fb5a98`)

Gate list derived with `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` (13 commands), every one run,
reconciled with `--ran` carrying exit codes: "13 derived famil(ies)
accounted for — 13 run, 0 NOT-MEASURED (a DERIVED zero)".

- `pnpm check:platform-checklist` exit 0: "OK — 15 areas, 265 items ...
symbol anchors: 619/637 resolved ... 17 file floors held".
- Anchor census unchanged by this diff: `areas/identity-auth.json` 83
against floor 82, `FOLLOW-UPS.md` 4 against floor 2. No floor or ledger
moved. (`identity-auth.json` has one anchor of headroom — the new
migration citations are bare paths, which add and remove no anchor.)
- `pnpm check:doc-authoring`, `check:nul-bytes`,
`check:cross-package-test-inputs`, `check:driver-memory-census`,
`check:gitlink-declared`, `check:refd-timer-probe`,
`check:watch-hint-literal`, `check-ci-filter-parity`,
`check-closing-keyword-parity` (+ `--self-test`),
`check-comment-mask-corpus`: all exit 0.
- `@objectstack/lint check:doc-formula-expressions`: first run exit 3
(PREREQUISITE NOT MET — `@objectstack/formula` / `@objectstack/lint`
unbuilt, nothing measured); after `turbo run build` of those two, exit
0.

## Changeset

None. The diff is `docs/qa/**` only and publishes nothing from any
released package, so this is `skip-changeset` territory; the label is
left to the PM seat.

## Acceptance notes

- No out-of-scope findings filed or proposed.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(qa): three approvals-checklist knownGap texts cite the retired backfill-account-issuer.ts

2 participants