ProofTrail is a monorepo for evidence-first browser automation.
The outward category line is:
Evidence-first browser automation with recovery and MCP
The repository is intentionally organized around one public execution mainline and one manifest-anchored evidence surface. The goal is not only to run browser automation, but to make each run inspectable, replayable, and recoverable after something breaks.
apps/api/: FastAPI backend for orchestration, operator APIs, and runtime stateapps/web/: operator-facing command center for launch, task review, and flow workshopapps/automation-runner/: record, extract, replay, and reconstruction workshop laneapps/mcp-server/: MCP-facing adapter for external AI clientspackages/orchestrator/: canonical CLI control plane (pnpm uiq <command>)packages/core/: manifest, artifact, and reporting contractsProofTrail has three related but distinct execution concepts. Treating them as the same thing is the easiest way to get confused.
| Lane | What it is | Primary entrypoint | Primary source of truth |
|---|---|---|---|
| Canonical evidence run | The public mainline used for standard repo-level execution and proof generation | just run -> pnpm uiq run --profile pr --target web.local |
.runtime-cache/artifacts/runs/<runId>/manifest.json and linked reports |
| Operator run | A template-driven run inside the operator platform (session -> flow -> template -> run) |
/api/runs, Web studio/workshop flows |
.runtime-cache/automation/universal/{sessions,flows,templates,runs}.json |
| Automation task | A lower-level command execution record used by the API control plane | /api/automation/* |
task store backend (file or SQL, depending on runtime config) |
The lanes are related, but they do not collapse into one object model.
The canonical public mainline is:
just setupjust run.runtime-cache/artifacts/runs/<runId>/just run resolves to pnpm uiq run --profile pr --target web.local.
That canonical path is orchestrator-first and manifest-first:
pnpm uiq <command> composes profile + target and writes
the run through one public mainline before runtime start, stage execution,
and final exit semantics are applied..runtime-cache/artifacts/runs/<runId>/ evidence through a
manifest-anchored bundle so the run can be inspected, replayed, and
discussed later.The public proof contract expects the manifest, summary, diagnostics index, log
index, and proof.*.json files to exist together as one bundle.
The operator lane is the product-facing workflow that manages longer-lived automation assets:
This lane is served by the FastAPI backend and the Web command center. It is stateful even when the canonical public mainline is not running.
When an operator run needs to replay a flow, the backend materializes a
helper-compatible runtime draft under .runtime-cache/automation/<sessionId>/
and passes FLOW_SESSION_ID into the replay lane. That bridge keeps
universal/*.json as the operator truth surface while avoiding a hard
dependency on the global latest-session.json pointer for template-driven
replay.
After the first result exists, the operator lane grows through five product surfaces:
Those surfaces sit on top of the existing lane model. They do not replace it.
Recovery also keeps an explicit Wave 5 safety boundary:
That means ProofTrail now exposes a stronger recovery assistant, but it still does not ship an autonomous self-heal loop.
just run-legacy and the lower-level workshop scripts still exist for deeper
record/extract/replay troubleshooting, but they are not the canonical public
mainline.
Treat helper-path outputs under .runtime-cache/automation/ as workshop or
operator surfaces, not as the primary public proof surface.
Two advanced surfaces are intentionally visible but secondary:
Different questions map to different truth surfaces:
| Question | Source of truth |
|---|---|
| “What happened in the canonical run?” | .runtime-cache/artifacts/runs/<runId>/manifest.json plus linked reports and proof files |
| “What canonical runs are still retained in this checkout?” | /api/evidence-runs* backed by manifest-derived evidence registry semantics |
| “What flow, template, or operator run exists right now?” | .runtime-cache/automation/universal/*.json |
| “What command task is queued, running, or failed?” | task store backend selected by runtime config |
| “What stages and thresholds define the canonical run?” | configs/profiles/*.yaml |
| “What target is being exercised and how is it started?” | configs/targets/*.yaml |
Do not silently substitute one truth surface for another. A canonical evidence run, an operator run, and an automation task may describe the same user story, but they are not interchangeable records.
flowchart LR
A["just run"] --> B["pnpm uiq run --profile pr --target web.local"]
B --> C["load profile + target"]
C --> D["start target runtime if needed"]
D --> E["execute unit/contract/ct/e2e/capture/a11y/perf/visual/report"]
E --> F["write manifest + reports + proof bundle"]
F --> G["inspect .runtime-cache/artifacts/runs/<runId>/"]
.runtime-cache/artifacts/runs/..runtime-cache/automation/.If you are new to the repository, read in this order:
README.mddocs/reference/run-evidence-example.mdpackages/orchestrator/src/cli.tsconfigs/profiles/pr.yamlconfigs/targets/web.local.yamlapps/api/app/services/universal_platform_service.pyapps/web/src/App.tsx