Skip to content

docs(plugin-auth): re-measure the three version-stamped vendor attestations outside #10073's two-string scope - #11446

Merged
os-sam merged 3 commits into
mainfrom
claude/issue-10188-plugin-auth-stale-attestations
Aug 23, 2026
Merged

docs(plugin-auth): re-measure the three version-stamped vendor attestations outside #10073's two-string scope#11446
os-sam merged 3 commits into
mainfrom
claude/issue-10188-plugin-auth-stale-attestations

Conversation

@os-sam

Copy link
Copy Markdown
Collaborator

Fixes#10188

Three version-stamped attestations in plugin-auth asserted vendor versions that are no
longer installed. Nothing was broken: all three claims were still true, only their
stamps and line anchors were stale. This re-measures each one against the copy installed
now and records the measurement date, so the next reader inherits a reading rather than an
assertion.

What each site now says, and how it was measured

Every anchor below was re-measured in this worktree, against node_modules as installed
on the current base
— not inherited from the issue body and not inherited from the first
commit on this branch.

1. auth-plugin.ts — the /admin/oauth2/update-client warrant (@better-auth/oauth-provider@1.7.1)

This is the load-bearing one: the comment is the stated warrant for a whole custom route,
and it carries its own retirement trigger ("when upstream adds disabled to
adminUpdateOAuthClient's schema, this route can be deleted"
).

Re-measured: adminUpdateOAuthClient is at dist/authorize-Crqw4_bR.mjs:2860; its body
schema
is the body: z.object({ … }) spanning :2862-2889, and disabled occurs
zero times in that block.

The claim still holds — upstream has NOT added disabled. Verified past the one block,
because that is the reading that would mean deleting a route rather than re-stamping a
comment:

  • the non-admin sibling /oauth2/update-client (:2897-2925) does not accept it either;
  • CIMD_FORBIDDEN_SERVER_FIELD_NAMES (:1117-1118) explicitly forbidsdisabled from
    client-supplied metadata;
  • the one disabled: z.boolean().optional() that does exist in the file (:3371) belongs
    to resourceBodySchema — OAuth resources, a different model, not clients;
  • the update handler sources it from the stored record (disabled: existingClient.disabled,
    :1972), never from the body.

So the route stays warranted and nothing is deleted here.

Resolving the discrepancy the card flagged. The issue body says the schema sits at
:2862-2896; the first commit on this branch says :2862-2889. Measured here: :2862-2889
is correct
for the body schema. :2896 is the closing }); of the entire
createAuthEndpoint(...) call — it includes the metadata block and the handler, which are
not the schema. The narrower range is the accurate one.

One further precision fix, this PR's only change to the inherited text. The reverse
control read "disabled … occurring 35 times elsewhere in the same file". Re-measured, 35
is the count of lines matching disabled (grep -c); the occurrence counts are 38
whole-word and 42 substring. The control now names the measurement it reports
(grep -c), so it is reproducible instead of merely assertive. The control itself is kept
— it is what makes a zero-hit search evidence rather than an assumption.

2 & 3. auth-manager.ts and auth-manager.test.ts — the better-call anchors

The issue body explicitly did not re-measure these; the first commit on this branch
claimed to. Confirmed independently here against installed better-call@1.4.0, because a
line anchor is exactly the claim that decays silently:

  • isAPIError is declared at dist/utils.mjs:55, and the quoted expression
    error instanceof APIError || error?.name === "APIError" is at :56 — so :55-56 is right.
  • It is consumed in the router's catch at dist/router.mjs:92.
  • The console.error + 500 / null body branch is at :93-97 (console.error at :93,
    return new Response(null, { status: 500 … }) at :94-97).

Both anchors and the surrounding prose hold as re-stamped.

Changeset: deliberately skip-changeset, not an oversight

