Skip to content

docs(qa): classify the five UNCLASSIFIED capability ledgers — four REST-config kinds authored, realtime_subscription waived - #15541

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-14961-platform-checklist-four-rest-kinds
Sep 4, 2026
Merged

docs(qa): classify the five UNCLASSIFIED capability ledgers — four REST-config kinds authored, realtime_subscription waived#15541
baozhoutao merged 2 commits into
mainfrom
claude/issue-14961-platform-checklist-four-rest-kinds

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #14961

check:platform-checklist was red on main: capability ledgers existed with neither checklist items nor a waiver. Every capability is now classified, and the gate exits 0.

The kind set had moved — five, not four

The card was measured at ca3fd4b1 (2026-09-03) and names four kinds. Re-run on today's origin/main (6f944589, as the card's triage asked), the gate reports five: realtime_subscription was enrolled that same morning by the SubscriptionSchema liveness enrolment. Clearing the four named kinds alone would have left the gate red, so all five are classified here. The drift happened inside the lifetime of the card filed against the red — recorded in FOLLOW-UPS.md §10a as the sharpest available evidence for the standing channel decision card #11730, which this PR does not touch and does not answer.

Before (base 6f944589, exit 1, five findings):

check-platform-checklist: 5 problem(s)
  x coverage.json - batch_endpoints: UNCLASSIFIED
  x coverage.json - crud_endpoints: UNCLASSIFIED
  x coverage.json - metadata_endpoints: UNCLASSIFIED
  x coverage.json - realtime_subscription: UNCLASSIFIED
  x coverage.json - route_generation: UNCLASSIFIED

Per capability: authored or waived, and why

Four of the five ledgers govern RestServerConfig sub-objects — deployment construction arguments, not stored metadata. The checklist already drove the routes; nothing covered the config that decides the routes exist. That is the gap the four new items in areas/api-backend.json fill, authored against packages/rest and packages/spec/src/api/rest-server.zod.ts rather than against the ledgers' prose.

capability verdict what and why
crud_endpoints authored New api-backend.rest-crud-config-contract + the two existing items that drive the mounted data routes. Five live operations.* switches gate six mounts — operations.list also gates POST /:object/query, which has no switch of its own — dataPrefix re-bases the CRUD, data-action, sharing and batch registrars and the /discovery routes.data advertisement together (ADR-0076 D12), and the two #14691 tombstones (patterns, objectParamStyle) refuse at construction.
batch_endpoints authored New api-backend.rest-batch-config-contract + bulk-write-contract + batch-transactional-discovery. Two asymmetries were read out of the registrar rather than assumed: the cross-object POST /batch is not under enableBatchEndpoint (only the per-object door is), and all four bulk gates are ANDs with a protocol member, so a false switch and a missing protocol member look identical from the route table. maxBatchSize is the one cap all five doors measure (400 BATCH_TOO_LARGE). Tombstones: operations.upsertMany, defaultAtomic.
metadata_endpoints authored New api-backend.rest-metadata-config-contract (P1 — it carries the disclosure gate) + platform-core.metadata-registry-serving. prefix moves the surface and its /discovery routes.metadata advertisement; the three endpoint switches gate more than their declared meaning says (endpoints.items also gates /diagnostics, /_drafts and the POST /_migrate-stored write door; endpoints.item also gates the book-tree read); maskObjectFields is the ADR-0106 D8 per-caller field mask, default on, with six carve-outs on the enableCache path. Tombstones: cacheTtl, endpoints.schema.
route_generation authored (not waived) New api-backend.rest-route-generation-tombstones. This is the one kind with no live property left — all four selectors were retired 2026-09-03 under ADR-0049 — and a waiver was still the wrong answer: the sub-object stays declared precisely so an authored key is refused with its prescription instead of silently stripped, and that refusal is shipped behaviour a checklist can drive (constructor, plugin path, and tsc). The item also scores whether each prescription names a replacement that actually exists, and keeps the two controls the retirement must not break (routes: {} still constructs; an unknown key is still stripped).
realtime_subscription waived, reason written out in coverage.json The only capability with nothing to drive, measured rather than asserted. SubscriptionSchema has zero runtime readers — its ledger records every property dead at a same-day census whose method and scope it declares, nothing outside packages/spec imports it, and the shipped in-memory adapter reads RealtimeSubscriptionOptions, a different type. There is also nothing to connect to: /api/v1/discovery advertises realtime enabled: true with status: degraded, handlerReady: false and no realtime route, which is the open decision on #14646 (whether the open framework mounts a transport at all — that card stays open and is not addressed here). An item authored today could only assert absence. The waiver names both of its exits: a mounted transport that parses this schema (author items, flip to items), or ADR-0049 retiring the schema (the ledger goes and the ratchet reports this entry as an ORPHAN to delete).

