doctor_frankentui
doctor_frankentui is the operator-facing verification harness. It
packages everything the testing stack needs to turn a change into a
pass/fail decision: replay capture, environment certification, suite
orchestration across profiles, determinism soak, coverage gating, and
semantic-contract validation. It is the binary CI runs on every push
and the binary you run locally when a screen starts misbehaving and
you need evidence.
Source: crates/doctor_frankentui/ (version 0.3.1, publish = false).
Why it exists
The testing stack in ftui-harness provides primitives —
ProgramSimulator,
ShadowRun, snapshot macros. That is enough
for a developer writing a test, but not enough for a system operator
evaluating a migration. Operators need:
- Reproducibility — identical runs across machines and points in time.
- Evidence — structured JSON + JSONL manifests you can diff, archive, and grep.
- Gating — an exit code that encodes go / no-go for release.
- Triage — a compact failure summary pointing to the first broken step.
Every one of these is an integration concern, not a unit-test concern.
doctor_frankentui owns that integration.
What it integrates
- capture — TUI replay/capture through a PTY, writes RunMeta
- seeding — MCP bootstrap + deterministic demo seeding
- suite — profile-matrix replay (modern/tmux/dumb/…)
- certify — environment smoke test + degraded-mode classification
- report — HTML/JSON/plaintext synthesis over completed runs
- plan — import-intake planning and snapshot materialisation
Pipeline
Each stage writes structured artifacts into a shared run root (defaults
under /tmp/doctor_frankentui/…). The next stage consumes what the
previous stage produced; triage runs last and extracts the first N
failure signals.
Commands at a glance
| Command (alias) | Purpose | Page |
|---|---|---|
replay (capture) | Replay a single profile through the capture stack. | commands |
seed-demo | Bootstrap MCP + deterministic demo seeding. | commands |
migrate (suite) | Profile-matrix replay, suite-level manifest. | commands |
certify (doctor) | Environment + capture-stack smoke test. | commands |
report | HTML/JSON/plaintext reports over completed runs. | commands |
plan (import) | Import-intake planning. | commands |
Every subcommand accepts --machine {auto, human, json} for CI-friendly
output.
Artifact contract (at a glance)
Every top-level flow writes into a well-known layout. The schemas are versioned and fixed — artifacts has the full reference, but the short version is:
Happy
/tmp/doctor_frankentui/e2e/happy_<TIMESTAMP>/
├── meta/
│ ├── summary.json
│ ├── artifact_manifest.json
│ ├── events.jsonl
│ ├── command_manifest.txt
│ ├── env_snapshot.txt
│ └── tool_versions.txt
└── logs/Prerequisites
The CLI itself only needs cargo. The supporting scripts
require the Python + jq + rg + cargo-llvm-cov stack below. See
commands for which command needs what.
cargo— Rust 1.74+ toolchain (edition 2024).python3— 3.11+ for TOML parsing viatomllib; otherwise 3.9+ withtomliinstalled (pip install tomli).jq— used by determinism-soak and a few report helpers.rg(ripgrep) — used bydoctor_frankentui_no_fake_gate.py.cargo-llvm-cov— required for coverage gates (cargo install cargo-llvm-cov).
Typical local invocation
Certify your environment
cargo run -p doctor_frankentui -- certify --fullThis is a smoke test: did FrankenTUI build, does the terminal grant raw mode, does the demo show a plausible first frame?
Run a happy-path capture
./scripts/doctor_frankentui_happy_e2e.shArtifacts at /tmp/doctor_frankentui/e2e/happy_<ts>/. Inspect
meta/summary.json — if status: "ok", you’re done.
If something breaks, drive the failure flow
./scripts/doctor_frankentui_failure_e2e.sh
python3 ./scripts/doctor_frankentui_replay_triage.py \
--run-root /tmp/doctor_frankentui/e2e/failure_<ts> \
--max-signals 8The triage output points at the first failing event and the JSON pointers for its expected/actual evidence.
Before merging, run the coverage gate
./scripts/doctor_frankentui_coverage.shReads crates/doctor_frankentui/coverage/thresholds.toml, fails on
any under-threshold group.