Uh oh!
There was an error while loading. Please reload this page.
docs(qa): classify the manifest capability in the platform-checklist coverage ratchet - #11524
Merged
Merged
Conversation
…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
os-steve
marked this pull request as ready for review
August 24, 2026 02:34
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 24, 2026
This was referenced Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#11421
check:platform-checklistwas red onmainwith exactly one problem:coverage.json · manifest: UNCLASSIFIED. Themanifestliveness ledger(
packages/spec/liveness/manifest.json) landed on 2026-08-23 and the checklistneither 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
manifestcapability is. Read against source rather thaninferred from the name, it is an authored, enforced, user-facing surface, not
an internal ledger:
engines.protocol/engines.platform/engine.objectstackassertProtocolCompat(manifest)runs beforeregistry.installPackage(metadata-protocol/src/protocol.ts:19755) and throwsOS_PROTOCOL_INCOMPATIBLEwith amigrateCommandnamespaceNamespaceConflictError(objectql/src/registry.ts:3473-3490), shareable namespaces exempt, same-package reinstall excludednamespaceprotocol.ts:19744-19748), so the prefix rule is not silently inert for Studio-authored packagespackagingos plugin build—manifest-depsexternalizes declared deps and packspackage.jsoninto the archive,bundledinlines them (cli/src/commands/plugin/build.ts:155-166,:202-207)id/versionManifestSchema, re-guarded post-parse in build, and refused server-side as400 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 devor a scratch plugin directory today. A waiver wouldhave 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 falselyrejecting; 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
packagingartifact fork; the compiled manifest(
main+integrity) read back out of the archive; theprotocol/missing-engines-rangelint nudge and its manifest scoping.coverage.jsonmapsmanifestto both, plus the existingapi-backend.package-rest-lifecycle— which already drives manifest keys overthe 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/versionare required byManifestSchema(so build's explicit guard is the empty-string arm, not the onlyidentity check), and the file
os plugin buildreads isobjectstack.plugin.json,not the
objectstack.config.tsthe liveness ledger names first.Two findings recorded as
negative, not scored as workingThe 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:
runtime(the plugin trust tier) is printed by build and publish anddispatched on nowhere (
manifest.runtime— the ADR-0025 §3.6 plugin trust tier — is read only to be echoed in two CLI lines, andloading's own tombstone tells upgrading authors it is enforced #11330 is open).integrityis computed and written into the compiled manifest, and nothingre-verifies it at unpack (
manifest.integritydeclares per-file artifact digests the spec says the runtime re-verifies at unpack — nothing computes them and nothing checks them #11331 is open).Both are named in the items'
negativeblocks so a runner cannot tick them.Verification — and why local runs are the only signal this will ever get
check:platform-checklistis not CI-wired. Its absence from CI is a recordedmaintainer decision quoted in
.github/workflows/lint.yml, and no CI job willconfirm 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:
Exactly one problem removed, none added.
Gate union re-run at the final commit
0315605d, each verdict quoted from thegate's own printed line:
The gate set was derived, not recalled:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstacknamescheck:doc-authoringandcheck:doc-formula-expressionsfor this surface; both wererun, alongside the card's own
check:platform-checklistfamily andcheck:nul-bytes.Coverage counts re-derived rather than inherited from the card: 31 liveness kinds vs
30 coverage entries before,
manifestthe only gap, no orphans — the card'sarithmetic still held.
No changeset: this is a docs-only change to an internal QA ledger and releases
nothing (
dispatch-gatesagrees — "write one unless this card is docs-only").skip-changesetapplied.Coordination
#11508 is in flight over
docs/qa/platform-checklist/README.md,areas/records-forms.json,areas/search.jsonandscripts/check-platform-checklist.mjs. This PR touches none of them — its wholesurface is
coverage.jsonplus 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