Skip to main content

Spec-driven development framework for AI coding agents

Project description

scafld

Review Gate Smoke

scafld builds long-running AI coding work under adversarial review, so your agent stays coherent across the whole job.

Canonical repo: https://github.com/nilstate/scafld. Default branch: main.

Most AI coding tools optimize for speed inside one turn. scafld optimizes for correctness across the whole run:

  • the work starts from a reviewed spec
  • execution stays phase-bounded and measurable
  • completion is gated by an independent challenger at review

The differentiator is simple: the agent does not get to grade its own homework.

Identity

scafld is a scaffold in the literal sense: temporary structure that shapes the build while the work is in progress.

The lifecycle stays familiar:

draft -> harden -> approve -> build -> review -> complete

What changed is the core model underneath it.

Primitives

Two nouns carry the system:

  • spec: what must be true. The reviewed contract and lifecycle source of truth.
  • session: what happened. The durable run ledger under .scafld/runs/{task-id}/session.json.

handoff is transport, not a primitive. It is the structured brief for the next voice.

Every generated handoff is:

  • immutable
  • sibling *.md + *.json
  • tagged by role × gate

Current runtime pairings:

  • executor × phase
  • executor × recovery
  • challenger × review

Review Gate

Challenge fires at one gate only in v1: review.

That keeps the system sharp without turning every phase into ceremony.

  • review emits a challenger handoff
  • the challenger writes a verdict into .scafld/reviews/{task-id}.md
  • complete closes only if the review gate passes, or a human applies the audited override path after a completed challenger round

The override path is explicit:

scafld complete <task-id> --human-reviewed --reason "manual audit"

That override is available only after a completed challenger review round exists.

Runtime Layout

.scafld/
  specs/{drafts,approved,active,archive}/
  runs/
    {task-id}/
      handoffs/
        executor-phase-phase1.md
        executor-phase-phase1.json
        executor-recovery-ac1_1-1.md
        executor-recovery-ac1_1-1.json
        challenger-review.md
        challenger-review.json
      diagnostics/
        ac1_1-attempt1.txt
      session.json
    archive/{YYYY-MM}/{task-id}/

Hard rules:

  • spec never carries runtime state
  • handoff is never read back to compute state
  • session is the only durable run-state source
  • recovery is a handoff gate plus counters in session, not a subsystem
  • telemetry is a view of session, not a separate artifact
  • v1 makes zero spec schema changes

Agent Surface

Default help teaches the slim workflow surface, including repo seeding:

scafld init
scafld plan <task-id>
scafld approve <task-id>
scafld build <task-id>
scafld review <task-id>
scafld complete <task-id>
scafld status <task-id>
scafld list
scafld report
scafld handoff <task-id>
scafld update

Use scafld --help --advanced to show the remaining operator tools such as harden, validate, branch, sync, audit, diff, summary, checks, and pr-body.

Wrapper intent:

  • plan: create a draft spec or reopen harden on an existing draft
  • build: start approved work and immediately drive validation to the next handoff or block
  • review: run the adversarial review gate and emit the challenger handoff
  • status: expose the canonical next_action and current_handoff

When the workspace includes them, the wrapper scripts are optional handoff adapters for Codex and Claude Code. The default challenger path is now scafld review itself.

.scafld/core/scripts/scafld-codex-build.sh <task-id>
.scafld/core/scripts/scafld-codex-review.sh <task-id>
.scafld/core/scripts/scafld-claude-build.sh <task-id>
.scafld/core/scripts/scafld-claude-review.sh <task-id>

Success Metrics

scafld claims quality lift only where it can measure it.

The canonical metrics are:

  • first_attempt_pass_rate
  • recovery_convergence_rate
  • challenge_override_rate

report surfaces all three per task and in aggregate.

Use scafld report --runtime-only to focus on tasks with runtime session data.

It also surfaces review-signal counts such as completed challenger rounds, grounded findings, and clean reviews that still record what was attacked.

There is also one honest boundary: scafld can emit a better handoff, but an external harness may still ignore it. That is why the metrics are framed as session outcomes, not proof of prompt consumption.

Install

pip install scafld
npm install -g scafld
git clone https://github.com/nilstate/scafld.git ~/.scafld && ~/.scafld/install.sh
curl -fsSL https://raw.githubusercontent.com/nilstate/scafld/main/install.sh | sh

pip install scafld installs the console entry point plus the managed runtime bundle used by scafld init and scafld update.

npm install -g scafld installs the same CLI package for environments that ship tooling through npm. The CLI still requires python3 at runtime. Commands that edit Markdown spec front matter, such as scafld harden, also require PyYAML in that Python runtime:

python3 -m pip install PyYAML

Setup

cd your-project
scafld init

This creates the managed runtime bundle, prompts, schemas, run directories, and project-owned overlays:

your-project/
  .scafld/
    scafld/                # Managed reset copy refreshed by `scafld update`
    config.yaml            # Project config overlay
    config.local.yaml      # Local machine overrides
    prompts/               # Active project-owned template sources
    runs/                  # Generated handoffs, diagnostics, session state
    reviews/               # Adversarial review artifacts
    specs/                 # Specs by lifecycle state
  AGENTS.md
  CLAUDE.md
  CONVENTIONS.md

Start by customizing:

  1. AGENTS.md
  2. CLAUDE.md
  3. CONVENTIONS.md
  4. .scafld/config.local.yaml

When the workspace includes them, the handoff-first wrappers are:

  • .scafld/core/scripts/scafld-codex-build.sh <task-id>
  • .scafld/core/scripts/scafld-codex-review.sh <task-id>
  • .scafld/core/scripts/scafld-claude-build.sh <task-id>
  • .scafld/core/scripts/scafld-claude-review.sh <task-id>

Repo-aware planning also works for mixed Python+Node repos. When both stacks are present, scafld merges the signals and prefers concrete detected commands over placeholder defaults.

Prompt ownership is deliberate:

  • .scafld/prompts/* is the active template layer the runtime reads first
  • .scafld/core/prompts/* is the managed reset copy refreshed by scafld update

Minimal Runtime Config

llm:
  model_profile: "default"
  context:
    budget_tokens: 12000
  recovery:
    max_attempts: 1

Anything beyond that waits until it earns its place through measured wins.

Next Docs

  • docs/execution.md
  • docs/integrations.md
  • docs/review.md
  • docs/run-artifacts.md
  • docs/cli-reference.md
  • AGENTS.md

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scafld-2.0.0.tar.gz (218.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scafld-2.0.0-py3-none-any.whl (215.8 kB view details)

Uploaded Python 3

File details

Details for the file scafld-2.0.0.tar.gz.

File metadata

  • Download URL: scafld-2.0.0.tar.gz
  • Upload date:
  • Size: 218.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scafld-2.0.0.tar.gz
Algorithm Hash digest
SHA256 61256733ae4b77644d566566bc74552bd4b61cd5b16941bf6fa6965324318228
MD5 9061c78bfc2d98159ec72771a71b11f2
BLAKE2b-256 67fe4acfa0b4c472112f13a81432af101a97a4f30a51cc9be5b57fc354321f7a

See more details on using hashes here.

File details

Details for the file scafld-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: scafld-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 215.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scafld-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0b1ccfc2fd9858f105ec6a36d039ee04c2093a153cdc12d2e969e1761b6eb438
MD5 7fa26ce4682126d37e948eacd3b63ad7
BLAKE2b-256 303d21cfc3bc2b07934fde546a4f5a1062e30460246b316d8a9a342125a1f084

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page