Design specification for Cadora's resume and remediation surfaces: the color and type tokens, the anatomy of a node line, the bounded remediation loop, the resume and remediation states (verified, drift refused, drift allowed, completed-green, honest-blocked on max attempts and on the cost ceiling, and not-remediable prerequisite), the gate-status vocabulary, the flags each behavior reads, and the voice.

Cadora · design spec

Resume & remediation, by their surfaces

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.

Palette

Semantic first · green re-passes, red blocks, amber marks trusted & drifted


Green--scr-green · #16c784Gate re-passed · completed-green
Red--scr-red · #fb7185Gate FAILED · refused · honest-blocked
Amber--scr-amber · #ffd08aTrusted · drift · remediate tag
Blue--scr-blue · #6ba5f0Run ids · paths
Ink--scr-bg · #0f172aCard ground
Canvas--scr-canvas · #111c2fInset · attempt rows
Panel--scr-panel2 · #162237Raised surface
Line--scr-line · #334158Borders
Text--scr-text · #f5f7fbPrimary · node id · path
Muted--scr-muted · #9aa8bcLabels · trusted nodes

Type & metrics

Monospace is the instrument voice — recovery is read at the shell


RoleFamilySize / weightNotes
Node linemono12px / 400The one-line verdict per node in cadora run
Marksmonogreen / red ok green · blocked red — the only status glyphs
Gate markmonotext / capsgate:<name> ok or the status in caps: FAILED · VACUOUS · PACKAGING_FAILED
Remediate tagmonoamberremediate:<state> x<n> — state + attempt count
CostmonotextAlways suffixed est. when from the price table, not metered
Run id / pathmonobluerun-YYYYmmdd-HHMMSS · runs/<id>
MetricValueMetricValue
Card radius10pxSemantic accent4px left border
Node line-height1.85Attempt row radius8px
Card padding14px 16pxState padding11px 13px
Trusted node borderdashedRemediate default0 = off

Anatomy — the node line

One line says what ran, what it cost, and whether the gate really passed


1234 ✓ build $3.4100 est. gate:tests ok remediate:completed-green x2
1Node + mark — the node id, prefixed (ran clean) or (blocked). One line per node, in DAG order.
2Cost — per-node spend, marked est. when it comes from the price table. On a remediated node it includes the attempts' cost.
3Gategate:<name> ok in green, or the failing status in caps (FAILED, VACUOUS, PACKAGING_FAILED, BLOCKED_PREREQUISITE). This is the deterministic check — the source of truth for green.
4Remediate tag — present only when --remediate engaged: completed-green or honest-blocked, and x<n> attempts run.

The bounded remediation loop

Fresh session → re-run the SAME gate → green only if it truly passes


failing gate (or blocking integrity finding) │ ├─ attempt k fresh, constrained session — gate detail fed back verbatim │ # told: do not weaken, skip, or bypass the gate; write real tests │ ├─ re-run the SAME ShellGate.check # + re-scan integrity when enforced │ ├─ pass → completed-green # the gate decides, never execution.ok │ └─ fail → next attempt, if any remain │ └─ bound hit (attempts, or --remediate-max-cost) → honest-blocked # full attempt trail kept; never a fabricated pass

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.

Anatomy — the resumed run

Two node kinds: trusted (skipped) and fresh (re-run)


resumedrun-20260717-163150 · resumed from 'build' · verified vs run-20260717-140205 · no drift
nodeplantrustednot re-run
nodedesigntrustednot re-run
nodebuildgate passedre-run · resume point
nodetestgate passedre-run · downstream

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.

Resume states

Provenance is checked before any skipped node is trusted


Verified · no drift → proceed

↩ resume: skipping plan, design · running from 'build' ↳ workspace verified against run-20260717-140205 — no drift (37 files)

Drifted · default → refuse

✗ resume refused: workspace drifted since run-20260717-140205 (2 modified, 0 removed, 1 added) => pass --allow-drift to override

Drifted · --allow-drift → proceed, recorded

⚠ workspace DRIFTED since run-20260717-140205 (2 modified, 0 removed, 1 added) proceeding under --allow-drift recorded in the evidence pack

No baseline → resume on trust

↳ no prior workspace manifest to verify against — resuming 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.

Remediation states

Green is earned, blocked is honest — never a fabricated pass


completed-green · gate re-passed

✓ build gate:tests ok remediate:completed-green x2 => node passes

honest-blocked · attempts exhausted

✗ build gate:tests FAILED remediate:honest-blocked x2 (max_attempts) => NOT a pass

honest-blocked · cost ceiling

✗ build gate:tests FAILED remediate:honest-blocked x2 (cost_ceiling) => stopped before overspend

not remediable · missing prerequisite

✗ build gate:tests BLOCKED_PREREQUISITE remediation does not engage => truthfully blocked

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.

The attempt trail

One row per fresh session — archived under <node>/remediation/


attempt 1fresh session · re-ran gate:testsFAILED
attempt 2fresh session · re-ran gate:testsPASSED

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.

Gate-status vocabulary

Which statuses the loop will try, and which it won't


StatusMeansRemediable?
failedThe gate command ran and did not passYes — default
vacuousThe gate "passed" having run zero real testsYes — default
packaging_failedThe package won't build / installYes — default
blocked_prerequisiteGate tooling is missing from the environmentNo — not agent-repairable
passedThe deterministic check holds— nothing to repair

What each flag drives

Two recovery paths · resume trusts, remediate repairs


FlagReadsEffect
--resume-from NODEnode idSkip every node upstream of NODE (trust their artifacts in --cwd); run NODE and downstream. Re-runs NODE itself.
--skip NODE[,NODE...]node idsSkip exactly the named nodes, trusting their existing workspace artifacts. Fine-grained alternative to --resume-from.
--allow-driftflagOn --resume-from/--skip, proceed even if the workspace drifted (default: refuse). The drift is recorded either way.
--remediate NintegerOn 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 USDfloatStop remediation honest-blocked if the attempts' summed cost would exceed this ceiling.

Voice

The verdict is evidence, not effort


DoNot
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”
Tokens and behavior are taken verbatim from cadora/runner.py, cadora/provenance.py, and cadora/remediation.py. Edit the rendered components in place, or hand the palette and metrics tables to a Figma library.