Skip to content

docs(qa): classify the manifest capability in the platform-checklist coverage ratchet - #11524

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-11421-classify-manifest-capability
Aug 24, 2026
Merged

docs(qa): classify the manifest capability in the platform-checklist coverage ratchet#11524
os-steve merged 1 commit into
mainfrom
claude/issue-11421-classify-manifest-capability

Conversation

@claude

@claudeclaudeBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Fixes#11421

check:platform-checklist was red on main with exactly one problem:
coverage.json · manifest: UNCLASSIFIED. The manifest liveness ledger
(packages/spec/liveness/manifest.json) landed on 2026-08-23 and the checklist
neither tested nor waived the capability it governs. This is authoring work in
docs/qa/platform-checklist/the gate script is untouched.

The decision this card actually turns on: items, not a waiver

The card asks for "items or a waiver" without saying which, and the honest answer
depends on what the manifest capability is. Read against source rather than
inferred from the name, it is an authored, enforced, user-facing surface, not
an internal ledger:

what a manifest declareswhat enforces it
engines.protocol / engines.platform / engine.objectstackassertProtocolCompat(manifest) runs beforeregistry.installPackage (metadata-protocol/src/protocol.ts:19755) and throws OS_PROTOCOL_INCOMPATIBLE with a migrateCommand
namespaceADR-0048 install-time ownership gate — NamespaceConflictError (objectql/src/registry.ts:3473-3490), shareable namespaces exempt, same-package reinstall excluded
(absent)namespacederived from the package id for runtime-created packages (protocol.ts:19744-19748), so the prefix rule is not silently inert for Studio-authored packages
packaginga real artifact fork in os plugin buildmanifest-deps externalizes declared deps and packs package.json into the archive, bundled inlines them (cli/src/commands/plugin/build.ts:155-166, :202-207)
id / versionrequired by ManifestSchema, re-guarded post-parse in build, and refused server-side as 400 PACKAGE_MANIFEST_INVALID (rest/src/package-routes.ts:532)

A waiver, per the checklist README, "is a debt marker, not an exemption: it names
what fixture or surface is missing". No fixture is missing here — every gate above
is drivable against os dev or a scratch plugin directory today. A waiver would
have been the thin reason the dispatch warned against.

What landed

Two new items, authored verify-first (every clause traced to a file:line before
it was written), plus the coverage mapping.

  • platform-core.manifest-install-contract (P1, api) — the install boundary.
    The handshake refusal and the two reads proving nothing was written; the
    structured diagnostic's fields; protocol-first precedence across all three range
    rungs, with the mixed pair as the load-bearing probe; the two non-determinations
    (no-range, unparsed range) admitting with a warning rather than falsely
    rejecting; the namespace ownership gate on all three legs (conflict, same-package
    reinstall, shareable exemption); namespace derivation read back from storage.
  • cli.plugin-manifest-build-contract (P2, cli) — the packaging boundary.
    Located refusals with no artifact written; the two identity guards as
    different refusals; the packaging artifact fork; the compiled manifest
    (main + integrity) read back out of the archive; the
    protocol/missing-engines-range lint nudge and its manifest scoping.
  • coverage.json maps manifest to both, plus the existing
    api-backend.package-rest-lifecycle — which already drives manifest keys over
    the install door (its 409 "no silent manifest clobber" guard is literally a
    manifest assertion), so the mapping reflects what the checklist really covers
    rather than only what this PR added.

Two sketch claims were corrected against source before they became clauses, and both
corrections are recorded in the items' history: id/version are required by
ManifestSchema (so build's explicit guard is the empty-string arm, not the only
identity check), and the file os plugin build reads is objectstack.plugin.json,
not the objectstack.config.ts the liveness ledger names first.

Two findings recorded as negative, not scored as working

The manifest's declared-but-inert half is on the enforce-or-remove worklist, and an
item that scored either as machinery would be authoring false coverage:

Both are named in the items' negative blocks so a runner cannot tick them.

Verification — and why local runs are the only signal this will ever get

⚠️check:platform-checklist is not CI-wired. Its absence from CI is a recorded
maintainer decision quoted in .github/workflows/lint.yml, and no CI job will
confirm anything below. The same disclosure #10810 and #11508 both carried. This PR
does not change that posture, does not schedule the gate, and does not build a
reporting path — both were fenced on the card.

The gate was already red before this change, so a red-then-green pass/fail proves
nothing. The evidence is a diff of problem lists:

$ diff <(grep '✗' base-gate.txt) <(grep '✗' after-gate.txt)
1d0
< ✗ coverage.json · manifest: UNCLASSIFIED — the platform has this capability
(liveness ledger exists) but the checklist neither tests nor waives it.
Add items or a waiver with a reason.

Exactly one problem removed, none added.

Gate union re-run at the final commit 0315605d, each verdict quoted from the
gate's own printed line:

✓ check-platform-checklist --self-test: 36 assertions — the trap-table extractor reads a good table and REFUSES an empty/renamed/reshaped one; `fixtures.provisioning.use` resolves against its own area and fires on a dangling one.
check-platform-checklist: OK — 15 areas, 207 items (207 active); coverage: 31 kinds mapped, 0 waived; traps: 19 documented, 19 in use; provisioning: 4 area recipes, 6 item references resolved (self-checks: 22 trap-vocabulary + 14 provisioning-resolve assertions).
✓ doc authoring guard: 389 files clean — no bare metadata literals.
✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 420 files / 1449 TS blocks judged clean by @objectstack/formula.
check-nul-bytes: OK (scanned 6455 text file(s) -- 6455 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).

The gate set was derived, not recalled:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack names
check:doc-authoring and check:doc-formula-expressions for this surface; both were
run, alongside the card's own check:platform-checklist family and check:nul-bytes.
Coverage counts re-derived rather than inherited from the card: 31 liveness kinds vs
30 coverage entries before, manifest the only gap, no orphans — the card's
arithmetic still held.

No changeset: this is a docs-only change to an internal QA ledger and releases
nothing (dispatch-gates agrees — "write one unless this card is docs-only").
skip-changeset applied.

Coordination

#11508 is in flight over docs/qa/platform-checklist/README.md,
areas/records-forms.json, areas/search.json and
scripts/check-platform-checklist.mjs. This PR touches none of them — its whole
surface is coverage.json plus the two area files that carry the new items
(platform-core.json, cli.json), and both changes are pure appends.

Generated by Claude Code


Generated by Claude Code

…t coverage ratchet
`check:platform-checklist` was red on `main` with one problem:
`coverage.json · manifest: UNCLASSIFIED`. The manifest liveness ledger
(`packages/spec/liveness/manifest.json`) landed on 2026-08-23 and the
checklist neither tested nor waived the capability it governs.
Classified as ITEMS, not a waiver. Grounding against source shows the
manifest is an authored, enforced, user-facing surface rather than an
internal ledger: an incompatible `engines` range is refused before the
registry write with a structured `OS_PROTOCOL_INCOMPATIBLE` diagnostic
(metadata-protocol/protocol.ts calls assertProtocolCompat ahead of
registry.installPackage), the ADR-0048 namespace gate refuses a package
whose namespace another package owns, a namespace-less runtime package
has one derived from its id, and `os plugin build` forks the artifact on
`packaging` and refuses an invalid manifest with located errors. A waiver
is a debt marker for a missing fixture (README) and no fixture is missing
here.
Two new items, authored verify-first against source:
platform-core.manifest-install-contract (P1, api) — the install
boundary: handshake refusal before the registry write, protocol-first
precedence across all three range rungs, no-range/unparsed-range
admitting with a warning, the three-legged namespace ownership gate,
and namespace derivation.
cli.plugin-manifest-build-contract (P2, cli) — the packaging boundary:
located refusals with no artifact written, the two identity guards
(schema-required id/version vs the empty-string post-parse guard),
the `packaging` artifact fork, the compiled manifest read back out of
the artifact, and the `protocol/missing-engines-range` lint nudge with
its manifest scoping.
`coverage.json` maps `manifest` to both, plus the existing
`api-backend.package-rest-lifecycle`, which already drives manifest keys
over the install door (its 409 "no silent manifest clobber" guard).
Two open enforce-or-remove findings on this surface — the printed-but-
unenforced `runtime` trust tier and the computed-but-unverified
`integrity` map — are recorded in the items' `negative` blocks so a run
cannot score either as working machinery.
Gate script untouched: the fix is data, not code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 24, 2026
@os-steve
os-steve marked this pull request as ready for review August 24, 2026 02:34
@os-steve
os-steve added this pull request to the merge queueAug 24, 2026
Merged via the queue into main with commit cd93277Aug 24, 2026
27 checks passed
@os-steve
os-steve deleted the claude/issue-11421-classify-manifest-capability branch August 24, 2026 02:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check:platform-checklist is red on main (coverage.json · manifest UNCLASSIFIED) and the gate is not CI-wired, so the red has no reporting channel

2 participants

@os-steve@claude