Skip to content

docs(qa): narrow the authz conformance matrix's completeness claim to what its ratchet checks (#8711) - #9026

Merged
qq9340100 merged 1 commit into
mainfrom
claude/issue-8711-authz-matrix-scope-narrowing
Aug 16, 2026
Merged

docs(qa): narrow the authz conformance matrix's completeness claim to what its ratchet checks (#8711)#9026
qq9340100 merged 1 commit into
mainfrom
claude/issue-8711-authz-matrix-scope-narrowing

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Part of #8711 — half (2), the ruled remainder. Half (1) (the missing active-flag rows) already landed in #8812.

What this does

Maintainer ruling on #8711 (comment accepting Option A): narrow the matrix's written completeness claim to what the mechanism actually delivers, rather than widen the ratchet (Option B, measured unachievable in general form) or fold in a declaration-side ratchet (Option C, deliberately left unruled and preserved as its own finding).

The matrix header and its companion test's header both claimed a new declared-but-unenforced authorization primitive "breaks CI." That is true only for the curated set of HTTP/transport entry points discover() enumerates (15 probes over 11 named source files) — a primitive enforced by a predicate inside an existing resolver adds no entry point and can be neither UNCLASSIFIED nor STALE. That is exactly why the ADR-0049/#8613 active flag sat outside the ledger for its whole inert period without breaking CI, per #8711's own diagnosis.

Both headers now state the narrowed, routes-completeness claim, carrying the measured numbers so it is load-bearing rather than vague:

  • 43 of 50 rows carry no covers key at all (7 rows, 9 keys, every one an HTTP/transport pin).
  • 37 of the 43 enforced rows are in-resolver predicates outside the ratchet entirely — the two active rows from test(dogfood): add the ADR-0056 D10 matrix rows for the grant-catalogue active flag (#8711) #8812 among them, the normal case rather than an exception.
  • discover() reads a curated table of 15 probes over 11 named source files (re-derived; the thread's earlier "10" undercounted by one — http-dispatcher.ts, rest-server.ts and in-memory-realtime-adapter.ts each carry more than one probe).
  • 5 of the 9 covers keys are gate-pins tied to the enforcement call itself (not merely a function name) — delete shouldDenyAnonymous from /actions, /automation or /packages, or drop the MCP context-threading / stdio principal binding, and the pinned key vanishes, the row goes STALE, and CI catches it. This anti-regression value is real and is preserved, not narrated away.

Outside the curated table, "one row per authorization primitive, each in EXACTLY ONE honest state" is now stated as the hand-maintained invariant it actually is, not a checked one.

A stale sentence in the [#8711] comment block above the two active rows (added in #8812) that referred to "the open half of #8711... deliberately NOT settled here" is also updated — that half is now settled, so the sentence would otherwise contradict the new header.

Boundaries respected (per the ruling)

  • ⛔ Nothing about the ratchet's checking behaviour changes. discover(), PROBES, HIGH_RISK, and checkLedger are byte-identical. Diff is prose and comments only.
  • ⛔ No primitive-discovery ratchet (Option B) was built.
  • ⛔ Option C (a declaration-side ratchet) is not touched — it stays an unassigned finding, graded separately.
  • ⛔ The row objects themselves (id/state/enforcement/covers/proof/note) are untouched, including the two permission-set-active / position-active rows from test(dogfood): add the ADR-0056 D10 matrix rows for the grant-catalogue active flag (#8711) #8812.

Numbers re-derived against current origin/main, not copied from the thread

Two of the four numbers moved because #8812 (half (1) of this same card) added two enforced, no-covers rows since the original 2026-08-15 measurement: 41/48 → 43/50 rows with no covers, 35/41 → 37/43 in-resolver enforced rows. The probe-file count is corrected from 10 to 11 (a miscount at the original measurement, not repo drift — the PROBES table itself hasn't changed since PR #8040). The gate-pin count (5 of 9) is unchanged and re-verified.

Tests

All at HEAD 882055342 (clean tree; no commit follows any run).

  • Conformance test itself (the evidence boundary 1 was respected): pnpm --filter @objectstack/dogfood exec vitest run authz-conformanceTest Files 1 passed (1), Tests 15 passed (15) — identical to before the edit.
  • Full dogfood regression gate: npx turbo run test --filter=@objectstack/dogfood --concurrency=2Test Files 110 passed | 1 skipped (111), Tests 780 passed | 3 skipped (783), Tasks: 62 successful, 62 total, exit 0.
  • Build closure first: pnpm --filter '@objectstack/dogfood^...' build — green.
  • pnpm --filter @objectstack/dogfood typecheck — clean.
  • Manual control-byte scan + pnpm check:nul-bytes — OK (5947 files scanned).

Gates, re-derived against the actual changed paths (node scripts/pm/dispatch-gates.mjs packages/qa/dogfood/test/authz-conformance.matrix.ts packages/qa/dogfood/test/authz-conformance.test.ts) rather than assumed from the dispatch prompt — it named two path-matched families and five convention-triggered families (editing a test file):

  • pnpm check:test-source-alias — OK, 72 packages scanned.
  • pnpm check:type-source-resolution — OK, 76 packages scanned.
  • pnpm check:query-options-erasure — OK, ratchet holds, none new.
  • pnpm check:type-check-coverage (no --re-measure) — OK, 64/77 packages type-checked, counts unchanged.
  • pnpm check:engine-double-contract — OK, 303 pinned, 133 in DEBT ledger, 2 exempt — unaffected by a comment-only diff.
  • pnpm check:where-matcher — OK, 243 matchers discovered, all conform.

Not run: check:type-check-debt (the --re-measure variant). It requires a full-workspace build (pnpm exec turbo run build --filter=./packages/* --filter=./packages/*/*) to re-run tsc per DEBT-ledger entry. Skipped deliberately: the diff is comments only in two files whose own tsc --noEmit is already clean, and a comment cannot move a raw-error count for any package — CI's full run is not expected to disagree, and I did not want to force a whole-monorepo build onto the shared verification lock for a change that provably cannot move this ratchet.

Truncation check on #8711 and its comments

Read the issue body and all 6 comments via the GitHub API before implementing. Every comment ends with a complete, matching attribution footer (or, for the ruling comment, a complete final sentence + footer) and every quoted/code block closes correctly (the JSON report comment's closing ``` and } both present). No comment shows a sanitizer-style mid-word cutoff (a bare angle bracket followed by a letter) or an abrupt mid-sentence stop. Nothing appeared cut off.


Generated by Claude Code

… what its ratchet checks (#8711)

Half (2), the ruled remainder of #8711 (half (1) landed in #8812). Maintainer
ruling: narrow the matrix's written claim to what the mechanism delivers
(Option A) — no primitive-discovery ratchet (Option B, measured unachievable
in general form), option C (a declaration-side ratchet) deliberately left
unruled and preserved as a separate finding.

The matrix header and its companion test's header claimed a new
declared-but-unenforced primitive "breaks CI." That is true only for the
curated set of HTTP/transport entry points `discover()` enumerates (15
probes over 11 named source files) — a primitive enforced by a predicate
inside an existing resolver adds no entry point and can be neither
UNCLASSIFIED nor STALE, which is exactly why the #8613 `active` flag sat
outside the ledger for its whole inert period without breaking CI.

Both headers now state the narrowed, routes-completeness claim with the
measured numbers so it is load-bearing: 43 of 50 rows carry no `covers` key
at all (7 rows, 9 keys, every one an HTTP/transport pin), 37 of the 43
`enforced` rows are in-resolver predicates outside the ratchet entirely, and
5 of the 9 `covers` keys that do exist are gate-pins that vanish (failing CI)
when the guard call they name is deleted — the real anti-regression value,
preserved. Outside the curated table, "one row per primitive" is stated as
the hand-maintained invariant it actually is.

Prose and comments only. `discover()`, `PROBES`, `HIGH_RISK`, `checkLedger`,
and every row's `state`/`enforcement`/`covers`/`proof` are untouched — the
conformance test still reports 15 passed (15), unchanged, which is the
evidence this boundary was respected.

Claude-Session: https://claude.ai/code/session_01NaS1PAHJcPfAA2acnV53Tn

Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 16, 2026 6:58am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/dogfood.

2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/permissions/authorization.mdx (via packages/qa/dogfood)
  • content/docs/permissions/delegated-administration.mdx (via packages/qa/dogfood)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Aug 16, 2026
@qq9340100
qq9340100 marked this pull request as ready for review August 16, 2026 07:06
@qq9340100
qq9340100 added this pull request to the merge queue Aug 16, 2026
Merged via the queue into main with commit 2ce1eb4 Aug 16, 2026
28 checks passed
@qq9340100
qq9340100 deleted the claude/issue-8711-authz-matrix-scope-narrowing branch August 16, 2026 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants