@giamme/forge 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +106 -1766
  3. package/SKILL.md +3 -2
  4. package/VERSION +1 -1
  5. package/docs/README.md +26 -0
  6. package/docs/add-ons.md +33 -0
  7. package/docs/artifacts.md +69 -0
  8. package/docs/commands.md +315 -0
  9. package/docs/dataset.md +20 -0
  10. package/docs/decomposed-runs.md +268 -0
  11. package/docs/development.md +95 -0
  12. package/docs/forge-ui.md +92 -0
  13. package/docs/fractal.md +181 -0
  14. package/docs/install.md +160 -0
  15. package/docs/memory.md +156 -0
  16. package/docs/models.md +118 -0
  17. package/docs/reviews.md +231 -0
  18. package/docs/safety.md +55 -0
  19. package/docs/troubleshooting.md +54 -0
  20. package/forge +5 -0
  21. package/package.json +3 -2
  22. package/references/decompose.md +1 -1
  23. package/references/fractal.md +1 -1
  24. package/references/harnesses.md +18 -6
  25. package/references/solo.md +1 -1
  26. package/scripts/forge-dispatch.sh +7 -1
  27. package/scripts/forge-runs.py +121 -0
  28. package/scripts/forge-runtime.py +59 -6
  29. package/scripts/forge-version.py +54 -12
  30. package/scripts/forge_dataset/harvest.py +1 -1
  31. package/scripts/forge_dataset/importer.py +1 -1
  32. package/scripts/forge_fractal/__init__.py +2 -1
  33. package/ui/README.md +80 -20
  34. package/ui/THIRD_PARTY_NOTICES.md +108 -0
  35. package/ui/docs/api.md +99 -17
  36. package/ui/forge_ui/export.py +16 -6
  37. package/ui/forge_ui/fractal.py +1 -2
  38. package/ui/forge_ui/reader.py +95 -7
  39. package/ui/forge_ui/server.py +10 -1
  40. package/ui/forge_ui/static/D-DINCondensed-Bold.woff2 +0 -0
  41. package/ui/forge_ui/static/app.js +279 -124
  42. package/ui/forge_ui/static/cloud3d.js +3 -2
  43. package/ui/forge_ui/static/cloudui.js +8 -5
  44. package/ui/forge_ui/static/convo.js +295 -0
  45. package/ui/forge_ui/static/datatable.js +232 -0
  46. package/ui/forge_ui/static/diffview.js +29 -10
  47. package/ui/forge_ui/static/findings3d.js +134 -0
  48. package/ui/forge_ui/static/graph.js +3 -3
  49. package/ui/forge_ui/static/icons.js +94 -0
  50. package/ui/forge_ui/static/index.html +25 -13
  51. package/ui/forge_ui/static/iso.js +70 -19
  52. package/ui/forge_ui/static/leaderboard.js +44 -48
  53. package/ui/forge_ui/static/panel.js +68 -32
  54. package/ui/forge_ui/static/runmodel.js +17 -1
  55. package/ui/forge_ui/static/scene3d.js +518 -43
  56. package/ui/forge_ui/static/search.js +2 -1
  57. package/ui/forge_ui/static/shell.js +137 -0
  58. package/ui/forge_ui/static/stagectl.js +150 -0
  59. package/ui/forge_ui/static/style.css +924 -469
  60. package/ui/forge_ui/static/theme.js +25 -0
  61. package/ui/forge_ui/transcripts.py +608 -0
package/SKILL.md CHANGED
@@ -29,8 +29,9 @@ For explanation requests, explain the workflow without spending model quota.
29
29
  or `forge-solo.sh` and relay the `forge-ui:` URL they print. Never ask on resume or retry;
30
30
  unattended runs leave it off. A UI failure never changes the run. Read [forge-ui](references/ui.md).
31
31
  - A finished solo run, `plan` or `run` may end with one stderr line, `forge X is available
32
- (you have Y): forge update` (checked at most once a day). Relay it once; run the update only
33
- when the user asks (`forge update`, then restart the harness session). `FORGE_UPDATE_CHECK=off` silences it.
32
+ (you have Y): <command>` (checked at most once a day; the command is `forge update`, or npm's
33
+ for an npm installation). Relay it once; run the update only when the user asks (that
34
+ command, then restart the harness session). `FORGE_UPDATE_CHECK=off` silences it.
34
35
  - `--fractal-auto-decompose` enables automatic split-or-atomic decisions before each
35
36
  eligible node implements. Include the effective planner and bounds in the approval
36
37
  preview; child decisions need no additional user approval inside those bounds.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8
1
+ 0.9
package/docs/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # forge documentation
2
+
3
+ [← README](../README.md)
4
+
5
+ The README is the short overview. These pages hold the rest, one topic each.
6
+
7
+ | Page | What's in it |
8
+ |---|---|
9
+ | [Install and update](install.md) | npm or a git checkout, the doctor, what the installer does per CLI, updating |
10
+ | [Command reference](commands.md) | every `/forge` flag with examples, the `forge` command, the runner scripts and their exit codes |
11
+ | [Models, efforts and harnesses](models.md) | the `alias:effort:harness` spec, effort ladders and clamping, yolo mode, the model registry |
12
+ | [Decomposed runs](decomposed-runs.md) | decompose levels and difficulty, routing, waves, capsules, planning, resuming, split and combine, `tasks.tsv` |
13
+ | [Reviews, retries and recovery](reviews.md) | verdicts, retries, infrastructure stops, severity thresholds, accepting, whole-run and shadow reviews, guards, verification, fail-first |
14
+ | [Fractal execution](fractal.md) | the optional nested-execution backend: install, run, inspect, bounds and recovery |
15
+ | [Project memory](memory.md) | `.forge/memory.md` and the ledger, what each role is told, whether to commit it, spend |
16
+ | [forge-ui](forge-ui.md) | the run viewer: commands, the shared server, environment variables, privacy |
17
+ | [Run dataset](dataset.md) | every run's inputs and outcomes, kept for training decision models |
18
+ | [Run artifacts](artifacts.md) | the run directory, a plan's files, worktrees and branches |
19
+ | [Safety](safety.md) | what forge never does to your branch, preconditions, execution integrity |
20
+ | [Ripwire and Jev](add-ons.md) | optional repository context and advisory judgments |
21
+ | [Troubleshooting](troubleshooting.md) | symptoms, causes and fixes |
22
+ | [Development](development.md) | repository layout, offline checks, runtime measurement |
23
+
24
+ Deeper material that the skill itself reads lives in [`references/`](../references/): the
25
+ per-harness details, the decomposition and Fractal contracts, memory internals, Jev and the
26
+ dataset schema.
@@ -0,0 +1,33 @@
1
+ # Ripwire and Jev
2
+
3
+ [← README](../README.md) · [All docs](README.md)
4
+
5
+ Two optional add-ons: Ripwire adds repository evidence to every prompt, and Jev gives advisory judgments. forge works without either.
6
+
7
+ ## Ripwire context
8
+
9
+ Forge automatically adds optional Ripwire 0.4.0 repository evidence to planner, dwarf,
10
+ and QA prompts across all six harnesses. Setup and interactive runners offer a pinned,
11
+ verified installation; headless runs continue when it is missing. Use `--no-ripwire`
12
+ or `FORGE_RIPWIRE=off` to disable it. Decomposed plans preserve opt-out across resumes
13
+ and retries. See [installation, controls and attempt artifacts](../references/ripwire.md).
14
+
15
+ ## Jev
16
+
17
+ Jev is TypeSafe's "System One" model. It answers narrow, typed questions over the state it is
18
+ given, quickly and with calibrated probabilities. forge can ask it for advice on routing, test
19
+ selection, gates and memory curation. That advice sits beside forge's own decisions and never
20
+ replaces a model choice, a test run, a review or verification.
21
+
22
+ It is **off by default**. Each enabled capability sends a narrow slice of the run to an external
23
+ API: task prompts, diff hunks, test names or memory text, and never `.forge/` or `.git`. The
24
+ installer offers setup and declines by default.
25
+
26
+ ```sh
27
+ forge jev setup # store an API key
28
+ forge jev status # resolved config and enabled capabilities
29
+ forge jev enable [--capability NAME] # turn it on, optionally for one capability
30
+ ```
31
+
32
+ Chosen sites can go to Cloudflare's hosted Clef instead (`forge jev setup --provider cloudflare`).
33
+ The [full Jev reference](../references/jev.md) covers capabilities, privacy and backtests.
@@ -0,0 +1,69 @@
1
+ # Run artifacts
2
+
3
+ [← README](../README.md) · [All docs](README.md)
4
+
5
+ What a run leaves on disk: the run directory, a decomposed plan's files, and where worktrees and branches live.
6
+
7
+ Each stage writes into the run directory, which lives **outside** the repo — anything forge
8
+ writes inside the working tree would show up in the dwarf's own diff and land in front of qa
9
+ as if the dwarf had written it.
10
+
11
+ ```
12
+ <run-dir>/
13
+ <role>.resolved what the spec resolved to (model, effort, harness, any clamp)
14
+ <role>.prompt the exact prompt sent
15
+ <role>.cmd the exact command line executed
16
+ <role>.log full transcript
17
+ <role>.last the final message — read this first
18
+ <role>.infra only after an infrastructure failure: class, retry_after, detail
19
+ <role>.orphans only when processes were left running after the harness exited
20
+ changes.diff the dwarf's real diff, which is qa's input
21
+ ```
22
+
23
+ A solo run also records, for forge-ui and for you:
24
+
25
+ ```
26
+ <run-dir>/
27
+ status RUNNING, then PASS|FAIL|UNKNOWN|NOCHANGES|INVALIDATED|TIMEOUT|INFRA|INTERRUPTED|ERROR
28
+ dwarf.spec, qa.spec the specs the run was given
29
+ attempts.tsv epoch, attempt number, status, infrastructure class, dwarf spec; one row per invocation
30
+ ```
31
+
32
+ Plus, in the repo itself and surviving the run:
33
+
34
+ ```
35
+ .forge/memory.md what forge learned here, injected into future prompts
36
+ .forge/ledger.tsv one row per dispatch, ever; never injected
37
+ ```
38
+
39
+ A decomposed run adds:
40
+
41
+ ```
42
+ <plan-dir>/
43
+ goal.txt
44
+ tasks.tsv
45
+ waves.tsv, deferrals.txt
46
+ tasks/<id>/{capsule.md,prompt.md,dwarf.*,qa.*,changes.diff,status}
47
+ tasks/<id>/attempt, attempts.tsv attempts spent; one audit row per entry (incl. refunded stops)
48
+ tasks/<id>/known_issues.md, qa.gate findings tolerated by --qa-threshold, and the gate's decision
49
+ tasks/<id>/guard.txt what forge observed about the implementer (self-commit, orphans, promises)
50
+ tasks/<id>/infra.txt, resume, noretry infrastructure stop record; QA-only resume marker; no-progress marker
51
+ tasks/<id>/qa_threshold optional per-task blocking threshold
52
+ results.tsv id status branch
53
+ timeout, qa_threshold, verify_retries options remembered from run/retry flags
54
+ integration.base commit the integration branch started from
55
+ verification.{status,exit,log,command,fingerprint} the combined verification
56
+ verification.{flaky,retry.log} only when a failing command passed on rerun
57
+ verification.coverage.txt suites the verify command does not run (advisory)
58
+ ```
59
+
60
+ with worktrees and branches at:
61
+
62
+ ```
63
+ <repo>/../.forge-worktrees/<run-id>/<task-id> worktree
64
+ forge/<run-id>/<task-id> task branch
65
+ forge/<run-id>-integration integration branch
66
+ ```
67
+
68
+ The worktree root is a **sibling of the repo, never `TMPDIR`**. Isolated worktrees are never
69
+ pushed, so a temp root that gets cleaned takes the only copy of that work with it.
@@ -0,0 +1,315 @@
1
+ # Command reference
2
+
3
+ [← README](../README.md) · [All docs](README.md)
4
+
5
+ Every flag of the `/forge` slash command, the `forge` command, and the scripts the skill runs underneath.
6
+
7
+ ## The `forge` command
8
+
9
+ npm puts `forge` on your `PATH`; in a git checkout it is `./forge`. Runs start from your agent
10
+ harness (`/forge`); this command installs forge and drives its optional tools.
11
+
12
+ | Command | Does |
13
+ |---|---|
14
+ | `forge install [--dry-run]` | link forge into each agent harness on this machine; see [install](install.md) |
15
+ | `forge update` | fast-forward a git checkout and refresh every harness installation; on an npm install it names the npm command instead. See [updating](install.md#updating-all-harness-installations) |
16
+ | `forge version [--check]` | the installed version, and whether a newer release is out |
17
+ | `forge fractal …` | opt-in Fractal execution; see [the command group](fractal.md#forge-fractal-command-group) |
18
+ | `forge runs [--repo DIR \| --all] [--limit N] [--json]` | this repo's recent runs, newest first: run id, kind, age, task states, verification and final review, goal, and the run dir. Read-only; the same summaries forge-ui shows |
19
+ | `forge ui open\|status\|stop` | forge-ui, the run viewer; see [the command group](forge-ui.md#forge-ui-command-group) |
20
+ | `forge dataset …` | every run's inputs and outcomes; see [run dataset](dataset.md) |
21
+ | `forge jev …` | optional Jev advice: setup, status, doctor, enable, disable, backtest; see [Jev](add-ons.md#jev) |
22
+ | `forge --help` | list the commands; `forge <command> --help` shows each one's options |
23
+
24
+ ## The `/forge` slash command
25
+
26
+ ```
27
+ /forge "<goal>" --dwarf <alias>[:<effort>[:<harness>]]
28
+ [--qa <alias>[:<effort>[:<harness>]]]
29
+ [--planner <alias>[:<effort>[:<harness>]]]
30
+ [--yolo-dwarf] [--yolo-qa] [--repo <dir>] [--native-review]
31
+ [--no-memory] [--timeout <seconds>] [--ui | --no-ui] [--fractal | --no-fractal]
32
+ [--fractal-auto-decompose] [--fractal-planner <spec>]
33
+ [--fractal-depth <n>] [--fractal-children <n>] [--fractal-nodes <n>]
34
+ [--fractal-iterations <n>] [--fractal-concurrency <n>] [--fractal-deadline <s>]
35
+ [--decompose-level low|medium|high] [--max-parallel <n>]
36
+ [--dwarf-high <spec>] [--dwarf-medium <spec>] [--dwarf-low <spec>]
37
+ [--qa-high <spec>] [--qa-medium <spec>] [--qa-low <spec>]
38
+ ```
39
+
40
+ | Flag | Default | Meaning |
41
+ |---|---|---|
42
+ | `--dwarf <spec>` | *asks* | the model that implements the change |
43
+ | `--qa <spec>` | `opus` at `xhigh` | the model that reviews the dwarf's diff |
44
+ | `--planner <spec>` | orchestrator plans | dispatch planning to a model; one dispatch per run, effort defaults to `xhigh` |
45
+ | `--no-memory` | memory on | write and inject nothing in `.forge/` |
46
+ | `--timeout <s>` | `2700` (45m) | kill any single dispatch that runs longer. `0` disables |
47
+ | `--yolo-dwarf` | off | drop the dwarf's sandbox and approval gates |
48
+ | `--yolo-qa` | off | drop the reviewer's sandbox |
49
+ | `--repo <dir>` | cwd | repository to work in |
50
+ | `--native-review` | off | use native Codex review against the recorded baseline instead of an inlined diff |
51
+ | `--decompose-level <l>` | off | split the goal into parallel tasks |
52
+ | `--max-parallel <n>` | `3` | concurrent task pipelines |
53
+ | `--dwarf-high/-medium/-low` | — | per-difficulty routing; comma-list pools models |
54
+ | `--qa-high/-medium/-low` | — | same, for reviewers |
55
+ | `--fractal` / `--no-fractal` | ask interactively; off unattended | mutually exclusive, per-run backend choice |
56
+ | `--fractal-auto-decompose` | off | enables Fractal with automatic recursive split-or-atomic decisions |
57
+ | `--fractal-planner <spec>` | top-level planner, then task root spec | frozen decision model; requires automatic mode |
58
+ | `--fractal-depth <n>` | `2` | nested levels below each Forge implementation node |
59
+ | `--fractal-children <n>` | `3` | unsettled direct children per node |
60
+ | `--fractal-nodes <n>` | `12` | lifetime nodes per Forge task, including implementation |
61
+ | `--fractal-iterations <n>` | `6` | per node per execution attempt |
62
+ | `--fractal-concurrency <n>` | `3` | shared model slots across nested trees and QA |
63
+ | `--fractal-deadline <s>` | `2700` | task attempt deadline, excluding explicit pauses |
64
+ | `--fractal-max-cost <amount>` | unsupported | returns an error; the bridge cannot enforce dollar caps |
65
+
66
+ Fractal's task deadline still applies when `--timeout 0` disables the ordinary
67
+ per-dispatch timeout. Child routing uses the dwarf tier flags; QA stays at the Forge
68
+ task boundary. Pools and Fractal limits are frozen for an existing run.
69
+
70
+ Before an interactive run, forge asks **“Use Fractal for this run? [y/N]”** once.
71
+ Pass `--fractal` or `--no-fractal` to answer explicitly; unattended runs default off.
72
+ It also asks **“Open forge-ui to watch this run? [y/N]”** (`--ui` / `--no-ui`); on a yes,
73
+ the [forge-ui](forge-ui.md) page opens as soon as the run exists. Resume and retry never ask.
74
+
75
+ For what `--native-review` trades away, see [native review](reviews.md#native-review).
76
+
77
+ ### Examples
78
+
79
+ ```bash
80
+ # minimum
81
+ /forge "make the cache key include the tenant id" --dwarf sol:high
82
+
83
+ # both roles named, reviewer thinking harder than the implementer
84
+ /forge "rewrite the rate limiter as a token bucket" --dwarf luna:max --qa sol:ultra
85
+
86
+ # same model, different CLI
87
+ /forge "extract the retry helper into its own module" --dwarf sol:high:openclaude
88
+
89
+ # Gemini as the dwarf, unsandboxed so it can actually run the tests it writes
90
+ /forge "add table-driven tests for the parser" --dwarf gemini:high:antigravity --yolo-dwarf
91
+
92
+ # a cheap dwarf with an expensive reviewer
93
+ /forge "update all the docstrings to match the new signatures" --dwarf haiku --qa opus:max
94
+
95
+ # work in another repo
96
+ /forge "bump the pinned deps and fix the fallout" --dwarf sol:xhigh --repo ~/dev/other-project
97
+
98
+ # large refactor, reviewed by codex's native reviewer
99
+ /forge "split the god object into three services" --dwarf sol:ultra --qa sol:ultra --native-review
100
+
101
+ # parallel, one dwarf for every task
102
+ /forge "add CRUD endpoints for projects, users and teams" \
103
+ --decompose-level medium --dwarf sol:high
104
+
105
+ # parallel, routed by difficulty, wider fan-out
106
+ /forge "migrate the whole API layer from REST to gRPC" \
107
+ --decompose-level high --max-parallel 5 \
108
+ --dwarf-high sol:ultra --dwarf-medium luna:high --dwarf-low haiku:medium \
109
+ --qa-high opus:max --qa sonnet:high
110
+
111
+ # pool two providers on the hard tier so neither quota carries it alone
112
+ /forge "implement the new billing rules across the codebase" \
113
+ --decompose-level medium \
114
+ --dwarf-high sol:xhigh,terra:xhigh --dwarf luna:high
115
+
116
+ # a model that thinks for a long time; raise the per-dispatch backstop
117
+ /forge "prove the scheduler cannot deadlock, and fix it if it can" \
118
+ --dwarf sol:ultra --timeout 7200
119
+ ```
120
+
121
+ After a decomposed run, a task that failed review can be re-run on its own — with the
122
+ findings that failed it, on a stronger model:
123
+
124
+ ```bash
125
+ bash scripts/forge-parallel.sh retry /tmp/forge-billing pricing --dwarf sol:ultra
126
+ ```
127
+
128
+ ## `scripts/forge-dispatch.sh`
129
+
130
+ Resolves a spec into a real CLI invocation and runs it. Needs only bash and coreutils, which
131
+ is the point: it behaves identically no matter which harness is orchestrating.
132
+
133
+ ```
134
+ forge-dispatch.sh doctor
135
+ forge-dispatch.sh dwarf <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--yolo] [--dry-run]
136
+ forge-dispatch.sh qa <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--yolo] [--dry-run]
137
+ [--native-review [--review-base <ref>]]
138
+ forge-dispatch.sh planner <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--dry-run]
139
+ ```
140
+
141
+ | Option | Meaning |
142
+ |---|---|
143
+ | `--prompt-file <f>` | file holding the prompt (required for `dwarf`/`qa`) |
144
+ | `--repo <dir>` | repository the role operates in |
145
+ | `--run-dir <d>` | where prompts, logs and results are written |
146
+ | `--yolo` | bypass sandbox and approvals for this role |
147
+ | `--dry-run` | resolve and print the command; run nothing |
148
+ | `--native-review` | qa only; use codex's built-in reviewer |
149
+ | `--review-base <ref>` | qa only; base ref for the native review |
150
+ | `--agy-timeout <s>` | antigravity `--print-timeout` (long runs need this raised) |
151
+ | `--timeout <s>` | kill this dispatch after `<s>` seconds; `0` disables. See the precedence below |
152
+
153
+ **Exit codes:** `0` ok · `2` spec or usage error · `3` harness missing or unusable ·
154
+ `4` the backend ran and failed · `7` the backend hit its timeout and was killed ·
155
+ `8` an **infrastructure failure** (quota or usage limit, auth, rate limit, network, or an
156
+ empty answer) — nothing about the work was judged, so callers pause instead of counting a
157
+ failure. On `8`, `<run-dir>/<role>.infra` holds `class=`, `retry_after=`, `detail=`, `rc=`,
158
+ `role=`.
159
+
160
+ **Timeout precedence.** An explicit `--timeout`, then `FORGE_TIMEOUT` (an explicit `0` wins
161
+ and disables the watchdog), then the optional fifth `timeout` column of the model's
162
+ [registry](models.md#model-registry) row, then the built-in `2700` (45 min). A value that was *not*
163
+ explicit is scaled by the resolved (post-clamp) effort: up to `high` ×1, `xhigh` ×4/3,
164
+ `max`/`ultra`/`ultracode` ×2. QA and planner default to `xhigh`, so their built-in limit is
165
+ 3600 s; dwarves default to `medium` and keep 2700 s. `<role>.resolved` records `timeout=` and
166
+ `timeout_source=` (`explicit`, `env`, `registry` or `default`, plus `+effort-scaled`).
167
+ `forge-parallel.sh run`/`retry --timeout S` sets it for a decomposed run (kept in the plan).
168
+ `FORGE_REGISTRY` points the dispatcher at an alternative registry file.
169
+
170
+ Only antigravity bounds its own runtime, and stock macOS has no `timeout` binary to wrap the
171
+ others in — so a hung backend used to block forever, and under a decomposed run one hung task
172
+ silently stalled the others. The default is deliberately generous: this is a backstop against
173
+ a wedged process, not a budget. A role killed by it has usually left a partial edit behind, so
174
+ `7` is worth reporting as such rather than as a clean failure.
175
+
176
+ On `3` or `4`, forge shows you the actual error rather than substituting a different model —
177
+ quietly swapping backends hides the fact that the one you picked is broken.
178
+
179
+ **Process hygiene.** Unless `FORGE_ORPHAN_GUARD=off` (or the run is a Fractal one), the harness
180
+ is started in its own session, and after it exits any process still alive in that session is
181
+ listed in `<role>.orphans` and stopped, so a backgrounded measurement cannot outlive the
182
+ dispatch. The timeout watchdog and the exit trap signal the whole session too.
183
+
184
+ ```bash
185
+ # what would this actually run?
186
+ bash scripts/forge-dispatch.sh dwarf sol:ultra --prompt-file /tmp/p --dry-run
187
+
188
+ # check a clamp before committing to a long run
189
+ bash scripts/forge-dispatch.sh qa gemini-pro:medium --prompt-file /tmp/p --dry-run
190
+ # effort=low
191
+ # clamped=medium -> low (gemini-pro offers low and high, but no medium)
192
+ ```
193
+
194
+ ## `scripts/forge-solo.sh`
195
+
196
+ The whole single-task run: memory injection, prompt assembly, the dwarf dispatch, the diff
197
+ capture, the QA dispatch, and the ledger writes.
198
+
199
+ ```
200
+ forge-solo.sh <run-dir> --repo <dir> --dwarf <spec> [--qa <spec>]
201
+ [--approach <file>] [--yolo-dwarf] [--yolo-qa]
202
+ [--native-review] [--no-memory] [--timeout <s>] [--dry-run] [--ui | --no-ui]
203
+ [--fail-first]
204
+ [--fractal | --no-fractal] [--fractal-<limit> <n>]
205
+ [--dwarf-low <pool>] [--dwarf-medium <pool>] [--dwarf-high <pool>] [--retry]
206
+ ```
207
+
208
+ You write two files into the run directory; forge does the rest:
209
+
210
+ | You write | Is |
211
+ |---|---|
212
+ | `prompt.md` | the implementation instruction (required) |
213
+ | `goal.txt` | one line, what was asked — given to the reviewer as intent (optional) |
214
+
215
+ | It writes | Is |
216
+ |---|---|
217
+ | `dwarf.last` / `qa.last` | each role's final message |
218
+ | `changes.diff` | exactly what the reviewer read |
219
+ | `verdict` | `PASS`, `FAIL`, `UNKNOWN` or `NOCHANGES` |
220
+ | `<role>.{input,log,resolved,cmd}` | the prompt, the transcript, the resolution, the command |
221
+ | `fractal-selection.json` | persisted backend choice; enabled runs include their managed run ID |
222
+
223
+ With Fractal, per-step dispatch artifacts live in the managed run while the solo directory
224
+ retains the aggregate diff and Forge QA result. `--retry` starts a new Fractal attempt;
225
+ `forge fractal resume RUN_ID` continues preserved execution and pipeline checkpoints.
226
+
227
+ ```bash
228
+ RUN="$(mktemp -d /tmp/forge-XXXXXX)"
229
+ echo "add retry with backoff to the HTTP client" > "$RUN/goal.txt"
230
+ echo "Add exponential backoff to src/http.py, capped at 5 attempts." > "$RUN/prompt.md"
231
+
232
+ bash scripts/forge-solo.sh "$RUN" --repo ~/dev/api --dwarf sol:high --qa opus
233
+ ```
234
+
235
+ **Exit codes:** `0` reviewed · `2` usage · `3` not a git repository · `4` a dispatch failed ·
236
+ `5` **no changes or review invalidated** · `7` a dispatch timed out · `8` a dispatch hit an
237
+ **infrastructure failure** (quota, auth, rate limit, network, empty output): nothing was
238
+ judged, fix the cause and run again. A dwarf that exits 0 with an empty answer *and* changes
239
+ nothing is reported as `8`, not `5` — it never really ran.
240
+
241
+ The dwarf is given the same implementer rules as in a decomposed run (no commits, no
242
+ background processes, finish measurements before the last message). If it commits anyway, the
243
+ run still reviews its changes, says so, and prints the `git reset --soft <old HEAD>` that would
244
+ turn them back into uncommitted changes; forge never resets anything itself. Orphan processes
245
+ and promised-later-work notes appear under "implementer guard notes".
246
+
247
+ `5` is the one worth recognising on sight. Headless dwarves genuinely stop to ask a
248
+ clarifying question that nothing can answer; the run ends having spent the quota and changed
249
+ nothing, with the question sitting in `dwarf.last`.
250
+
251
+ Two things it gets right that are easy to get wrong by hand, and that fail *silently* rather
252
+ than loudly:
253
+
254
+ - **`.forge/` is excluded from the capture.** Forge rewrites its own memory in the working
255
+ tree at the end of every run, so left in, it reaches the reviewer as a file the dwarf
256
+ appears to have touched — which a good reviewer correctly flags as scope creep.
257
+ - **New files are diffed against `/dev/null`.** A `git status` line says only `?? calc.py`.
258
+ A dwarf whose entire task was to add a file would have had its actual code reviewed by
259
+ nobody, while the run still reported a clean QA pass.
260
+
261
+ The run directory must live outside the repository — anything forge writes inside the working
262
+ tree shows up in the dwarf's own diff. `forge-solo.sh` refuses rather than letting that happen
263
+ quietly.
264
+
265
+ ## `scripts/forge-parallel.sh`
266
+
267
+ Decomposed runs: many dwarves in isolated worktrees, per-task QA, only passing work merged.
268
+ Bash 3.2 entrypoints use a Python standard-library coordinator to schedule eligible tasks.
269
+
270
+ ```
271
+ forge-parallel.sh plan <plan-dir> --repo <dir> [routing flags] [--planner <spec>] [--no-memory]
272
+ [--decompose-level L] [--shadow-qa <spec>[,..]|none] [--shadow-rate R]
273
+ [--explore E] [--ui | --no-ui] [--fail-first | --no-fail-first]
274
+ forge-parallel.sh run <plan-dir> [--max-parallel N] [--yolo-dwarf] [--yolo-qa] [--dry-run]
275
+ [--verify <cmd>] [--setup <cmd>] [--timeout S]
276
+ [--retry-failed N] [--infra-retries M]
277
+ [--qa-threshold P0|P1|P2|P3|none] [--verify-retries N]
278
+ [--fractal | --no-fractal] [--fractal-<limit> <n>]
279
+ forge-parallel.sh retry <plan-dir> <task-id> [--dwarf <spec>] [--timeout S]
280
+ [--qa-threshold Pn|none] [--verify-retries N]
281
+ forge-parallel.sh accept <plan-dir> <task-id> --reason "<why>" --approved
282
+ forge-parallel.sh review <plan-dir> [--qa <spec>] [--yolo-qa] [--qa-threshold Pn]
283
+ forge-parallel.sh integrate <plan-dir> --approved [--final-review <qa-spec>] [--verify-retries N]
284
+ forge-parallel.sh split <plan-dir> <new-plan-dir> --tasks <id,id> [--dry-run]
285
+ forge-parallel.sh combine <new-plan-dir> <plan-dir> <plan-dir>... [--verify <cmd>] [--dry-run]
286
+ ```
287
+
288
+ | Subcommand | Does |
289
+ |---|---|
290
+ | `plan` | validate `tasks.tsv`, resolve difficulty → concrete dwarf/qa specs, compute waves, render the approval table |
291
+ | `run` | schedule ready tasks; per task: worktree → dwarf → diff → QA → status; merge passing tasks onto the integration branch |
292
+ | `retry` | re-run **one** failed task in the worktree it already has, with its reviewer's findings in the prompt |
293
+ | `integrate` | **never automatic** — merge the integration branch into your branch |
294
+ | `accept` | **only on your explicit instruction** — merge a `FAIL`/`UNKNOWN` task's reviewed work anyway, recording why |
295
+ | `review` | **opt-in, spends QA quota** — one reviewer reads the whole combined result; read-only |
296
+ | `split` / `combine` | move tasks into a plan of their own / join fully merged plans into one |
297
+
298
+ | Flag | Subcommands | Remembered in the plan | Means |
299
+ |---|---|---|---|
300
+ | `--timeout S` | run, retry | `timeout` | per-dispatch timeout in seconds (`0` disables); wins over `FORGE_TIMEOUT` |
301
+ | `--retry-failed N` | run | no — this run only | re-queue a task the reviewer rejected up to `N` more times inside the run |
302
+ | `--infra-retries M` | run | no — this run only | wait out up to `M` infrastructure stops instead of pausing |
303
+ | `--qa-threshold Pn` | run, retry | `qa_threshold` | least severe finding that still blocks; milder ones become known issues; `none` clears |
304
+ | `--verify-retries N` | run, retry, integrate | `verify_retries` | reruns of a failed verify command (default `1`, `0` = strict single run) |
305
+
306
+ **Exit codes:** `0` ok · `2` usage or validation · `3` precondition (not a git repo, …) ·
307
+ `5` some task failed QA, or the combined verification failed · `6` integration conflict ·
308
+ `8` **paused on an infrastructure failure** (quota, auth, rate limit, network): no attempt was
309
+ spent and nothing was judged — fix the cause and run the same command again.
310
+
311
+ The full plan → run → integrate walkthrough is in [decomposed runs](decomposed-runs.md#plan-run-integrate). `retry`, `accept` and `review` are covered in [reviews, retries and recovery](reviews.md); resuming, `split`/`combine`, scope drift and `tasks.tsv` in [decomposed runs](decomposed-runs.md).
312
+
313
+ ## `scripts/forge-memory.sh` and `scripts/forge-install.sh`
314
+
315
+ See [project memory](memory.md#scriptsforge-memorysh) and [install](install.md#scriptsforge-installsh).
@@ -0,0 +1,20 @@
1
+ # Run dataset
2
+
3
+ [← README](../README.md) · [All docs](README.md)
4
+
5
+ Run dirs get deleted, and the ledger keeps spec strings and verdicts but no inputs. So
6
+ every run also records its raw inputs and outcomes outside every repo, in
7
+ `~/.local/share/forge/dataset/` (`FORGE_DATA_HOME` moves it, `FORGE_DATASET=off` turns
8
+ it off). That covers resolved models, prompts, per-attempt diffs, verdicts and findings,
9
+ tokens, merge and verification outcomes, and the full request behind every Jev judgment.
10
+ It exists to train and calibrate decision models on what forge actually did.
11
+
12
+ ```sh
13
+ forge dataset status # size, counts, and anything that looks incomplete
14
+ forge dataset import ~/.local/share/forge/legacy # runs that predate live capture
15
+ forge dataset export # labeled decision cases for benchmarks and fine-tuning
16
+ forge dataset outcomes # which integrated lines survived, read from git history
17
+ ```
18
+
19
+ Capture is fail-open and never read by anything that builds a prompt. See
20
+ [references/dataset.md](../references/dataset.md) for the event schema and its invariants.