⚠️ The waiver does not reopen waiver-as-exemption. SWEEP.md records 6 of 6 waivers ever written turning out stale, and every one of those claimed "no independent runtime behaviour" about a surface that had some. This one claims the opposite kind of thing — that the reader is missing — and is grounded in a census plus a discovery reading, not in the schema's own prose. FOLLOW-UPS.md §10d says so, and asks the next sweep to re-audit it like any other waiver.

Sweep honesty

This was a scoped sweep (SWEEP.md permits one for a "does the checklist cover X?" question): angle 3 (routes and runtime) only, against packages/rest, the REST config schema and the five ledgers. ⚠️ It was executed sequentially by one reader — no sub-agent tool in the session — which SWEEP.md allows as a degraded path with a declaration. The authored items stand on their own evidence; this run supports no claim that nothing else is missing in these areas. Declared in FOLLOW-UPS.md §10.

Also in this PR

areas/records-forms.json is untouched (draft PR #15395 owns it this cycle). The one records-forms item this PR needs is referenced by id from coverage.json, which that PR does not edit.

Verification — every verdict line, exit code captured before any pipe

All of it re-run on this branch's head 00b063dcd — the ratchet families (check:platform-checklist, check:nul-bytes) were re-run on the exact tree that commit carries, after the last content edit.

The gate itself

$ node scripts/check-platform-checklist.mjs        # base 6f944589, before the change
EXIT=1
check-platform-checklist: 5 problem(s)             # the five findings quoted above

$ pnpm check:platform-checklist                    # this branch
EXIT=0
check-platform-checklist: OK - 15 areas, 264 items (264 active); coverage: 35 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; source citations: 20 family files carry no `file:line`
pin; symbol anchors: 624/624 resolved against 306 cited sources, 17 file floors held;
(self-checks: 22 trap-vocabulary + 34 provisioning-resolve + 19 unreferenced-recipe +
53 meta-call-spelling + 19 source-line-citation + 29 symbol-anchor assertions).

$ node scripts/check-platform-checklist.mjs --self-test
EXIT=0
check-platform-checklist --self-test: 176 assertions - ...

⚠️ The self-test is 176, not the 141 the card quotes. 141 was ca3fd4b1's count; 176 is what 6f944589 reports, and it is unchanged by this PR — the gate script is not edited here (git diff --stat touches four files, none of them scripts/check-platform-checklist.mjs). Noted in FOLLOW-UPS.md §10e: quote the count from the run you actually made.

$ pnpm check:nul-bytes
EXIT=0
check-nul-bytes: OK (scanned 7518 text file(s) -- 7518 tracked, 0 untracked-not-ignored;
skipped 7 binary; no raw ASCII control bytes).

The runner's selector — the new items resolve by id and, via their source citations, by source file:

$ node scripts/checklist-select.mjs file:packages/rest/src/rest-server.ts
EXIT=0
selector: file:packages/rest/src/rest-server.ts -> 16 runnable item(s)
  ... all four new items listed ...

The derived gate family. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 19 commands for this changeset (check:platform-checklist is not among them — it is not CI-wired, which is #11730's subject). All 19 exit 0 after pnpm install and building the two packages two of them need:

EXIT=0 :: node packages/lint/scripts/check-reference-carrier-shape.mjs
EXIT=0 :: node packages/lint/scripts/check-reference-carrier-shape.mjs --self-test
EXIT=0 :: node scripts/check-ci-filter-parity.mjs
EXIT=0 :: node scripts/check-closing-keyword-parity.mjs
EXIT=0 :: node scripts/check-closing-keyword-parity.mjs --self-test
EXIT=0 :: node scripts/check-comment-mask-corpus.mjs
EXIT=0 :: pnpm --filter @objectstack/lint run check:doc-formula-expressions
EXIT=0 :: pnpm check:agent-test-spelling
EXIT=0 :: pnpm check:bash32-floor
EXIT=0 :: pnpm check:cli-command-ids
EXIT=0 :: pnpm check:cross-package-test-inputs
EXIT=0 :: pnpm check:doc-authoring
EXIT=0 :: pnpm check:driver-memory-census
EXIT=0 :: pnpm check:entry-guard
EXIT=0 :: pnpm check:nul-bytes
EXIT=0 :: pnpm check:parse-guard
EXIT=0 :: pnpm check:pnpm-filter-targets
EXIT=0 :: pnpm check:refd-timer-probe
EXIT=0 :: pnpm check:watch-hint-literal

First pass, 7 of them answered EXIT=3 / ERR_MODULE_NOT_FOUND on a fresh worktree — NOT MEASURED, not findings, exactly as their own text says. All were the missing install; @objectstack/formula and @objectstack/lint additionally needed building (both under the shared verify lock, OS_VERIFY_LOCK_SLOT=issue-14961).

The roster gates the derivation flags as unreadable-from-silence (their allowlists live under scripts/, which one of this diff's paths is in) were run rather than assumed:

EXIT=0 :: node scripts/check-published-list-mirrors.mjs
EXIT=0 :: node scripts/check-published-list-mirrors.mjs --self-test
EXIT=0 :: pnpm check:console-injection
EXIT=0 :: pnpm check:engine-double-contract
EXIT=0 :: pnpm check:i18n-stale-fill
EXIT=1 :: pnpm check:published-readme-exports   <- NOT MEASURED, see below

check:published-readme-exports prints its own verdict: 160 package(s) are not built, so this run measured nothing there — its --self-test is green and it reports zero content findings. Measuring it needs a whole-repo build, and this diff touches no README and no package. Recorded as NOT MEASURED, never as a pass, and left to CI.

Not owed: pnpm lint is not in the derived family for these paths. Two derivation caveats recorded rather than hidden: the tool warns the tree is 3 commits behind origin/main (this branch is based on 6f944589; the two files that moved are unrelated durability gates), and 16 families "apply once this card's changeset exists" — there is deliberately no changeset here.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

…ST-config kinds authored, realtime_subscription waived

`check:platform-checklist` was red on `main`: five capability ledgers had neither
checklist items nor a waiver. The card names four (`batch_endpoints`,
`crud_endpoints`, `metadata_endpoints`, `route_generation`); `realtime_subscription`
was enrolled the morning of dispatch and the gate reports it too, which the card's
triage anticipated by asking for a re-run on today's `origin/main`.

Four new items in `areas/api-backend.json`, authored against the shipped REST surface
rather than the ledgers' prose — each covers the deployment config that decides which
routes exist, not the routes' behaviour (which existing items already drive):

- `rest-crud-config-contract` — five switches gate six mounts (`operations.list`
  also gates `POST /:object/query`), `dataPrefix` moves the routes and the
  `/discovery` advertisement together, both #14691 tombstones refuse at construction.
- `rest-batch-config-contract` — `enableBatchEndpoint` gates only the per-object
  door (the cross-object `POST /batch` is unconditional), each bulk gate is an AND
  with its protocol member, `maxBatchSize` is the one cap all five doors measure.
- `rest-metadata-config-contract` — `prefix` moves the surface and its
  advertisement, the three endpoint switches gate more routes than their declared
  meaning says (`endpoints.items` also gates the `_migrate-stored` write door),
  `maskObjectFields` is the ADR-0106 D8 disclosure gate, six cache carve-outs.
- `rest-route-generation-tombstones` — the one kind with no live property left:
  all four selectors were retired 2026-09-03, and the refusal-with-a-prescription
  IS the shipped behaviour, so it is authored rather than waived.

`realtime_subscription` is waived with the measurement written out: `SubscriptionSchema`
has zero runtime readers (every property `dead` at a same-day census, the shipped
adapter reads `RealtimeSubscriptionOptions` instead), and `/discovery` advertises
realtime with `handlerReady: false` and no route — the open decision on whether a
transport is mounted at all is #14646. The waiver names both of its exits.

`FOLLOW-UPS.md` §10 records what is not a checklist item: the `endpoints.items`
radius, that no shipped boot path authors `RestServerConfig` at all, and that the
mount half of every switch is unpinned. §10 is the first FOLLOW-UPS section to carry
symbol anchors, so the anchor baseline gains a floor for it at the censused count.

Verified: `pnpm check:platform-checklist` exit 0 (35 kinds mapped, 1 waived;
624/624 anchors resolved, 17 file floors held) · `--self-test` 176 assertions exit 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
E1 → #15542 (the `endpoints.items` radius), E2 → #15543 (no boot path authors
`RestServerConfig`), E3 → #15544 (the mount half of every switch is unpinned).
The rows said "filed"; a register that does not carry the reference makes the
next sweep re-derive the finding to discover it already has a card.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@claude

claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

ACCEPT + ruling — PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk.

Reviewed against the three-dot diff origin/main...claude/issue-14961-platform-checklist-four-rest-kinds (merge base 6f9445898, head 00b063dcd): 4 files, +557/−1, matching the PR file list — areas/api-backend.json (four authored items grounded in packages/rest / rest-server.zod.ts, not the ledgers' prose), coverage.json (the five kinds classified: four mapped, realtime_subscription waived with its two exits named), FOLLOW-UPS.md §10 (the sweep declared degraded-but-honest: angle 3, sequential), and an additive floor row in scripts/checklist-symbol-anchor-baseline.json. areas/records-forms.json untouched (draft #15395 owns it). The kind set drifted to FIVE on today's main (realtime_subscription enrolled this morning); clearing four would have left the gate red — right call.

This gate is not CI-wired (#11730), so this seat MEASURED it in a detached worktree at 00b063dcd:

check-platform-checklist: OK — 15 areas, 264 items (264 active); coverage: 35 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
✓ check-platform-checklist --self-test: 176 assertions — the trap-table extractor reads a good table and REFUSES an 

against main's check-platform-checklist: 5 problem(s) (exit 1). Derived family 19/19 green; check:published-readme-exports NOT MEASURED (unbuilt tree), as it should be.

Ruling on the open question: A — keep the waiver. It claims the READER is missing (measured by a census that states its method and scope, plus the /discovery handlerReady:false reading), not "no runtime behaviour" — the claim the six stale waivers made; it is dated, names both exits (a mounted transport, or the ADR-0049 retirement making the entry an orphan) and asks the next sweep to re-audit it. B would put an item in the ledger that exists only to clear the count; C leaves main red for the life of #14646. The three out-of-scope findings (#15542 / #15543 / #15544) land in packages/rest territory and are left for triage to route.

Fixes #14961 closes the card on merge (#15167 already closed as its duplicate; #11730 untouched). Flipping ready and arming auto-merge now.


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review September 4, 2026 20:22
@baozhoutao
baozhoutao enabled auto-merge September 4, 2026 20:22
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 70c9399 Sep 4, 2026
33 of 35 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-14961-platform-checklist-four-rest-kinds branch September 4, 2026 20:57
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/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants