Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
# Changelog

## 0.3.0

Added:

- Generic agent runner contract (`detect` / `generateStage` / `executeTask`
/ `resumeTask`) with a runner registry, discriminated statuses
(available/unavailable/unauthenticated/incompatible/misconfigured/error),
and structured execution outcomes.
- Claude Code local CLI runner: executable/authentication detection,
help-based capability probing with graceful degradation, non-interactive
JSON invocation built as an argv array with prompts over stdin, session
ids, timeouts, cancellation, and stdout/stderr size limits.
- Runner diagnostics: `runner list`, `runner doctor [name]`,
`runner show <name>` — read-only, `--json`, never echo credentials.
- Model-assisted spec authoring: `spec generate <name> --stage <stage>` and
`spec refine <name> --stage <stage> --instruction …` with versioned prompt
contracts, workflow-mode prerequisites, read-only generation tools,
deterministic candidate validation (invalid candidates are retained under
the run directory and never applied), unified diffs, atomic writes, and
dependent-approval invalidation. Nothing is ever auto-approved.
- Approved task execution: `spec run <name>` (`--task`, `--next`, `--all`,
`--dry-run`, `--allow-dirty`, `--no-verify`) — one task per run, twenty
pre-run checks, bounded task context, sequential `--all` that stops on the
first unverified task.
- Git before/after snapshots with hash-exact changed-file attribution,
protected-path hashing (`.kiro/**`, sidecar config/state), patch capture
with size limits, and a clean-working-tree policy with a precise
`--allow-dirty` baseline.
- Trusted verification commands from `.specbridge/config.json` (argv arrays,
per-command timeouts, required/optional), never derived from spec content
or model output.
- Append-only task evidence under `.specbridge/evidence/<spec>/<task>/`,
deterministic evidence evaluation, and verified-only surgical checkbox
completion (one character on one line; the tasks approval hash is
re-recorded for SpecBridge's own sanctioned edit).
- Manual task acceptance: `spec accept-task --task … --reason …`, recorded
as `manually-accepted` (actor `local-user`), always distinct from
automated verification.
- Run records under `.specbridge/runs/<run-id>/` (prompt, raw output,
snapshots, verification, evidence, report) plus `run list`, `run show`,
and resumable Claude Code sessions via `run resume <run-id>` with
divergence detection and `parentRunId` lineage.
- Versioned runner configuration schema (v0.2 config files upgrade with safe
defaults), a deterministic mock runner with failure/rogue scenarios, and a
fake Claude CLI process fixture — CI needs no Claude installation and no
network.
- Documented exit codes 3–6 (runner unavailable / runner failure /
timeout–cancel / safety) extending the unchanged 0/1/2 contract.

Security:

- No embedded authentication: the local user installs and authenticates
Claude Code independently; SpecBridge never stores or prints credentials.
- No dangerous permission bypass: `bypassPermissions` and
`dangerously-skip-permissions` are rejected at the config schema, argv
assembly, and pre-spawn layers.
- No model-controlled verification: commands come only from trusted project
configuration; spec files and model output are treated as data.
- No automatic git commit, push, reset, stash, or rollback.
- Protected-path modifications (`.kiro`, sidecar state, moved HEAD,
configured paths) prevent verification and are reported, with evidence
preserved.

Deferred (see docs/roadmap.md):

- full spec-to-code drift verification CLI, GitHub Action gates, MCP server,
additional production runners (codex/ollama/openai-compatible remain
honest stubs), parallel task execution.

## 0.2.0

- Offline Kiro-compatible spec creation: `spec new` renders plain-Markdown
Expand Down
143 changes: 109 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,19 @@ Working today (fully offline, no model, no API key):
| `specbridge spec show <name>` | Spec summary; `--file`, `--raw`, `--state`, `--analysis`, `--status`, `--json` |
| `specbridge spec context <name>` | Agent-ready context (`--format json`, `--target claude-code`) |
| `specbridge compat check [name]` | Prove the byte-identical no-op round trip |

Planned commands (`spec run/sync/verify/export`) are registered, marked
| `specbridge runner list / doctor / show` | **v0.3** — read-only runner diagnostics (executable, auth, capabilities) |
| `specbridge spec generate <name> --stage <s>` | **v0.3** — model-assisted stage drafting (result stays draft) |
| `specbridge spec refine <name> --stage <s>` | **v0.3** — model-assisted refinement with a unified diff |
| `specbridge spec run <name>` | **v0.3** — execute ONE approved task; evidence-gated checkbox completion |
| `specbridge spec accept-task <name> --task <id> --reason …` | **v0.3** — explicit, audited manual acceptance |
| `specbridge run list / show / resume` | **v0.3** — inspect append-only run records; resume interrupted sessions |

Planned commands (`spec sync/verify/export`) are registered, marked
"(planned)" in `--help`, and exit with an honest error — see the
[roadmap](docs/roadmap.md). Every command supports `--help` with examples.
Exit codes: `0` success · `1` workflow/verification failure · `2` usage or
configuration error · `3` runner unavailable · `4` runner failure ·
`5` timeout/cancel · `6` safety violation.

## Spec authoring and approval (v0.2)

Expand Down Expand Up @@ -248,20 +257,65 @@ guessing when none exists.

All four are created offline by `specbridge spec new` (since v0.2) and gated
by `spec approve` — see [docs/approval-workflow.md](docs/approval-workflow.md).
Runner-assisted content generation is a separate, later phase and will always
be opt-in.
Runner-assisted generation (since v0.3) is always explicit opt-in; offline
templates remain the default.

## Model-assisted authoring and task execution (v0.3)

With a locally installed, locally authenticated Claude Code CLI (or the
offline mock runner), SpecBridge can draft spec stages and execute approved
tasks — with the safety model doing the real work:

```sh
specbridge runner doctor claude-code

specbridge spec generate notification-preferences --stage requirements
specbridge spec analyze notification-preferences --stage requirements
specbridge spec approve notification-preferences --stage requirements

specbridge spec generate notification-preferences --stage design
specbridge spec approve notification-preferences --stage design
specbridge spec generate notification-preferences --stage tasks
specbridge spec approve notification-preferences --stage tasks

specbridge spec run notification-preferences --task 2.3
specbridge run show <run-id>
```

How it stays safe (details: [task execution](docs/task-execution.md),
[evidence](docs/execution-evidence.md), [verification](docs/task-verification.md),
[security](docs/security.md)):

- **SpecBridge does not include Claude usage.** You install and authenticate
Claude Code yourself; SpecBridge only invokes the local executable and
never stores, proxies, or prints credentials.
- **Model output is never proof.** The repository state is captured before
and after every run; the model's reported files/tests are stored as
claims and cross-checked against actual git evidence.
- **Task completion requires evidence.** The checkbox flips only after
trusted verification commands (from `.specbridge/config.json`, argv
arrays, never from spec content or model output) pass — or after explicit,
audited manual acceptance with a reason.
- **Generated stages are never auto-approved**, approved stages are never
overwritten, and one task runs per invocation (`--all` is sequential and
stops at the first unverified task).
- **SpecBridge never enables `bypassPermissions`** or any permission-skip
flag — rejected at three layers — and never commits, pushes, or rolls
back your repository.

## Claude Code integration

`specbridge spec context <name> --target claude-code` produces a single
document with steering, spec content, task progress, and working agreements
(surgical checkbox edits, `.kiro` is the source of truth, run
`compat check` after edits).
Two directions, both covered in
[docs/claude-code-integration.md](docs/claude-code-integration.md):

A Claude Code skill wrapping the CLI lives at
[integrations/claude-code/skills/specbridge](integrations/claude-code/skills/specbridge/SKILL.md).
The CLI remains the product core; the skill is a thin wrapper.
More: [docs/claude-code-integration.md](docs/claude-code-integration.md).
- **SpecBridge invokes Claude Code** (v0.3): `spec generate/refine/run` use
your locally installed, locally authenticated `claude` CLI as a runner —
see [docs/claude-code-runner.md](docs/claude-code-runner.md).
- **Claude Code drives SpecBridge**: `spec context --target claude-code`
produces agent-ready context, and a skill wrapping the CLI lives at
[integrations/claude-code/skills/specbridge](integrations/claude-code/skills/specbridge/SKILL.md).
The CLI remains the product core; the skill is a thin wrapper that never
bypasses approval gates or edits checkboxes itself.

## Spec drift verification

Expand Down Expand Up @@ -297,32 +351,43 @@ require one.

| Runner | Status |
| --- | --- |
| `mock` | ✅ Implemented — offline, deterministic, used by tests |
| `claude-code` | 🚧 Detection only (`isAvailable`); generation lands in Phase F |
| `codex` | 🚧 Detection only; generation lands in Phase F |
| `mock` | ✅ Implemented — offline, deterministic, scenario-driven, used by CI |
| `claude-code` | ✅ **v0.3** — local CLI runner: generation, refinement, task execution, resume |
| `codex` | ❌ Stub — honestly not implemented (roadmap) |
| `ollama` | ❌ Stub — honestly not implemented |
| `openai-compatible` | ❌ Stub — honestly not implemented |

Configuration lives in `.specbridge/config.json`
([docs/runner-adapters.md](docs/runner-adapters.md)). Never commit API keys.
([docs/agent-runners.md](docs/agent-runners.md)). Never commit API keys;
SpecBridge stores no credentials of any kind.

## Security and privacy

- Default commands are read-only and fully offline; no telemetry, no network.
- Writes (later phases) are atomic, path-checked against traversal, and
confined to the workspace.
- Spec content is treated as data — never executed as shell commands or
trusted as instructions.
- Writes are atomic, path-checked against traversal, and confined to the
workspace; symlinks are never followed out of the repository.
- Spec content and model output are treated as data — never executed as
shell commands or trusted as instructions.
- Runner execution is always explicit; verification commands come from
trusted project configuration, never from model output.
- Logs never include secrets or environment variables.

## Limitations (v0.2)

- Task execution, sync, drift-verification CLI, and export are not
implemented yet (they fail honestly; the drift library primitives exist).
- `spec new` renders offline templates only — no model writes content in
v0.2, by design. Runner-assisted generation is a future opt-in.
trusted project configuration (argv arrays, no shell), never from model
output; permission bypasses are rejected at three layers.
- No credentials are ever collected, stored, or printed; logs never include
secrets or environment variables.
- Full model: [docs/security.md](docs/security.md).

## Limitations (v0.3)

- Sync, the drift-verification CLI, and export are not implemented yet (they
fail honestly; the drift library primitives exist). v0.3 does **not** yet
implement full spec-to-code drift analysis.
- Claude Code is the only production runner; codex/ollama/openai-compatible
remain stubs. Claude usage happens under your own account and plan.
- Task execution requires a git repository, sidecar workflow state, and
fully approved stages — by design; there is no force flag.
- Tasks can only auto-verify when verification commands are configured;
with none configured, runs end `implemented-unverified`.
- One task per run; `--all` is strictly sequential. Parallel execution,
agent teams, sandboxing, and automatic rollback are out of scope for v0.3.
- Analysis is deterministic and structural; it cannot judge whether
requirements are *good*, only whether they are well-formed and complete.
- Workflow order cannot be inferred without sidecar state (reported as
Expand All @@ -336,10 +401,13 @@ Configuration lives in `.specbridge/config.json`
## Roadmap

v0.1: read-only compatibility, doctor, listing, context, round-trip proof.
v0.2 (this release): offline spec authoring, deterministic analysis,
hash-based approvals, stale-approval detection. Next: runner adapters (F),
task execution with evidence (G), sync + drift verification (H), GitHub
Action (I), Claude Code skill polish (J), optional MCP server (K).
v0.2: offline spec authoring, deterministic analysis, hash-based approvals,
stale-approval detection. v0.3 (this release): agent runner contract, the
Claude Code local runner, model-assisted generation/refinement, approved
task execution with git snapshots, trusted verification, append-only
evidence, verified-only checkbox completion, manual acceptance, and
resumable sessions. Next: sync + drift verification CLI (H), GitHub Action
gates (I), more runners, optional MCP server (K).
Full detail: [docs/roadmap.md](docs/roadmap.md).

## Documentation
Expand All @@ -350,8 +418,15 @@ Full detail: [docs/roadmap.md](docs/roadmap.md).
[Spec analysis](docs/spec-analysis.md) ·
[Approval workflow](docs/approval-workflow.md) ·
[Sidecar state](docs/sidecar-state.md) ·
[Agent runners](docs/agent-runners.md) ·
[Claude Code runner](docs/claude-code-runner.md) ·
[Model-assisted authoring](docs/model-assisted-authoring.md) ·
[Task execution](docs/task-execution.md) ·
[Execution evidence](docs/execution-evidence.md) ·
[Task verification](docs/task-verification.md) ·
[Session resume](docs/session-resume.md) ·
[Security](docs/security.md) ·
[Spec drift](docs/spec-drift.md) ·
[Runner adapters](docs/runner-adapters.md) ·
[Claude Code integration](docs/claude-code-integration.md) ·
[Migration from Kiro](docs/migration-from-kiro.md) (spoiler: there is none) ·
[Roadmap](docs/roadmap.md) ·
Expand Down
113 changes: 113 additions & 0 deletions docs/agent-runners.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Agent runners

Runners make SpecBridge model- and agent-agnostic: a runner wraps one way of
invoking an AI coding agent. Default SpecBridge commands never require one;
runner execution is always explicit.

## The contract (v0.3)

Every runner implements the same model-agnostic contract
(`@specbridge/runners`):

| Method | Purpose |
| --- | --- |
| `detect(context)` | Read-only probe: executable, version, authentication, capabilities |
| `generateStage(input, execution)` | Draft one spec stage (returns Markdown in structured output) |
| `executeTask(input, execution)` | Implement exactly one approved task |
| `resumeTask?(input, execution)` | Continue an interrupted session (optional capability) |

Runners return **structured observations only**. A runner never updates task
checkboxes and never decides whether evidence is sufficient — execution
orchestration lives in `@specbridge/execution` and evidence evaluation in
`@specbridge/evidence`. Everything a model reports (`changedFiles`,
`commandsReported`, `testsReported`) is treated as an unverified claim.

### Runner kinds and statuses

Kinds: `mock` (offline, deterministic), `claude-code` (local Claude Code
CLI), `unsupported` (honest stubs: `codex`, `ollama`, `openai-compatible` —
documented on the [roadmap](roadmap.md), not implemented, never faked).

Detection statuses: `available`, `unavailable`, `unauthenticated`,
`incompatible`, `misconfigured`, `error`. Only `available` permits
execution; every other status comes with actionable diagnostics.

Execution outcomes: `completed`, `blocked`, `failed`, `cancelled`,
`timed-out`, `permission-denied`, `malformed-output`, `no-change`.

## CLI

```sh
specbridge runner list # all runners with status
specbridge runner doctor claude-code # deep read-only diagnosis
specbridge runner show claude-code # effective configuration
```

All three are read-only and support `--json`. `runner doctor` exits `0`
when the runner is available and `3` otherwise.

## Configuration

Runners are configured in `.specbridge/config.json` (versioned schema
`1.0.0`; a v0.2 config file keeps working — every new field has a safe
default):

```json
{
"schemaVersion": "1.0.0",
"defaultRunner": "claude-code",
"runners": {
"claude-code": {
"enabled": true,
"command": "claude",
"model": null,
"maxTurns": 30,
"timeoutMs": 1800000,
"permissionMode": "acceptEdits",
"tools": ["Read", "Glob", "Grep", "Edit", "Write", "Bash"],
"allowedBashRules": ["Bash(git status *)", "Bash(pnpm test *)"]
},
"mock": { "scenario": "success" }
},
"verification": {
"commands": [
{ "name": "test", "argv": ["pnpm", "test"], "timeoutMs": 600000, "required": true }
]
},
"execution": {
"requireCleanWorkingTree": true,
"stopOnUnverifiedTask": true,
"capturePatch": true,
"maximumPatchBytes": 10485760,
"protectedPaths": []
}
}
```

Validation is fail-closed and enforces the safety rules:

- commands are **argv arrays** — a shell string like `["pnpm test"]` is
rejected outright, and no shell is ever invoked
- null bytes and path traversal are rejected
- `bypassPermissions` and `dangerously-skip-permissions` are rejected
wherever they appear; there is no override
- an invalid config file refuses execution instead of degrading silently

Never commit API keys; SpecBridge stores no credentials of any kind.

## The mock runner

`mock` is fully offline and deterministic: identical input produces
identical output. Its configured `scenario` selects the behavior — including
deliberately bad behaviors (`malformed-output`, `protected-path`,
`modify-tasks-doc`, `timeout`, `claims-untested`, `resume-failure`, …) so
the safety layers around runners are testable end to end. CI runs entirely
on the mock runner plus a fake Claude CLI process fixture; it never needs a
real Claude installation or network access.

## Related

- [Claude Code runner](claude-code-runner.md)
- [Model-assisted authoring](model-assisted-authoring.md)
- [Task execution](task-execution.md)
- [Security model](security.md)
Loading
Loading