plugin-auth is a published package, so this was a judgement call rather than an automatic
skip. The call is no changeset, because nothing reaches the published artifact:

  • auth-plugin.ts — a // comment inside a class method body;
  • auth-manager.ts — a JSDoc block on smsQuotaExceededApiError, which is module-local
    and not exported
    , so it does not appear in any dist/*.d.ts;
  • auth-manager.test.ts — a test file, not published at all.

No exported symbol's documentation changes, no behaviour changes, no public surface moves,
no accept/reject behaviour changes. A version bump would announce to consumers a release
whose entire content they cannot observe, and would put a line with no consumer meaning into
centrally-compiled release notes. The skip-changeset label is applied on that basis.

Verification

Union derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
and no hand-supplied paths (the script took the change set from git itself: 3 paths vs
merge base 851909530). All runs below are at a3f1ad79f2, on a base merged up to
current main, with exit codes captured before any pipe and heavy work serialized through
scripts/pm/os-verify-lock.sh.

All 9 path-matched families plus the 6 convention-triggered ones ran to a real verdict, all
green:

gateverdict
check:auth-mount-ledger17 rawApp mounts accounted, exact on METHOD path
check:published-files69 publishable packages OK
check:route-envelope10 route modules: 7 conformant, 2 ratcheted, 1 exempt
check:slot-lookupratchet holds, none new
check:test-source-aliasOK — 72 packages scanned
check:type-source-resolutionOK — 77 packages scanned
check-ci-filter-parity.mjsOK — 88 declared globs covered
check-plugin-teardown-shape.mjs63 Plugin implementations, baseline fully burned down
docs-audit/check-affected-docs.mjsself-test 339 cases pass
check:query-options-erasureratchet holds, none new
check:type-check-coverageOK — 65/78 packages type-checked
check:engine-double-contractOK — 386 pinned
check:cross-package-test-inputsOK — 14 packages, all declared
check:where-matcher285 matchers, 0 silently-wrong
check:type-check-debt--re-measure: OK — 33 ledger entries, none above its recorded number

check:type-check-debt first refused (--re-measure cannot run: 30 workspace dependencies … have no built type entry point on disk). That refusal is NOT MEASURED, not a
pass, so the closure was built exactly as lint.yml does
(turbo run build --filter='./packages/*' --filter='./packages/*/*', 70/70 successful) and
the gate re-run to the real green above.

Package verification:

  • pnpm --filter @objectstack/plugin-auth typecheck — exit 0, both tsc programs clean.
  • pnpm --filter @objectstack/plugin-auth test70 test files, 1455 tests passed.

Lint — a declared narrowing, with its evidence. The repo-wide pnpm lint was attempted
under the shared verify lock and never acquired it (VERDICT queue-timeout (exit 99) after
9m00s behind another agent's build) — that is NOT MEASURED and is reported as such, not as a
pass. In its place, the narrowed run and the three facts that make the narrowing a
measurement rather than a gap:

  1. Population from ESLint's own config, not from a guess: pnpm lint is
    eslint . --no-inline-config over the single root eslint.config.mjs, and all three
    changed files return real result objects (no "ignored by pattern" warning), so they are
    inside that population.
  2. Count read from --format json: 3 files linted, 0 errors, 0 warnings.
  3. Invariance for untouched files: this repo "runs one eslint.config.mjs, which never
    enables type-aware linting (no parserOptions.project, no typed @typescript-eslint
    rules) for ANY file" (eslint.config.mjs:326-329, which carries its own positive-control
    measurement). With no cross-file type information in play, a comment-only edit inside
    three files cannot move any verdict on a file it does not touch.

CI runs the full farm regardless, and its conclusion is authoritative over the narrowing.

Scope

Comment text only, in exactly the three files the issue names. No assertion, pin, schema,
route, or gate input is touched. The generalizable "dependency name adjacent to a version
literal" gate the issue sketches is not built here — the issue names that as its own stop
condition, and it stays a separate card.


Generated by Claude Code

