Skip to content

Commit 56b0a58

Browse files
test(dogfood): re-measure the authz census for the approval record-lock read (#26406)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} --> _Requested by **Yibo Wang** · [project thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBRzZP1k46z6vHf1CGVyw2uH)_ Fixes #26400 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:只改 dogfood 的两个 authz 普查测试文件里的计数与说明文字,记下 #26361 新增的审批记录锁读取路由(81 行台账、rest-server 行 70 / 19 / 51、总盲点 65 / 70)。 - 为什么改:#26361 加了一条路由但没同步普查,`main` 的 Dogfood Regression Gate (1/3) 和 (3/3) 从那以后一直红,发版闸门读的正是这两条。 - 风险与回滚:只动测试文件,不动任何发布包和路由代码;回滚即 revert 本 PR,`main` 会回到红。 - 先看:`packages/qa/dogfood/test/authz-probe-blind-spot.census.ts` 的 rest-server.ts 行(新盲点 50 → 51 的判定),其次台账行,再看 `authz-conformance.matrix.ts` 第 27 行。 - 两分钟验证:`pnpm --filter @objectstack/dogfood exec vitest run test/authz-probe-blind-spot.test.ts test/authz-conformance.test.ts`,预期 2 个文件、108 个测试全绿(`main` 上是 10 个红)。 - 需要你做的:无,席位落地。 ## What changes Census bookkeeping for the route #26361 added, `GET {basePath}/approvals/records/:object/:recordId/lock` in `packages/rest/src/approvals-routes.ts`. Each figure below was measured with `deriveProbeFileCensus()` on this tree, not copied from the card or from the server seat's reading (6431978738). The reading agreed with the server seat on every figure it gave. | Row / figure | Before | After | Why | |---|---|---|---| | `rest-route-ledger.ts` population / reachable / blindSpot | 80 / 80 / 0 | 81 / 81 / 0 | one new ledger row carrying `family: 'approvals'`, a family the other approval rows already carry | | `rest-route-ledger.ts` `keys` | 18 | 18 | no new family, so no new key | | `rest-route-ledger.ts` controls `route: '` / `family: '` | 80 / 80 | 81 / 81 | the same row | | `rest-server.ts` population / reachable / blindSpot | 69 / 19 / 50 | 70 / 19 / 51 | **a new blind spot**: one direct `this.routeManager.register(` site in `registerApprovalsEndpoints`, outside `registerMetadataEndpoints` and the `/meta` subset, the same as its seven siblings | | `rest-server.ts` controls `this.routeManager.register(` / `approvals-routes.ts: …` / `enforceAuth` | 62 / 7 / 115 | 63 / 8 / 116 | the new site, and its handler opens with `this.enforceAuth(…)` (the only `enforceAuth` line #26361 added) | | `BLIND_SPOT_TOTAL_STATIC` / `_RUNTIME` | 64 / 69 | 65 / 70 | one call site and one runtime mount; it is a direct registration, not a route factory, so the 5-mount static/runtime delta holds | | `authz-conformance.matrix.ts` docblock (the figure #17111 parses) | 80 rows / 18 families | 81 rows / 18 families | plus a line in the dated drift note | Every edited figure has a provenance comment in the row, in the shape the earlier re-measurements use. ## Why `Dogfood Regression Gate (1/3)` and `(3/3)` have been red on every `main` push run that runs them since #26361 (`6a2866af`). This is the main-red stop-bleed under convention ①. It moves the census forward and does not revert #26361. ## Tests Both files, under the verify lock, on `1cc4fa20`: <details><summary>before (origin/main b33dd25): 2 files failed, 10 tests failed, 98 passed</summary> ``` Test Files 2 failed (2) Tests 10 failed | 98 passed (108) os-verify-lock: VERDICT command-exit 1 AssertionError: expected 81 to be 80 (rest-route-ledger.ts population) AssertionError: expected 70 to be 69 (rest-server.ts population) control "route: '" moved in packages/rest/src/rest-route-ledger.ts: expected 81 to be 80 control "this.routeManager.register(" moved in packages/rest/src/rest-server.ts: expected 63 to be 62 "packages/rest/src/rest-route-ledger.ts: docblock says 80 rows, the table holds 81" (#17111 pin and its 5 doctoring cases) ``` </details> <details><summary>after (1cc4fa2): 2 files passed, 108 tests passed</summary> ``` Test Files 2 passed (2) Tests 108 passed (108) os-verify-lock: VERDICT command-exit 0 · held the lock 21s ``` </details> ## Acceptance notes - The order named a docblock figure in `packages/rest/src/rest-route-ledger.ts`. The figure the #17111 pin reads is in `authz-conformance.matrix.ts` line 27, so that is the one that moved. No `packages/rest/**` file changes, as the claim requires. - Shards 1/3 and 3/3 were not run whole locally: the title carries no `!` and no `(narrowing)` arm, so the full battery is not owed. The two files above hold all 10 failures. The card's acceptance (the first `main` push run and the next scheduled run green) can only be read after landing. - The census pins still sit outside PR and merge-queue CI, which is how #26361 merged green. Seat 1 answered that question on the card (6432031749). It is not in this PR. ## Verification Local derived gate set (`dispatch-gates.mjs` on `1cc4fa20`, 50 families): 48 exit 0, 2 NOT MEASURED, 0 red. <details><summary>NOT MEASURED (exit 3, prerequisite not met in this container)</summary> - `node scripts/check-plugin-teardown-shape.mjs --self-test`: its positive control is pinned to a commit that this shallow clone cannot reach. - `pnpm check:dual-build-cjs-loads`: it reads built output, and seven packages outside this diff have no `dist/`. Both run in CI's `Lint & Repo Gates`. `--ran` reconciliation: `50 derived famil(ies) accounted for — 48 run, 2 NOT-MEASURED`. </details> ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (not touched) - [x] 2. Every name I added uses the casing for its kind. (no names added) - [x] 3. No formatter ran; `pnpm lint` passes. (CI-owned) - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset. (`@objectstack/dogfood` is private, test files only: `skip-changeset`) - [x] 6. `packages/spec` touched: n/a. - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English, except the 维护者速读 block. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Generated by [Claude Code](https://claude.ai/code/session_01WGufzfNhdx3xRKeaa8e7JB)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent dada291 commit 56b0a58

2 files changed

Lines changed: 37 additions & 14 deletions

File tree

‎packages/qa/dogfood/test/authz-conformance.matrix.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// hand-curated regex table reaching 1 of 17 REST registrars and 4 of 17
2525
// dispatcher domain files.
2626
//
27-
// The population comes from `packages/rest/src/rest-route-ledger.ts` (80 rows
27+
// The population comes from `packages/rest/src/rest-route-ledger.ts` (81 rows
2828
// / 18 families) and `packages/runtime/src/route-ledger.ts` (105 rows / 23
2929
// domains) because those two are enumerated from a RUNNING server and guarded
3030
// in both directions by their own conformance tests — so a new family or
@@ -58,7 +58,9 @@
5858
// `family: packages`, which survives on the publish row. (91 → 83 rows and
5959
// 19 → 18 families later, when #20102 retired the whole `reports` family;
6060
// 81 → 80 rows, families unmoved, when #25104 retired the `/docs` viewer
61-
// page, whose `openapi` family survives on the document row.)
61+
// page, whose `openapi` family survives on the document row; 80 → 81 rows,
62+
// families unmoved, when #26361 added the approval record-lock read, whose
63+
// `approvals` family the other approval rows already carry.)
6264
// Two stale figures in
6365
// one docblock with two entirely different causes is the failure mode the pin
6466
// above ends. Widening a regex instead was refused: it rots on the next

‎packages/qa/dogfood/test/authz-probe-blind-spot.census.ts‎

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,17 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
386386
// viewer page row (`GET /api/v1/docs`) left the ledger with its route. It
387387
// carried `family: 'openapi'`, which the surviving document row still
388388
// carries, so `reachable` moves with `population` and `keys` stays 18.
389-
population: 80,
390-
reachable: 80,
389+
// [#26400] 80 / 80 / 0 -> 81 / 81 / 0: the approval record-lock read
390+
// (`GET /api/v1/approvals/records/:object/:recordId/lock`, landed in
391+
// #26361) joined the ledger with its route. It carries `family:
392+
// 'approvals'`, a family the other approval rows already carry, so
393+
// `reachable` moves with `population`, the blind spot stays 0 and `keys`
394+
// stays 18 (18 distinct families before and after, re-derived).
395+
population: 81,
396+
reachable: 81,
391397
blindSpot: 0,
392398
populationRule: 'ledger rows inside REST_ROUTE_LEDGER; reachable = rows carrying a `family` (each distinct value mints a key)',
393-
controls: { "route: '": 80, "family: '": 80, RestRouteLedgerEntry: 2 },
399+
controls: { "route: '": 81, "family: '": 81, RestRouteLedgerEntry: 2 },
394400
// [#22430] The `openapi` family is the second classified one, by the
395401
// `anonymous-deny-api-description` row; the note's 2 / 16 counts it.
396402
// [ADR-0138 E2] The `forms` family is the third, by the D2 class 1 row
@@ -401,7 +407,9 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
401407
'That guard is why this file can be a population source and a regex table cannot: a mounted route with no ' +
402408
'row here is already RED in another package, so a new family cannot be silently absent from this file, ' +
403409
'and therefore cannot be silently absent from the authz ratchet either. 18 families; 3 classified by ' +
404-
'matrix rows (metadata, openapi and forms), 15 enumerated in the shrink-only baseline. Re-measured 81 -> 80 when the ' +
410+
'matrix rows (metadata, openapi and forms), 15 enumerated in the shrink-only baseline. Re-measured 80 -> 81 when the ' +
411+
'approval record-lock read joined with its route; it carries `family: approvals`, which the other approval rows ' +
412+
'already carry. Earlier re-measured 81 -> 80 when the ' +
405413
'OpenAPI document viewer page row left with its route; it carried `family: openapi`, which the surviving document row ' +
406414
'still carries. Earlier re-measured 82 -> 81 when the permission-set ' +
407415
'overlay-discard row left with its route; it carried `family: security`, which the surviving security rows still carry. ' +
@@ -535,9 +543,9 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
535543
kinds: ['ROUTE_ENUMERATION', 'TRIPWIRE'],
536544
probes: 3,
537545
keys: 1,
538-
population: 69,
546+
population: 70,
539547
reachable: 19,
540-
blindSpot: 50,
548+
blindSpot: 51,
541549
populationRule:
542550
'route registration sites — `this.routeManager.register(` call sites, LESS the one inside ' +
543551
'`registerPerItemRoute` (the shared forwarder, not a route; its extent is bounded by the declaration\'s own ' +
@@ -952,13 +960,22 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
952960
// (`:2545`) and the two inline comments on the internal context keys in
953961
// `computeExecCtx` (`:3444`, `:3454`). `enforceAuth`'s own body gained a
954962
// comparison in lines that do not spell the term.
963+
// [#26400] 69 / 19 / 50 -> 70 / 19 / 51, and `enforceAuth` 115 -> 116: the
964+
// approval record-lock read (`GET {basePath}/approvals/records/:object/
965+
// :recordId/lock`, landed in #26361) is one new direct
966+
// `this.routeManager.register(` site (62 -> 63; 7 -> 8 in
967+
// `approvals-routes.ts`) inside `registerApprovalsEndpoints`, NOT inside
968+
// `registerMetadataEndpoints`, so it is a NEW BLIND SPOT, the same as its
969+
// seven siblings; its handler opens with `enforceAuth`, so that control
970+
// gains one. No registrar was added, so `private register*Endpoints(`
971+
// stays 16 and the registrar list stays 18.
955972
controls: {
956973
'private register*Endpoints(': 16,
957-
'this.routeManager.register(': 62,
974+
'this.routeManager.register(': 63,
958975
'registrar list length': 18,
959976
'data-action-routes.ts: this.routeManager.register(': 9,
960977
'batch-routes.ts: this.routeManager.register(': 5,
961-
'approvals-routes.ts: this.routeManager.register(': 7,
978+
'approvals-routes.ts: this.routeManager.register(': 8,
962979
'sharing-routes.ts: this.routeManager.register(': 8,
963980
'analytics-routes.ts: this.routeManager.register(': 1,
964981
'security-routes.ts: this.routeManager.register(': 6,
@@ -991,7 +1008,7 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
9911008
'registerPerItemRoute(': 8,
9921009
'const registerPerItemRoute =': 1,
9931010
'forwarder slice: this.routeManager.register(': 1,
994-
enforceAuth: 115,
1011+
enforceAuth: 116,
9951012
},
9961013
note:
9971014
'The single non-tripwire probe names ONE registrar of 16. The other 15 can never mint a key: ' +
@@ -1276,7 +1293,7 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
12761293
/**
12771294
* Entry points inside the probe table's OWN files that no mintable key can
12781295
* reach, counting only the route/handler surfaces the ratchet's completeness
1279-
* claim is about: rest-server.ts (50 static / 55 runtime), http-dispatcher.ts
1296+
* claim is about: rest-server.ts (51 static / 56 runtime), http-dispatcher.ts
12801297
* (13) and domains/mcp.ts (1).
12811298
*
12821299
* hono-plugin.ts's 6 mounts are deliberately EXCLUDED from this total and
@@ -1294,8 +1311,12 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
12941311
// [#25104] 65 / 70 -> 64 / 69: the retired `/docs` viewer page left
12951312
// `discovery-routes.ts` (on rest-server.ts's registrar list) as one blind-spot
12961313
// call site and one runtime mount.
1297-
export const BLIND_SPOT_TOTAL_STATIC = 64;
1298-
export const BLIND_SPOT_TOTAL_RUNTIME = 69;
1314+
// [#26400] 64 / 69 -> 65 / 70: the approval record-lock read joined
1315+
// `approvals-routes.ts` (on rest-server.ts's registrar list) as one blind-spot
1316+
// call site and one runtime mount (one ledger row, 80 -> 81: a direct
1317+
// registration, not a route factory, so static and runtime move together).
1318+
export const BLIND_SPOT_TOTAL_STATIC = 65;
1319+
export const BLIND_SPOT_TOTAL_RUNTIME = 70;
12991320

13001321
/**
13011322
* Re-measure every row above from the same sources the probes read.

0 commit comments

Comments
 (0)