Skip to content

proof-carrying-adaptive-packs-2026-07-13 M0: Conformance manifest format (pack.conformance.v1) - #767

Merged
CueCrux-Myles merged 1 commit into
mainfrom
feat/adaptive-packs-m0-conformance-manifest
Aug 25, 2026
Merged

proof-carrying-adaptive-packs-2026-07-13 M0: Conformance manifest format (pack.conformance.v1)#767
CueCrux-Myles merged 1 commit into
mainfrom
feat/adaptive-packs-m0-conformance-manifest

Conversation

@CueCrux-Myles

Copy link
Copy Markdown
Contributor

What

M0 of ExecPlan proof-carrying-adaptive-packs-2026-07-13. Adds pack.conformance.v1 — the signed block a memory pack uses to declare what it does, so a replay against a local shadow corpus can later prove whether it did that.

The block is an optional conformance field on crux.integration.v1, valid only for the kinds that execute (external_tool, wasm), and declares six things:

Field What it pins down
claimed_capabilities Must equal the manifest's declared capability set
expected_mutations Fact writes (entity prefix, keys, operation, privacy, per-call bound) and receipt emissions
replay_corpus Named, SHA-256 content-addressed corpus + the declared operations
invariants Closed set a harness can evaluate — no prose escape hatch
envelope Integer bounds on token cost, latency, response size, fact writes, decay, contradiction rate (ppm), undo
compatibility Min daemon version, manifest schema, superseded versions, migrations, rollback safety

Three decisions worth reviewing

The declaration is inside the signature. It is appended to ManifestSigningPayload, so widening an envelope after signing invalidates the signature and changes hashes.manifest. A promise an attacker can edit after signing is not evidence. It is skip_serializing_if = "Option::is_none", so every manifest signed before the block existed produces byte-identical payloads and keeps its hash and signature — a_manifest_without_a_declaration_hashes_exactly_as_before pins that, and the untouched studio-board-example still validates against its committed hash.

Every bound is an integer. Rates are parts-per-million, costs are whole units. JSON has no canonical form for a float, so a f64 bound would make a signature depend on which serialiser wrote it.

invariants[].kind and receipts[].receipt_kind are closed enums, and facts[].operation has no delete. A declared property no harness can evaluate is an unverifiable claim inside a proof-carrying format; and the store is append-only, so delete would name an operation the substrate cannot perform.

The schema is MIT

docs/spec/pack.conformance.v1.schema.json carries its own SPDX-License-Identifier: MIT and license object; the full notice is reproduced in docs/spec/pack-conformance-v1.md. The format is meant to be copied by a registry, linter, or SDK; the daemon that enforces it stays Apache-2.0.

The document is generated by conformance::json_schema() and a test asserts the committed file is byte-equal, so schema and Rust types cannot drift — the failure mode where an implementer validates green and is then rejected by the daemon. Independently verified against python3 jsonschema 4.10.3: Draft202012Validator.check_schema passes, the reference block validates, and the five malformations the Rust tests exercise are each rejected.

Reference pack

integrations/community/ext.conformance.reference/0.2.0/ — an external_tool pack with two tools, a three-case content-addressed corpus, five invariants, a full envelope, and a supersede_facts migration from 0.1.0. Generated and signed from a fixed documented example seed (same pattern as studio-board-example); its endpoint is reference.pack.invalid (RFC 2606) so copying it cannot point a reader's daemon at anything real. It is picked up automatically by the existing community_pack_manifests_are_safe_and_reviewable CI gate.

Daemon wiring (M5 seam consumed, not reinvented)

  • pack_conformance::cases_from_manifest now replays a declaring pack's own signed corpus instead of the one-empty-args-case-per-tool floor — the seam's own doc comment said "the M0 manifest block plugs in exactly here". The floor is unchanged for packs without a block.
  • New corpus_id_from_manifest; POST /v1/extensions/{id}/conformance defaults corpus_id to the declared one. Purely additive — the body field becomes #[serde(default)], and an unnamed corpus with no declaration still 422s exactly as before.
  • MAX_DECLARED_CASES is pinned equal to MAX_CASES_PER_RUN by a test, so a manifest can never declare a corpus the hook would refuse to run.