…outside #10073's two-string scope
Site 1 (auth-plugin.ts): the better-auth-1.6.11 stamp on the
/admin/oauth2/update-client 'no disabled in the Zod body schema' claim is
re-measured against the installed @better-auth/oauth-provider@1.7.1 —
adminUpdateOAuthClient (dist/authorize-Crqw4_bR.mjs:2860) declares its body
schema at :2862-2889 and 'disabled' occurs zero times in that block (35
elsewhere in the file, so the search reaches the text). The custom route is
still warranted; only the stamp was stale.
Sites 2-3 (auth-manager.ts, auth-manager.test.ts): the better-call@1.3.7
anchors are re-measured against the installed better-call@1.4.0 — isAPIError
now at dist/utils.mjs:55-56, consumed at dist/router.mjs:92, with the
console.error + 500/null-body branch at :93-97. The prose claim holds
unchanged; both anchors had drifted by one line.
Comment-only diff; no assertion, pin, or gate input is touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01APWX2AwT3a4xDcjPCe8bk4
…le line count
Re-measured on the installed @better-auth/oauth-provider@1.7.1: the
adminUpdateOAuthClient body schema at dist/authorize-Crqw4_bR.mjs:2862-2889
still contains zero 'disabled', and the reverse control's '35' is a count of
LINES matching 'disabled' elsewhere in that file (grep -c), not a count of
occurrences (whole-word: 38, substring: 42). Naming the measurement makes the
control reproducible instead of merely assertive.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01APWX2AwT3a4xDcjPCe8bk4
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ✅

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-auth/src/auth-manager.ts) — pages documenting those are invisible to this run
  • the SDK route bridge reached 45 of 222 client-bound route-ledger rows — the other 177 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run: node scripts/docs-audit/affected-docs.mjs --bridge-coverage

Coarse fallback — 11 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 5a916c4d4dc57f09bc4cbd5e7fe33f3545b186c8packageMentionDocs.

Which tree this was computed on

This run read content/docs from f78f9eaa7089836e96a448ec3b50126c99cd1ae3 — the merge of head a3f1ad79f26b11757e0022bea0d730e1e1517d5c into base 5a916c4d4dc57f09bc4cbd5e7fe33f3545b186c8, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin f78f9eaa7089836e96a448ec3b50126c99cd1ae3 && git checkout f78f9eaa7089836e96a448ec3b50126c99cd1ae3
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 5a916c4d4dc57f09bc4cbd5e7fe33f3545b186c8 a3f1ad79f26b11757e0022bea0d730e1e1517d5c && git checkout -B drift-repro 5a916c4d4dc57f09bc4cbd5e7fe33f3545b186c8 && git merge --no-ff a3f1ad79f26b11757e0022bea0d730e1e1517d5c
node scripts/docs-audit/affected-docs.mjs --json 5a916c4d4dc57f09bc4cbd5e7fe33f3545b186c8

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 23, 2026
@os-sam
os-sam marked this pull request as ready for review August 23, 2026 20:05
@os-sam
os-sam added this pull request to the merge queueAug 23, 2026
Merged via the queue into main with commit 001bd81Aug 23, 2026
35 checks passed
@os-sam
os-sam deleted the claude/issue-10188-plugin-auth-stale-attestations branch August 23, 2026 20:22
os-sam pushed a commit that referenced this pull request Aug 23, 2026
…outside #10188's plugin-auth carrier
Both sites stamp the same upstream-gap claim as #10188's plugin-auth site 1 (the
stock /admin/oauth2/update-client endpoint's Zod body schema does not accept
`disabled`). Nothing was broken: both claims are still TRUE, only the stamps
(and, for site 1, the anchor) were stale. Re-measured 2026-08-23 against
installed @better-auth/oauth-provider@1.7.1, independently of #10188/#11446's
own re-measurement.
Fixes#11362
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01APWX2AwT3a4xDcjPCe8bk4
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-sam@claude