Skip to Content

Artifact contract

Every doctor_frankentui flow writes into a known layout under a run root (defaults under /tmp/doctor_frankentui/…). The files are the contract: CI relies on these exact names and schemas, and humans grep them with operations/evidence-grep-patterns recipes. This page documents the contract verbatim.

Source: README + crates/doctor_frankentui/src/runmeta.rs + the scripts/doctor_frankentui_*_e2e.sh scripts.

Timestamps in run-root directory names are UTC in %Y%m%dT%H%M%SZ form — e.g. happy_20260423T000000Z.

Happy path

/tmp/doctor_frankentui/e2e/happy_<TIMESTAMP>/ ├── logs/ (per-step stdout/stderr logs) ├── project/ (captured project state, if any) └── meta/ ├── summary.json ├── summary.txt ├── artifact_manifest.json ├── events.jsonl ├── events_validation_report.json ├── step_results.tsv ├── command_manifest.txt ├── env_snapshot.txt └── tool_versions.txt

meta/summary.json

Outcome summary for the run.

{ "status": "ok", "run_id": "doctor_happy_seed0", "started_at": "T000000", "finished_at": "T000042", "profile": "modern", "stage_outcomes": [ { "stage": "seed-demo", "status": "ok", "duration_ms": 812 }, { "stage": "replay", "status": "ok", "duration_ms": 34121 }, { "stage": "report", "status": "ok", "duration_ms": 411 } ], "artifact_manifest": "meta/artifact_manifest.json", "events": "meta/events.jsonl" }
  • status: "ok" or "degraded" or "failed".
  • stage_outcomes[]: ordered list with per-stage timing.
  • profile: the capture profile used (one of list-profiles).

meta/artifact_manifest.json

Full file inventory for the run.

{ "schema_version": "artifact-manifest-v1", "run_id": "doctor_happy_seed0", "root": "/tmp/doctor_frankentui/e2e/happy_20260423T000000Z", "files": [ { "path": "meta/events.jsonl", "size_bytes": 45120, "sha256": "…" }, { "path": "logs/seed_demo.stdout.log", "size_bytes": 1240, "sha256": "…" } ] }

Checksums are SHA-256 and are stable across identical runs when E2E_DETERMINISTIC=1 is active.

meta/events.jsonl

Append-only JSONL ledger. Each line is one event. Schema is versioned — current is schema_version: "e2e-events-v1". Validated by scripts/doctor_frankentui_validate_jsonl.py and mirrored into meta/events_validation_report.json.

Common event kinds:

  • stage_start / stage_end
  • step_start / step_end
  • frame_captured — includes frame_idx, checksum
  • diff_decision — diff-strategy selection
  • resize_decision — BOCPD-driven resize coalescing
  • conformal_frame_guard — frame-budget guard verdict
  • degradation_event — degradation cascade transition
  • voi_decision — VOI sampling outcome

See operations/evidence-grep-patterns for jq recipes per event type.

meta/events_validation_report.json

Output of the JSONL validator. ok: true plus a count of warnings if E2E_JSONL_VALIDATE_MODE=warn, or a hard ok: false in strict mode.

meta/step_results.tsv

One row per step: step_id, status, duration_ms, notes. Useful for quick scans without a JSON parser.

meta/command_manifest.txt

Exact commands executed, in order. Reproduces the run.

meta/env_snapshot.txt

Captured environment at start. Includes TERM, COLORTERM, NO_COLOR, TMUX, ZELLIJ, E2E_DETERMINISTIC, E2E_SEED, E2E_TIME_STEP_MS, and the git SHA.

meta/tool_versions.txt

Versions for cargo, rustc, python3, jq, rg, cargo-llvm-cov.

Failure path

/tmp/doctor_frankentui/e2e/failure_<TIMESTAMP>/ ├── cases/<case_id>/… (per-case captures + artifacts) ├── logs/ └── meta/ ├── summary.json ├── summary.txt ├── case_results.json ├── case_results.tsv ├── replay_triage_report.json ├── events.jsonl ├── events_validation_report.json ├── command_manifest.txt ├── env_snapshot.txt └── tool_versions.txt

meta/summary.json

{ "status": "failed", "run_id": "doctor_failure_seed0", "failed_stage": "replay", "first_failing_case": "case_003", "failure_reason": "frame_checksum_mismatch", "duration_ms": 28310, "stage_outcomes": [ /* … */ ] }

meta/case_results.json

Per-case details for every adversarial case the failure suite ran.