The hook still reports evidence and never a verdict; comparing observed behaviour against this envelope is M1, signing the verdict is M2.

Gate

schema validates; a reference pack ships a conformance manifest that the daemon parses and signature-checks

Tests named after the gate's claims:

  • published_schema_document_matches_the_generator, published_schema_document_is_a_well_formed_json_schema (every $ref resolves, no unreachable $defs), published_schema_document_carries_the_mit_notice, published_schema_document_uses_only_supported_keywords
  • schema_accepts_a_valid_conformance_block, schema_accepts_the_reference_packs_conformance_block, schema_rejects_a_block_that_the_rust_validator_also_rejects
  • reference_pack_ships_a_conformance_manifest_the_daemon_parses, reference_pack_conformance_manifest_signature_checks, reference_pack_conformance_block_is_covered_by_the_signature (widen one bound → SignatureInvalid / ManifestHashMismatch), reference_pack_replay_corpus_is_content_addressed
  • Daemon side: daemon_parses_and_signature_checks_the_reference_pack, a_declared_corpus_supplies_the_cases, the_declared_corpus_passes_precheck, declared_case_cap_matches_the_run_cap
  • 26 unit tests in conformance.rs covering every cross-field rule

cargo test --workspace green; clippy --workspace -D warnings, cargo fmt --check, typos, check-licence-headers.sh, check-agent-docs.sh, unwrap-ratchet.sh, and RUSTDOCFLAGS=-D warnings cargo doc all clean. sha2 added as a dev-dependency only — it was already in Cargo.lock, no new transitive deps.

Docs

New docs/spec/pack-conformance-v1.md; developer guide §2.2, §2.4 and §4.2 updated (the "what is signed" lists were about to become wrong).

🤖 Generated with Claude Code

…mat (pack.conformance.v1)

Adds the block a memory pack uses to declare what it does, so a replay can
later prove whether it did that — claimed capabilities, expected fact and
receipt mutations, a content-addressed replay-corpus reference, invariant
tests, a behavioural envelope (token cost, latency, decay, contradiction rate,
undo), and compatibility + migration assertions.

The declaration sits INSIDE ManifestSigningPayload, not beside it: a promise an
attacker can edit after signing is not evidence. It is skipped when absent, so
every manifest signed before the block existed produces byte-identical payloads
and keeps its hash and signature.

Two design rules the format is built on. Every bound is an integer, because
JSON has no canonical form for a float and the block is signed. `invariants[].kind`
and `receipts[].receipt_kind` are closed sets with no custom escape hatch,
because a declared property no harness can evaluate is an unverifiable claim
inside a proof-carrying format.

The published schema (docs/spec/pack.conformance.v1.schema.json) is MIT so the
format can be implemented and vendored freely; it is generated by
conformance::json_schema and a test asserts the committed file is byte-equal,
so schema and types cannot drift.

Daemon wiring: pack_conformance::cases_from_manifest now replays a declaring
pack's own signed corpus instead of the one-empty-args-case-per-tool floor, and
POST /v1/extensions/{id}/conformance defaults corpus_id to the declared
replay_corpus.corpus_id.

Gate: schema validates; a reference pack ships a conformance manifest that the
daemon parses and signature-checks — verified by
published_schema_document_matches_the_generator,
published_schema_document_is_a_well_formed_json_schema,
schema_accepts_the_reference_packs_conformance_block,
schema_rejects_a_block_that_the_rust_validator_also_rejects,
reference_pack_ships_a_conformance_manifest_the_daemon_parses,
reference_pack_conformance_manifest_signature_checks,
reference_pack_conformance_block_is_covered_by_the_signature,
reference_pack_replay_corpus_is_content_addressed, and (daemon side)
daemon_parses_and_signature_checks_the_reference_pack,
a_declared_corpus_supplies_the_cases, the_declared_corpus_passes_precheck,
declared_case_cap_matches_the_run_cap. cargo test --workspace green; clippy
--workspace -D warnings, fmt, typos, licence headers, check-agent-docs, and
rustdoc -D warnings all clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@CueCrux-Myles
CueCrux-Myles added this pull request to the merge queue Aug 25, 2026
Merged via the queue into main with commit b10fa06 Aug 25, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant