Lifecycle
scafld keeps workflow state visible in the filesystem and durable in the
session ledger. Specs move through .scafld/specs/; runtime evidence lives
under .scafld/runs/.
States
| Status | Directory | Description |
|---|---|---|
draft | drafts/ | Spec is being written and hardened. |
approved | approved/ | Human accepted the contract. Ready to execute. |
active | active/ | A build phase is open or phase evidence is being recorded. |
blocked | active/ | Attempted build evidence found a blocking failure. |
review | active/ | Work reached the adversarial review gate. |
completed | archive/YYYY-MM/ | Review passed and work was archived. |
failed | archive/YYYY-MM/ | Work was explicitly failed. |
cancelled | archive/YYYY-MM/ | Work was abandoned before completion. |
Typical path:
draft -> approved -> active -> review -> completedHardening is tracked separately with harden_status so it can be repeated and
audited without inventing another lifecycle directory.
Commands
scafld plan add-auth
scafld harden add-auth
scafld harden add-auth --mark-passed
scafld validate add-auth
scafld approve add-auth
scafld build add-auth
# for manual acceptance, use the build command printed by handoff
scafld build add-auth --criterion <id> --disposition pass --evidence-digest <sha256> --actor <actor> --reason "what was verified"
# implement the opened phase, then repeat build until review
scafld build add-auth
scafld review add-auth
scafld finalize add-authscafld review add-auth is the provider/model gate. After it passes,
scafld finalize add-auth consumes the accepted review, runs acceptance against
deterministic tree facts, mints a signed receipt, archives the canonical spec,
and records completion. Finalize does not invoke a model. scafld verify <receipt> --target <commit-ish> then replays the receipt as the CI merge wall.
See CLI Reference for the legacy complete command.
Failure paths:
scafld fail add-auth --reason "acceptance cannot be satisfied"
scafld cancel add-auth --reason "replaced by narrower task"Filesystem State
.scafld/specs/
drafts/
approved/
active/
archive/
2026-05/The directory a spec lives in matches its lifecycle status. You should be able to answer "what is in flight?" with:
ls .scafld/specs/activeEvidence Ordering
When a command changes runtime state, scafld writes the session first and then projects the current state back into the Markdown spec.
That gives scafld one authority rule:
- session is the durable evidence source
- spec is the readable contract plus current projection
- handoff is transport for the next model voice
If the spec projection and session ever disagree, reconciliation should rebuild the projected state from session evidence.
Hardening
harden_status values:
not_runin_progresspassedneeds_revisionoverriddenerror
scafld harden <task-id> opens a harden round while the spec is still a draft.
The active prompt asks the agent to record evidence-backed observations for
design, scope, paths, commands, acceptance timing, and rollback or repair shape.
Design comes first: the round should challenge shared ownership and keep
API/MCP/CLI/provider/docs surfaces as light adapters over common behavior. The
round is bound to the draft digest, so repeating harden without changing the
draft reuses or blocks on the existing round instead of stacking new rounds.
scafld harden <task-id> --mark-passed verifies dimension coverage, anchors, and unresolved blocking
observations before recording that the draft survived hardening. Missing
dimensions, open blocking observations, and unresolved citations keep harden
not-ready and leave the round open.
Approving over incomplete, stale, failed, or needs_revision harden evidence
requires scafld approve <task-id> --reason <reason>. scafld records that
operator decision as overridden; real shape blockers should be fixed in the
draft and hardened again.
Approval remains explicit. Hardening makes the approval decision worth trusting.
Review Gate
scafld review moves work to the review gate and writes the challenger verdict.
scafld finalize refuses to archive until the latest review verdict is pass.
That separation is the core product stance: execution tries to finish the work; adversarial review tries to break confidence in the work.
Queries
scafld status add-auth
scafld status add-auth --json
scafld status add-auth --json --no-context
scafld list
scafld list --json
scafld reportstatus --json is the right integration surface for wrappers. It reports the
current lifecycle state, next allowed follow-up command, and task material
projection without requiring the wrapper to scrape Markdown or invent a separate
change manifest. Agent entry should read full status or handoff once. Follow-up
polling can use --no-context after the same spec_source.sha256 is already in
context; scafld keeps source path, digest, and byte count while omitting only the
markdown body.
