THE LOOP signals → specs → code → reports
| hornero init [--hooks] [--no-sdd] [--no-wiki] |
Scaffold .hornero/ + sdd/ in any repo. Idempotent; never overwrites config. |
| cp notes.md .hornero/inbox/ |
Feed a signal: meeting notes, docs, ideas — any text file. |
| hornero reconcile --dry-run |
Preview proposed deltas. Guaranteed zero writes. |
| hornero reconcile |
Interactive review — approve/reject/edit/skip each delta. Needs a TTY; without one, nothing is applied. |
| hornero build [SPEC-ID] [--backend mock|cli] |
Approved specs → briefs → coding-agent backend. Every run leaves a trace. |
| hornero report [--only NAME] |
Regenerate sdd/reports/: capabilities · workflows · traceability. No-ops when current. |
| hornero reindex |
Rebuild the knowledge index (deterministic). Auto via --hooks post-merge. |
| hornero status |
Spec counts by state · pending inbox · index health. |
CONFIG .hornero/config.yaml
signal_sources: [inbox, git] # git = opt-in
tracker: repo
dispatch:
backend_order: [mock] # api never
# auto-added
models:
reconciler: fake:s.json
wiki: fake:s.json
scribe: fake:s.json
sdd_upstream: git@…/toolkit
sdd_ref: main
unknown keys fail closed
SDD TOOLKIT prompts as dependencies — sdd.lock, 3-way drift
| hornero sdd install --from SRC [--ref R] |
Install managed set + scaffold + lockfile. Adopts existing files, never clobbers. |
| hornero sdd status / diff [FILE] |
Drift table (one line per file) / unified diff vs upstream. |
| hornero sdd sync [--dry-run] [--force] |
Fast-forwards behind + new; diverged blocks (exit ≠ 0) until resolved. |
| hornero sdd sync --theirs F / --ours F |
Resolve a diverged file: upstream wins / local wins (lock re-baselined). |
| hornero sdd sync --push FILE… |
Promote improvements upstream via PR. Secret-scanned; never the default branch. |
| hornero sdd sync --workspace DIR |
Pull-sync every child repo carrying .hornero/sdd.lock; skips the rest. |
| hornero sdd hold|unhold|pin FILE |
Per-file policy: local (never pulled) · back to sync · frozen. |
DRIFT STATES U/L/C
current
behind → pull
modified → push?
diverged → human
deleted_locally → --force
new_upstream → install
held · pinned → skip
# U = upstream now
# L = lock (last sync)
# C = current on disk
# no timestamps, no
# "newest wins" — ever
WIKI for the next agent
| hornero wiki init |
First build: quickstart + areas, link-checked. |
| hornero wiki update |
Surgical, scoped to the git window. Empty window ⇒ zero model calls. |
needs models.wiki
no-op says “already current”
TRACES & DRs process truth
| hornero runs list [--spec S] |
Registered agent runs. |
hornero runs show REF --kind tool_use --range e#2:e#9 |
Exact event slices of a trace. |
| hornero runs adopt FILE.jsonl |
Adopt a Claude Code transcript. |
| hornero scribe REF [--force] |
Trace → DR-NNN. Citations verified or the claim is dropped. |
WHERE THINGS LIVE
sdd/specs/ the tracker
sdd/decisions/ ADRs + DRs
sdd/proposals/ brainstorms
sdd/reports/ HTML audit
wiki/ agent docs
.hornero/inbox/ signals in
.hornero/runs/ traces (ignored)
.hornero/sdd.lock committed
.hornero/watermarks.json committed
.hornero/ledger.db ignored
EXIT CODES
0 ok / already current
1 failure — or diverged files pending a human
2 precondition (no lock, unknown file)
3 no model configured
# reconcile without a TTY
# exits WITHOUT writing —
# that's the safety, not a bug