Skip to content

feat(conformance): add declarative conformance runner (022)#362

Merged
pofallon merged 2 commits into
mainfrom
022-conformance-runner
Jul 24, 2026
Merged

feat(conformance): add declarative conformance runner (022)#362
pofallon merged 2 commits into
mainfrom
022-conformance-runner

Conversation

@pofallon

Copy link
Copy Markdown
Contributor

Declarative conformance runner (022)

Implements the 022-conformance-runner spec: conformance cases become data a shared runner executes, not pointers to hand-written Rust tests. Adding a case/assertion/fixture is a pure data edit — no new Rust function (SC-001).

What's included

  • Declarative case shape in conformance/registry/cases.json — ordered operations[], oracleType, per-channel expected[], scoped allowedDifferences[], fsAllowlist, cleanup, resourceGroup. A record is exactly one of legacy (binary-backed) or declarative, enforced fail-loud at load.
  • Four oracle types (oracle_type.rs, one explicit dispatch): spec-expectation, live-differential (deacon vs the pinned oracle), snapshot (vs a committed provenance-checked snapshot), invariant-metamorphic (relationship across ≥2 ops).
  • Observable channels + observers (observe/): CLI-process (exit/stdout/stderr/structured-output), allowlist-scoped filesystem/file-content, and the four Docker channels (image/process-graph/injected-process/temporal). Evidence captured raw then normalized by the single normalize.rs; raw + normalized persisted separately.
  • Docker cases run in an isolated external temp workspace with RAII cleanup (reclaims container/network/volume/temp-dir on success and unwind).
  • Committed snapshots under conformance/snapshots/<os-arch>/<case-id>/ with 13-field provenance + staleness gating; a reviewed conformance-snapshot refresh bin is the only writer.
  • Scoped allowed differences(behavior, context, observablePath) + exactly one resolvable waiverId/divergenceId; no global ignore lists; self-invalidating when stale.
  • New validation classes V16–V20 (validate.rs), all block a PR via registry_valid; certify surfaces snapshot coverage as non-blocking info.
  • New live binary parity_conformance_runner (parity profile only), registered in the parity registry + wired into all nextest profiles.

Review fixes folded in (from /code-review xhigh)

  • Snapshot staleness no longer gates on host tool versions (node/docker/compose). They are informational provenance only; gating on them made every committed snapshot stale on every machine but the recorder's, which would have turned the parity lane red on CI (recorded Node 22.23.1 vs CI Node 20). Staleness now compares only the evidence-determining inputs (case/fixture hashes, oracle/source pins, imageDigests, normalizer).
  • no-reference-for-platform is non-blocking in the live binary — surfaced (never silently skipped) but not a hard failure, consistent with the runner exit-code contract and certify.
  • Metamorphic idempotence check observes the full container set, not just the first match, so a non-idempotent op that leaves a second container behind is detected instead of masked.
  • Aligned snapshot check's snapshot root with the certify/validate sibling-resolution.
  • Fixed an unrelated pre-existing bug: --force-tty-if-json now honors its documented case-insensitive env vocabulary via clap's BoolishValueParser.

Verification

  • cargo fmt --all -- --check and cargo clippy --all-targets --all-features -- -D warnings clean.
  • Full hermetic conformance + parity suite green (incl. real-Docker channel tests, record/replay, staleness).
  • Live parity_conformance_runner passes against real Docker + the pinned oracle.

🤖 Generated with Claude Code

https://claude.ai/code/session_019vhr7Tcf8ybvSZSE1owqBT

Conformance cases become data a shared runner executes, not pointers to
hand-written Rust tests. Adding a case/assertion/fixture is a pure data
edit (SC-001): declarative case shape in cases.json, four oracle types
(spec-expectation / live-differential / snapshot / invariant-metamorphic),
observable channels + observers (CLI-process, filesystem, four Docker
channels), the single normalizer, isolated Docker workspaces with RAII
cleanup, committed provenance-checked snapshots with staleness gating,
scoped allowed differences, validation classes V16-V20, and the new
parity_conformance_runner live binary.

Folds in review fixes:
- staleness gates only on evidence-determining inputs; host tool versions
  (node/docker/compose) are informational, so committed snapshots replay
  fresh across machines (fixes the parity lane going red on CI Node 20)
- no-reference-for-platform is non-blocking in the live binary
- metamorphic idempotence observes the full container set (detects a
  leftover second container instead of masking it)
- snapshot check uses the certify/validate sibling snapshot resolution
- --force-tty-if-json honors its documented case-insensitive env vocabulary

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019vhr7Tcf8ybvSZSE1owqBT
@github-actions github-actions Bot added feature New feature (alias) build Build system changes deps Dependency updates labels Jul 24, 2026
…kout

The declarative conformance runner hashes fixture bytes into fixtureHash/
caseHash and the hermetic snapshot_staleness tests recompute them and compare
to the recorded provenance. On a Windows checkout git's autocrlf rewrote LF to
CRLF, changing the fixture bytes so the recomputed caseHash no longer matched
the LF-computed committed value (committed_snapshot_hashes_match_the_committed_case
on the windows dev-fast lane). Extend .gitattributes with -text for the byte-exact
conformance/fixtures/** and conformance/snapshots/**, mirroring the 020/021 entries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019vhr7Tcf8ybvSZSE1owqBT
@pofallon
pofallon merged commit 67cd700 into main Jul 24, 2026
15 checks passed
@pofallon
pofallon deleted the 022-conformance-runner branch July 24, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Build system changes deps Dependency updates feature New feature (alias)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant