Cadora · design spec
Everything needed to render or extend the recovery surfaces — the exact tokens, the node line's anatomy, the bounded remediation loop, every resume and remediation state, and the flags that drive them. The rendered components are live HTML; edit them here or lift the specs into Figma.
Semantic first · green re-passes, red blocks, amber marks trusted & drifted
--scr-green · #16c784Gate re-passed · completed-green--scr-red · #fb7185Gate FAILED · refused · honest-blocked--scr-amber · #ffd08aTrusted · drift · remediate tag--scr-blue · #6ba5f0Run ids · paths--scr-bg · #0f172aCard ground--scr-canvas · #111c2fInset · attempt rows--scr-panel2 · #162237Raised surface--scr-line · #334158Borders--scr-text · #f5f7fbPrimary · node id · path--scr-muted · #9aa8bcLabels · trusted nodesMonospace is the instrument voice — recovery is read at the shell
| Role | Family | Size / weight | Notes |
|---|---|---|---|
| Node line | mono | 12px / 400 | The one-line verdict per node in cadora run |
| Marks | mono | green / red | ✓ ok green · ✗ blocked red — the only status glyphs |
| Gate mark | mono | text / caps | gate:<name> ok or the status in caps: FAILED · VACUOUS · PACKAGING_FAILED |
| Remediate tag | mono | amber | remediate:<state> x<n> — state + attempt count |
| Cost | mono | text | Always suffixed est. when from the price table, not metered |
| Run id / path | mono | blue | run-YYYYmmdd-HHMMSS · runs/<id> |
| Metric | Value | Metric | Value |
|---|---|---|---|
| Card radius | 10px | Semantic accent | 4px left border |
| Node line-height | 1.85 | Attempt row radius | 8px |
| Card padding | 14px 16px | State padding | 11px 13px |
| Trusted node border | dashed | Remediate default | 0 = off |
One line says what ran, what it cost, and whether the gate really passed
Fresh session → re-run the SAME gate → green only if it truly passes
Green is decided here, by re-running the deterministic check — not by the agent's claim of success. A blocked_prerequisite gate never enters the loop: missing tooling is not agent-repairable.
Two node kinds: trusted (skipped) and fresh (re-run)
Trusted nodes are recorded skipped in telemetry with a reason (resumed from 'build' or explicitly skipped) and add no agent cost. Fresh nodes re-execute and re-gate. The banner names the resume point and the baseline the workspace was verified against.
Provenance is checked before any skipped node is trusted
Verified · no drift → proceed
Drifted · default → refuse
Drifted · --allow-drift → proceed, recorded
No baseline → resume on trust
Drift is classified modified / removed / added, most-actionable first, bounded to twelve lines per class. Refuse is the default; --allow-drift is opt-in and always leaves a record.
Green is earned, blocked is honest — never a fabricated pass
completed-green · gate re-passed
honest-blocked · attempts exhausted
honest-blocked · cost ceiling
not remediable · missing prerequisite
Blocked reasons recorded in the pack: max_attempts, cost_ceiling, executor_failed, integrity_blocked. Every state keeps the full attempt trail — the archived proof of what was tried.
One row per fresh session — archived under <node>/remediation/
Each attempt gets its own synthetic id <node>-remediate-<k> and a prompt built from the current gate/integrity detail — never the agent's own claim. The verdict pill is the re-run gate result, not the session's self-report.
Which statuses the loop will try, and which it won't
| Status | Means | Remediable? |
|---|---|---|
| failed | The gate command ran and did not pass | Yes — default |
| vacuous | The gate "passed" having run zero real tests | Yes — default |
| packaging_failed | The package won't build / install | Yes — default |
| blocked_prerequisite | Gate tooling is missing from the environment | No — not agent-repairable |
| passed | The deterministic check holds | — nothing to repair |
Two recovery paths · resume trusts, remediate repairs
| Flag | Reads | Effect |
|---|---|---|
| --resume-from NODE | node id | Skip every node upstream of NODE (trust their artifacts in --cwd); run NODE and downstream. Re-runs NODE itself. |
| --skip NODE[,NODE...] | node ids | Skip exactly the named nodes, trusting their existing workspace artifacts. Fine-grained alternative to --resume-from. |
| --allow-drift | flag | On --resume-from/--skip, proceed even if the workspace drifted (default: refuse). The drift is recorded either way. |
| --remediate N | integer | On a failed/vacuous gate (or a blocking integrity finding), run up to N repair attempts in a fresh constrained session (default 0 = off). |
| --remediate-max-cost USD | float | Stop remediation honest-blocked if the attempts' summed cost would exceed this ceiling. |
The verdict is evidence, not effort
| Do | Not |
|---|---|
| Name the trusted set — skipping plan, design | “Resumed ✓” |
| State the drift — 2 modified, 0 removed, 1 added | “Workspace changed” |
| Show the state + count — honest-blocked x2 (max_attempts) | “Gave up” |
| Keep the exact words — completed-green / honest-blocked / trusted | “Fixed!” / “Failed” |