{ "schema_version": "case-results-v1", "cases": [ { "case_id": "case_001", "description": "inline mode under 40-column viewport", "status": "ok", "duration_ms": 3120 }, { "case_id": "case_003", "description": "alt screen + rapid resize storm", "status": "failed", "duration_ms": 4820, "failure_signal": "frame_checksum_mismatch", "artifact_dir": "cases/case_003", "events_pointer": "meta/events.jsonl#L4812" } ] }

meta/replay_triage_report.json

Output of scripts/doctor_frankentui_replay_triage.py run at end of the failure flow. Top-N failure signals with JSON pointers to the evidence. See replay triage for the signal schema.

{ "schema_version": "replay-triage-v1", "run_root": "/tmp/doctor_frankentui/e2e/failure_20260423T000000Z", "signals": [ { "severity": 2, "message": "frame checksum diverged at index 42", "event_index": 4812, "event_type": "frame_captured", "case_id": "case_003", "step_id": "resize_storm", "pointers": ["meta/events.jsonl#L4812", "cases/case_003/frame_42.txt"], "expected": { "checksum": "0xdeadbeef00000000" }, "actual": { "checksum": "0xcafef00d00000000" } } ], "timeline": [ /* compacted timeline entries */ ] }

meta/events.jsonl (failure variant)

Same schema as happy-path, but may be truncated at the failure point. Validate with events_validation_report.json.

Determinism path

/tmp/doctor_frankentui/determinism_soak_<TIMESTAMP>/ ├── happy_run_<iter>/ (full happy-path artifacts per iter) ├── failure_run_<iter>/ (full failure-path artifacts per iter) ├── logs/ └── meta/ ├── run_index.tsv ├── determinism_report.json └── determinism_report.txt

meta/determinism_report.json

Frame-checksum parity across iterations. Non-volatile divergence fails the gate.

{ "schema_version": "determinism-report-v1", "iterations": 3, "total_frames": 2148, "matches": 2148, "divergences": 0, "divergence_ratio": 0.0, "per_iteration": [ { "iter": 1, "run_id": "doctor_happy_seed0", "frames": 716 }, { "iter": 2, "run_id": "doctor_happy_seed0", "frames": 716 }, { "iter": 3, "run_id": "doctor_happy_seed0", "frames": 716 } ], "volatile_events": [] }
  • divergence_ratio = divergences / total_frames. Gate fails at any non-zero value outside the volatile_events allowlist.

meta/determinism_report.txt

Human-readable summary. Suitable for PR comment bots.

Full guide: determinism soak.

Coverage path

target/doctor_frankentui_coverage/ ├── coverage_summary.json ├── coverage_gate_report.json └── coverage_gate_report.txt

coverage_gate_report.json

Output of scripts/doctor_frankentui_coverage.sh after comparing coverage_summary.json against crates/doctor_frankentui/coverage/thresholds.toml.

{ "schema_version": "coverage-gate-v1", "passed": true, "totals": { "lines": { "actual": 92.1, "threshold": 89.0, "verdict": "pass" }, "branches": { "actual": 72.4, "threshold": 69.0, "verdict": "pass" }, "functions": { "actual": 88.3, "threshold": 86.0, "verdict": "pass" } }, "groups": { "orchestration": { "lines": { "actual": 90.1, "threshold": 88.0, "verdict": "pass" }, /* … */ }, "foundations": { /* … */ }, "module_capture":{ /* … */ } } }
  • verdict: "pass" or "fail" per metric.
  • The whole gate passed iff every listed metric passed.

Full guide: coverage gate.

Troubleshooting map

From the doctor_frankentui README:

SymptomLikely causeNext step
certify exits 30Capture stack degraded (no raw mode / no PTY).Inspect meta/doctor_summary.json.degraded_reason; re-run with --allow-degraded if acceptable.
events.jsonl absentChild process crashed before first event.Read logs/<step>.stderr.log; check meta/command_manifest.txt to reproduce.
events_validation_report.json.ok == falseSchema drift.Compare against tests/e2e/lib/e2e_jsonl_schema.json; file an issue if the schema changed intentionally.
determinism_report.json.divergences > 0Non-volatile divergence.Open meta/run_index.tsv, find the diverging iter, diff happy_run_<iter>/meta/events.jsonl across iters.
coverage_gate_report.json.passed == falseA group or module dropped below threshold.Inspect groups.<name> for the failing metric; use cargo llvm-cov --html to drill into uncovered lines.
artifact_manifest.json missing filesCapture interrupted.Re-run; if reproducible, open an issue with the interrupted run root attached.
All checksums match but snapshot tests failProfile drift.Re-run with FTUI_TEST_PROFILE pinned; check snapshot tests.