@giamme/forge 0.8.0 → 0.10.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.
- package/CHANGELOG.md +50 -0
- package/README.md +106 -1766
- package/SKILL.md +22 -3
- package/VERSION +1 -1
- package/docs/README.md +26 -0
- package/docs/add-ons.md +33 -0
- package/docs/artifacts.md +84 -0
- package/docs/commands.md +365 -0
- package/docs/dataset.md +29 -0
- package/docs/decomposed-runs.md +310 -0
- package/docs/development.md +95 -0
- package/docs/forge-ui.md +128 -0
- package/docs/fractal.md +181 -0
- package/docs/install.md +160 -0
- package/docs/memory.md +156 -0
- package/docs/models.md +118 -0
- package/docs/reviews.md +245 -0
- package/docs/safety.md +55 -0
- package/docs/troubleshooting.md +54 -0
- package/forge +20 -0
- package/package.json +3 -2
- package/references/dataset.md +18 -1
- package/references/decompose.md +20 -2
- package/references/fractal.md +1 -1
- package/references/harnesses.md +18 -6
- package/references/solo.md +1 -1
- package/references/ui.md +27 -5
- package/scripts/forge-config.py +347 -0
- package/scripts/forge-control.py +645 -0
- package/scripts/forge-dispatch.sh +7 -1
- package/scripts/forge-issues.py +806 -0
- package/scripts/forge-lib-task.sh +234 -35
- package/scripts/forge-parallel-options.sh +3 -1
- package/scripts/forge-parallel.sh +3 -2
- package/scripts/forge-route.py +184 -27
- package/scripts/forge-runs-rm.py +840 -0
- package/scripts/forge-runs.py +139 -0
- package/scripts/forge-runtime.py +59 -6
- package/scripts/forge-schedule.py +227 -11
- package/scripts/forge-ui.py +85 -19
- package/scripts/forge-version.py +54 -12
- package/scripts/forge_dataset/__init__.py +77 -6
- package/scripts/forge_dataset/capture.py +5 -2
- package/scripts/forge_dataset/harvest.py +23 -1
- package/scripts/forge_dataset/importer.py +420 -18
- package/scripts/forge_fractal/__init__.py +2 -1
- package/scripts/forge_registry.py +168 -16
- package/ui/README.md +116 -23
- package/ui/THIRD_PARTY_NOTICES.md +108 -0
- package/ui/docs/api.md +283 -23
- package/ui/forge_ui/__main__.py +10 -2
- package/ui/forge_ui/control.py +575 -0
- package/ui/forge_ui/export.py +33 -9
- package/ui/forge_ui/fractal.py +1 -2
- package/ui/forge_ui/reader.py +121 -8
- package/ui/forge_ui/server.py +135 -5
- package/ui/forge_ui/static/D-DINCondensed-Bold.woff2 +0 -0
- package/ui/forge_ui/static/app.js +358 -131
- package/ui/forge_ui/static/cloud3d.js +3 -2
- package/ui/forge_ui/static/cloudui.js +8 -5
- package/ui/forge_ui/static/controls.js +619 -0
- package/ui/forge_ui/static/convo.js +295 -0
- package/ui/forge_ui/static/datatable.js +232 -0
- package/ui/forge_ui/static/diffview.js +29 -10
- package/ui/forge_ui/static/findings3d.js +134 -0
- package/ui/forge_ui/static/findingsview.js +412 -0
- package/ui/forge_ui/static/graph.js +3 -3
- package/ui/forge_ui/static/icons.js +94 -0
- package/ui/forge_ui/static/index.html +31 -13
- package/ui/forge_ui/static/iso.js +70 -19
- package/ui/forge_ui/static/leaderboard.js +44 -48
- package/ui/forge_ui/static/panel.js +92 -36
- package/ui/forge_ui/static/rundelete.js +388 -0
- package/ui/forge_ui/static/runmodel.js +17 -1
- package/ui/forge_ui/static/scene3d.js +518 -43
- package/ui/forge_ui/static/search.js +2 -1
- package/ui/forge_ui/static/settings.js +399 -0
- package/ui/forge_ui/static/shell.js +137 -0
- package/ui/forge_ui/static/stagectl.js +150 -0
- package/ui/forge_ui/static/style.css +1099 -469
- package/ui/forge_ui/static/theme.js +25 -0
- package/ui/forge_ui/static/uikit.js +161 -0
- package/ui/forge_ui/transcripts.py +608 -0
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: forge
|
|
3
3
|
description: Dispatch implementation and independent diff review to user-selected models through local agent CLIs. Use for /forge or explicit requests to delegate coding or review; explanation-only questions do not authorize dispatch.
|
|
4
|
-
argument-hint: '"<goal>" --dwarf <alias>[:effort[:harness]] [--qa <alias>] [--planner <alias>] [--yolo-dwarf] [--yolo-qa] [--decompose-level low|medium|high] [--fractal|--no-fractal|--fractal-auto-decompose] [--fractal-planner <spec>] [--jev|--no-jev] [--jev-shadow] [--no-memory] [--no-ripwire] [--ui|--no-ui] [--timeout <seconds>] [--retry-failed <n>] [--escalate-after <n>] [--qa-threshold P0|P1|P2|P3] [--shadow-qa <spec>[,<spec>]] [--shadow-rate <0..1>] [--explore <0..0.5>] [--fail-first]'
|
|
4
|
+
argument-hint: '"<goal>" --dwarf <alias>[:effort[:harness]] [--qa <alias>] [--planner <alias>] [--yolo-dwarf] [--yolo-qa] [--decompose-level low|medium|high] [--fractal|--no-fractal|--fractal-auto-decompose] [--fractal-planner <spec>] [--jev|--no-jev] [--jev-shadow] [--no-memory] [--no-ripwire] [--ui|--no-ui] [--timeout <seconds>] [--retry-failed <n>] [--escalate-after <n>] [--qa-threshold P0|P1|P2|P3] [--file-issues ask|auto|off] [--shadow-qa <spec>[,<spec>]] [--shadow-rate <0..1>] [--explore <0..0.5>] [--fail-first]'
|
|
5
5
|
allowed-tools: [Bash, Read]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -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):
|
|
33
|
-
|
|
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.
|
|
@@ -54,10 +55,28 @@ For explanation requests, explain the workflow without spending model quota.
|
|
|
54
55
|
(`--escalate-after N`, `0` = off); an explicit `retry --dwarf` overrides it. `accept`
|
|
55
56
|
overrides a reviewer, so run it (with the user's `--reason` and
|
|
56
57
|
`--approved`) only on the user's explicit instruction; never self-accept.
|
|
58
|
+
- When you report a run, read `<plan>/control.log` and mention any human change made mid-run
|
|
59
|
+
(a threshold, a budget, a model pin; `forge control show <plan>` lists them). Never set a
|
|
60
|
+
control, pin or delete a run with `forge control` / `forge runs rm` unless the user asks.
|
|
57
61
|
- Exit `8` / status `INFRA` is a quota, auth or network stop, not a task failure and no
|
|
58
62
|
attempt was spent: report it, say what to fix, and re-run only when told. For a multi-task
|
|
59
63
|
plan, offer the opt-in whole-run review (`review`, or `integrate --final-review <qa-spec>`);
|
|
60
64
|
it spends QA quota, so never run it unprompted.
|
|
65
|
+
- **Leftover findings become issues.** A run can finish with review findings nobody will act on:
|
|
66
|
+
- CONFIRMED findings that `--qa-threshold` tolerated (`tasks/<id>/known_issues.md`);
|
|
67
|
+
- PLAUSIBLE findings in a passed task's `qa.last`;
|
|
68
|
+
- whatever a whole-run review left open.
|
|
69
|
+
|
|
70
|
+
When there are any, act on the user's `--file-issues` choice with one filer:
|
|
71
|
+
- **gh-proman**, only when it is installed and set up for the repository: `gh-proman -C <repo> config show` exits 0. It also puts the issues on the team's board with a priority. Run `gh-proman findings --from <plan or run dir> --include-plausible --json`, then follow the gh-proman skill's review-findings steps.
|
|
72
|
+
- **forge's own filer** otherwise (gh-proman missing, or not configured for this repo; never configure it yourself): `python3 <skill_dir>/scripts/forge-issues.py <plan or run dir> --include-plausible --json`, plain `gh issue create`. Pass `--lang` matching the repo's existing issues, and `--label bug` when the repo has that label. If `gh` is missing, unauthenticated or the repo has no GitHub remote, list the findings in the report and say why none were filed.
|
|
73
|
+
|
|
74
|
+
The choice:
|
|
75
|
+
- `ask` (the default): show the dry-run summary (count by severity, titles, anything already filed) and ask once: **"File these N findings as GitHub issues? [all / CONFIRMED only / none]"**. Then re-run with `--apply`, adding `--include-plausible` only for "all".
|
|
76
|
+
- `auto`: file them without asking (`--apply`, PLAUSIBLE included as "to verify" issues) and report what was created and skipped.
|
|
77
|
+
- `off`: never offer.
|
|
78
|
+
|
|
79
|
+
`--file-issues` is an instruction to you: never forward it to a runner. Skip INFRA, interrupted and still-failing runs. Both filers mark each issue with the same finding fingerprint and skip a finding either one already filed, so offering again after a retry only brings up new ones. A draft flagged as a possible duplicate is skipped on `--apply`: show it, and file it (`--confirm-new`) only if the user says it is different.
|
|
61
80
|
- Jev is optional, off unless configured and enabled, and always advisory: it never
|
|
62
81
|
changes a task's tier, never selects a model, and never substitutes for QA acceptance
|
|
63
82
|
or repository verification (`--jev-act` is still accepted and changes nothing). Read
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.10
|
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.
|
package/docs/add-ons.md
ADDED
|
@@ -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,84 @@
|
|
|
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: P0-P3, or none (exempt from the plan's)
|
|
52
|
+
tasks/<id>/escalations.tsv epoch, attempt, from-spec, to-spec, source (policy|retry|pin); older rows have 4 columns
|
|
53
|
+
tasks/<id>/escalation.pin a human's one-shot model for the next full retry: one dwarf spec on one line
|
|
54
|
+
tasks/<id>/escalation.pin.applying the pin while a retry has claimed it; removed once the retry is recorded
|
|
55
|
+
tasks/<id>/retry_budget, retries.used live per-task retry budget (a number); retries spent (kept after the run)
|
|
56
|
+
results.tsv id status branch
|
|
57
|
+
timeout, qa_threshold, verify_retries options remembered from run/retry flags (also escalate_after)
|
|
58
|
+
control.log one JSON line per human change made with forge control
|
|
59
|
+
scheduler.live, control.lock only while a scheduler runs: {"pid", "started"}; the lock serialises forge control
|
|
60
|
+
retry_budget, infra_budget only while a scheduler runs: its live budgets (a number each)
|
|
61
|
+
integration.base commit the integration branch started from
|
|
62
|
+
verification.{status,exit,log,command,fingerprint} the combined verification
|
|
63
|
+
verification.{flaky,retry.log} only when a failing command passed on rerun
|
|
64
|
+
verification.coverage.txt suites the verify command does not run (advisory)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
with worktrees and branches at:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
<repo>/../.forge-worktrees/<run-id>/<task-id> worktree
|
|
71
|
+
forge/<run-id>/<task-id> task branch
|
|
72
|
+
forge/<run-id>-integration integration branch
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`control.log` lines look like
|
|
76
|
+
`{"at": 1761200000.5, "actor": "ui", "action": "set", "task": null, "key": "qa-threshold", "value": "P2", "previous": "P1"}`
|
|
77
|
+
(`actor` is `cli` or `ui`; `action` is `set`, `pin` or `unpin`; `key` is the control's name, or `pin`; `task` is null for a plan-wide
|
|
78
|
+
control). `scheduler.live`, `retry_budget`, `infra_budget` and the per-task `retry_budget` exist
|
|
79
|
+
only while the scheduler is live: it publishes the flags it was given when it starts, re-reads them
|
|
80
|
+
at every decision and removes them when it stops, which is why `forge control` refuses a budget
|
|
81
|
+
change outside a live run. See [live controls](decomposed-runs.md#changing-a-run-while-it-works).
|
|
82
|
+
|
|
83
|
+
The worktree root is a **sibling of the repo, never `TMPDIR`**. Isolated worktrees are never
|
|
84
|
+
pushed, so a temp root that gets cleaned takes the only copy of that work with it.
|
package/docs/commands.md
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
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 control show\|set\|pin\|unpin PLAN_DIR …` | change a live plan: `set` takes `qa-threshold`, `timeout`, `escalate-after`, `verify-retries`, `retry-budget` or `infra-retries` (the last two only while a scheduler runs; `--task ID` for `qa-threshold` and `retry-budget`, value `inherit` drops the override); `pin PLAN_DIR TASK SPEC` sets the model the task's next full retry uses once, `unpin` drops it; `--json`. Every change is logged in `control.log`. See [live controls](decomposed-runs.md#changing-a-run-while-it-works) |
|
|
20
|
+
| `forge config show\|set\|unset [--repo DIR] [--json]` | one view of every config source (registry, Jev, the repo's `.forge/verify`, `setup` and `verify-subset`, dataset, `FORGE_*` variables with secrets hidden); `set KEY VALUE` / `unset KEY` edit `repo.verify`, `repo.setup`, `repo.verify-subset` (must contain `{files}`) and, for `set`, `jev.enabled true\|false`. `-` as a value reads stdin. Exit 2 on invalid input |
|
|
21
|
+
| `forge runs rm RUN_DIR [--dry-run] [--yes] [--no-archive] [--worktrees] [--branches] [--json]` | delete a run directory but keep what it taught the dataset; see [below](#forge-runs-rm) |
|
|
22
|
+
| `forge issues RUN [--apply] …` | file the review findings a run left open as GitHub issues; see [below](#forge-issues) |
|
|
23
|
+
| `forge ui open\|status\|stop` | forge-ui, the run viewer; see [the command group](forge-ui.md#forge-ui-command-group) |
|
|
24
|
+
| `forge dataset …` | every run's inputs and outcomes; see [run dataset](dataset.md) |
|
|
25
|
+
| `forge jev …` | optional Jev advice: setup, status, doctor, enable, disable, backtest; see [Jev](add-ons.md#jev) |
|
|
26
|
+
| `forge --help` | list the commands; `forge <command> --help` shows each one's options |
|
|
27
|
+
|
|
28
|
+
### `forge runs rm`
|
|
29
|
+
|
|
30
|
+
Deletes a run directory (a plan dir or a solo run dir) without losing its traces. It holds the
|
|
31
|
+
run's own lock from the first step to the last (`schedule.lock` of a plan, `pipeline.lock` of a
|
|
32
|
+
solo run), so a run started meanwhile fails to start instead of racing the delete. In order:
|
|
33
|
+
|
|
34
|
+
1. **preserve**: a strict dataset import of the run; every event must be stored, or nothing is deleted;
|
|
35
|
+
2. **archive**: a self-describing `.tar.gz` under `<data home>/archive/` (`--no-archive` skips it);
|
|
36
|
+
3. **intent**: the dataset event `run_delete_started`;
|
|
37
|
+
4. `--worktrees` removes the run's clean worktrees; `--branches` runs `git branch -D` on its
|
|
38
|
+
branches that no worktree has checked out;
|
|
39
|
+
5. the run directory is removed, `run_deleted` is recorded and the run leaves the registry.
|
|
40
|
+
|
|
41
|
+
What counts as the run's is decided from the run id, not read from the run directory: a worktree
|
|
42
|
+
under `<repo>/../.forge-worktrees/<run id>/` on `forge/<run id>/<task>` or
|
|
43
|
+
`forge/<run id>-integration`. Any other worktree there is `foreign`, one with uncommitted changes
|
|
44
|
+
is `dirty`; neither is touched, and a dirty one keeps the run directory too. Branches are reported
|
|
45
|
+
`merged` or `UNMERGED`, so you see what deleting them would lose. `--dry-run` changes nothing and
|
|
46
|
+
reports; `--yes` skips the prompt for the run id (needed without a terminal); `--json` prints one
|
|
47
|
+
object, on failure too. Exit 0 ok, 2 refused input, 3 busy or the run is active, 4 failed during
|
|
48
|
+
deletion or the run directory was kept (the same command finishes the job).
|
|
49
|
+
|
|
50
|
+
### `forge issues`
|
|
51
|
+
|
|
52
|
+
`forge issues <plan dir, task dir, review dir, known_issues.md or qa.last>` drafts one GitHub
|
|
53
|
+
issue per finding the run left open (`--group task|run` for fewer) and files them only with
|
|
54
|
+
`--apply`. The findings are the CONFIRMED ones `--qa-threshold` tolerated, PLAUSIBLE ones with
|
|
55
|
+
`--include-plausible`, and what the whole-run review left open. Each issue carries a hidden
|
|
56
|
+
fingerprint, so a finding is never filed twice, by this command or by gh-proman. Also:
|
|
57
|
+
`--min-severity`, `--repo`, `--lang`, `--label`, `--confirm-new`, `--max-issues` (default 10; pass
|
|
58
|
+
the size of a `--only` selection).
|
|
59
|
+
|
|
60
|
+
| Flag | Does |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `--json` | machine-readable output; `findings` lists each one with its fingerprint, severity, origin, task, `filed` state and `dismissed` mark |
|
|
63
|
+
| `--offline` | never run `gh`: no filed state, commit publication judged from local refs |
|
|
64
|
+
| `--only FP` | keep only these 12-hex fingerprints (repeatable or comma-separated) |
|
|
65
|
+
| `--all-runs` | read `RUN` as a repository (or a plan dir naming one) and collect every run in its registry; the newest plan wins for a finding in several |
|
|
66
|
+
| `--dismiss FP`, `--undismiss FP`, `--reason TEXT` | mark findings as needing no work (or take it back), then exit; no network. The marks live outside the repo, in `${XDG_STATE_HOME:-~/.local/state}/forge/findings/<repo key>.json` |
|
|
67
|
+
| `--include-dismissed` | draft dismissed findings too |
|
|
68
|
+
|
|
69
|
+
Two filers for one repository at once would both see a finding as unfiled, so `--apply` takes a
|
|
70
|
+
repository lock from the issue lookup to the last `gh issue create`, and each dismissal takes it
|
|
71
|
+
around its write. A busy lock is retried for 10 s, then exit 3. Exit 0 ok, 2 usage or a `gh` or
|
|
72
|
+
dismissal-store error, 3 busy.
|
|
73
|
+
|
|
74
|
+
## The `/forge` slash command
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
/forge "<goal>" --dwarf <alias>[:<effort>[:<harness>]]
|
|
78
|
+
[--qa <alias>[:<effort>[:<harness>]]]
|
|
79
|
+
[--planner <alias>[:<effort>[:<harness>]]]
|
|
80
|
+
[--yolo-dwarf] [--yolo-qa] [--repo <dir>] [--native-review]
|
|
81
|
+
[--no-memory] [--timeout <seconds>] [--ui | --no-ui] [--fractal | --no-fractal]
|
|
82
|
+
[--fractal-auto-decompose] [--fractal-planner <spec>]
|
|
83
|
+
[--fractal-depth <n>] [--fractal-children <n>] [--fractal-nodes <n>]
|
|
84
|
+
[--fractal-iterations <n>] [--fractal-concurrency <n>] [--fractal-deadline <s>]
|
|
85
|
+
[--decompose-level low|medium|high] [--max-parallel <n>]
|
|
86
|
+
[--dwarf-high <spec>] [--dwarf-medium <spec>] [--dwarf-low <spec>]
|
|
87
|
+
[--qa-high <spec>] [--qa-medium <spec>] [--qa-low <spec>]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Flag | Default | Meaning |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `--dwarf <spec>` | *asks* | the model that implements the change |
|
|
93
|
+
| `--qa <spec>` | `opus` at `xhigh` | the model that reviews the dwarf's diff |
|
|
94
|
+
| `--planner <spec>` | orchestrator plans | dispatch planning to a model; one dispatch per run, effort defaults to `xhigh` |
|
|
95
|
+
| `--no-memory` | memory on | write and inject nothing in `.forge/` |
|
|
96
|
+
| `--timeout <s>` | `2700` (45m) | kill any single dispatch that runs longer. `0` disables |
|
|
97
|
+
| `--yolo-dwarf` | off | drop the dwarf's sandbox and approval gates |
|
|
98
|
+
| `--yolo-qa` | off | drop the reviewer's sandbox |
|
|
99
|
+
| `--repo <dir>` | cwd | repository to work in |
|
|
100
|
+
| `--native-review` | off | use native Codex review against the recorded baseline instead of an inlined diff |
|
|
101
|
+
| `--decompose-level <l>` | off | split the goal into parallel tasks |
|
|
102
|
+
| `--max-parallel <n>` | `3` | concurrent task pipelines |
|
|
103
|
+
| `--dwarf-high/-medium/-low` | — | per-difficulty routing; comma-list pools models |
|
|
104
|
+
| `--qa-high/-medium/-low` | — | same, for reviewers |
|
|
105
|
+
| `--fractal` / `--no-fractal` | ask interactively; off unattended | mutually exclusive, per-run backend choice |
|
|
106
|
+
| `--fractal-auto-decompose` | off | enables Fractal with automatic recursive split-or-atomic decisions |
|
|
107
|
+
| `--fractal-planner <spec>` | top-level planner, then task root spec | frozen decision model; requires automatic mode |
|
|
108
|
+
| `--fractal-depth <n>` | `2` | nested levels below each Forge implementation node |
|
|
109
|
+
| `--fractal-children <n>` | `3` | unsettled direct children per node |
|
|
110
|
+
| `--fractal-nodes <n>` | `12` | lifetime nodes per Forge task, including implementation |
|
|
111
|
+
| `--fractal-iterations <n>` | `6` | per node per execution attempt |
|
|
112
|
+
| `--fractal-concurrency <n>` | `3` | shared model slots across nested trees and QA |
|
|
113
|
+
| `--fractal-deadline <s>` | `2700` | task attempt deadline, excluding explicit pauses |
|
|
114
|
+
| `--fractal-max-cost <amount>` | unsupported | returns an error; the bridge cannot enforce dollar caps |
|
|
115
|
+
|
|
116
|
+
Fractal's task deadline still applies when `--timeout 0` disables the ordinary
|
|
117
|
+
per-dispatch timeout. Child routing uses the dwarf tier flags; QA stays at the Forge
|
|
118
|
+
task boundary. Pools and Fractal limits are frozen for an existing run.
|
|
119
|
+
|
|
120
|
+
Before an interactive run, forge asks **“Use Fractal for this run? [y/N]”** once.
|
|
121
|
+
Pass `--fractal` or `--no-fractal` to answer explicitly; unattended runs default off.
|
|
122
|
+
It also asks **“Open forge-ui to watch this run? [y/N]”** (`--ui` / `--no-ui`); on a yes,
|
|
123
|
+
the [forge-ui](forge-ui.md) page opens as soon as the run exists. Resume and retry never ask.
|
|
124
|
+
|
|
125
|
+
For what `--native-review` trades away, see [native review](reviews.md#native-review).
|
|
126
|
+
|
|
127
|
+
### Examples
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# minimum
|
|
131
|
+
/forge "make the cache key include the tenant id" --dwarf sol:high
|
|
132
|
+
|
|
133
|
+
# both roles named, reviewer thinking harder than the implementer
|
|
134
|
+
/forge "rewrite the rate limiter as a token bucket" --dwarf luna:max --qa sol:ultra
|
|
135
|
+
|
|
136
|
+
# same model, different CLI
|
|
137
|
+
/forge "extract the retry helper into its own module" --dwarf sol:high:openclaude
|
|
138
|
+
|
|
139
|
+
# Gemini as the dwarf, unsandboxed so it can actually run the tests it writes
|
|
140
|
+
/forge "add table-driven tests for the parser" --dwarf gemini:high:antigravity --yolo-dwarf
|
|
141
|
+
|
|
142
|
+
# a cheap dwarf with an expensive reviewer
|
|
143
|
+
/forge "update all the docstrings to match the new signatures" --dwarf haiku --qa opus:max
|
|
144
|
+
|
|
145
|
+
# work in another repo
|
|
146
|
+
/forge "bump the pinned deps and fix the fallout" --dwarf sol:xhigh --repo ~/dev/other-project
|
|
147
|
+
|
|
148
|
+
# large refactor, reviewed by codex's native reviewer
|
|
149
|
+
/forge "split the god object into three services" --dwarf sol:ultra --qa sol:ultra --native-review
|
|
150
|
+
|
|
151
|
+
# parallel, one dwarf for every task
|
|
152
|
+
/forge "add CRUD endpoints for projects, users and teams" \
|
|
153
|
+
--decompose-level medium --dwarf sol:high
|
|
154
|
+
|
|
155
|
+
# parallel, routed by difficulty, wider fan-out
|
|
156
|
+
/forge "migrate the whole API layer from REST to gRPC" \
|
|
157
|
+
--decompose-level high --max-parallel 5 \
|
|
158
|
+
--dwarf-high sol:ultra --dwarf-medium luna:high --dwarf-low haiku:medium \
|
|
159
|
+
--qa-high opus:max --qa sonnet:high
|
|
160
|
+
|
|
161
|
+
# pool two providers on the hard tier so neither quota carries it alone
|
|
162
|
+
/forge "implement the new billing rules across the codebase" \
|
|
163
|
+
--decompose-level medium \
|
|
164
|
+
--dwarf-high sol:xhigh,terra:xhigh --dwarf luna:high
|
|
165
|
+
|
|
166
|
+
# a model that thinks for a long time; raise the per-dispatch backstop
|
|
167
|
+
/forge "prove the scheduler cannot deadlock, and fix it if it can" \
|
|
168
|
+
--dwarf sol:ultra --timeout 7200
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
After a decomposed run, a task that failed review can be re-run on its own — with the
|
|
172
|
+
findings that failed it, on a stronger model:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bash scripts/forge-parallel.sh retry /tmp/forge-billing pricing --dwarf sol:ultra
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## `scripts/forge-dispatch.sh`
|
|
179
|
+
|
|
180
|
+
Resolves a spec into a real CLI invocation and runs it. Needs only bash and coreutils, which
|
|
181
|
+
is the point: it behaves identically no matter which harness is orchestrating.
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
forge-dispatch.sh doctor
|
|
185
|
+
forge-dispatch.sh dwarf <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--yolo] [--dry-run]
|
|
186
|
+
forge-dispatch.sh qa <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--yolo] [--dry-run]
|
|
187
|
+
[--native-review [--review-base <ref>]]
|
|
188
|
+
forge-dispatch.sh planner <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--dry-run]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Option | Meaning |
|
|
192
|
+
|---|---|
|
|
193
|
+
| `--prompt-file <f>` | file holding the prompt (required for `dwarf`/`qa`) |
|
|
194
|
+
| `--repo <dir>` | repository the role operates in |
|
|
195
|
+
| `--run-dir <d>` | where prompts, logs and results are written |
|
|
196
|
+
| `--yolo` | bypass sandbox and approvals for this role |
|
|
197
|
+
| `--dry-run` | resolve and print the command; run nothing |
|
|
198
|
+
| `--native-review` | qa only; use codex's built-in reviewer |
|
|
199
|
+
| `--review-base <ref>` | qa only; base ref for the native review |
|
|
200
|
+
| `--agy-timeout <s>` | antigravity `--print-timeout` (long runs need this raised) |
|
|
201
|
+
| `--timeout <s>` | kill this dispatch after `<s>` seconds; `0` disables. See the precedence below |
|
|
202
|
+
|
|
203
|
+
**Exit codes:** `0` ok · `2` spec or usage error · `3` harness missing or unusable ·
|
|
204
|
+
`4` the backend ran and failed · `7` the backend hit its timeout and was killed ·
|
|
205
|
+
`8` an **infrastructure failure** (quota or usage limit, auth, rate limit, network, or an
|
|
206
|
+
empty answer) — nothing about the work was judged, so callers pause instead of counting a
|
|
207
|
+
failure. On `8`, `<run-dir>/<role>.infra` holds `class=`, `retry_after=`, `detail=`, `rc=`,
|
|
208
|
+
`role=`.
|
|
209
|
+
|
|
210
|
+
**Timeout precedence.** An explicit `--timeout`, then `FORGE_TIMEOUT` (an explicit `0` wins
|
|
211
|
+
and disables the watchdog), then the optional fifth `timeout` column of the model's
|
|
212
|
+
[registry](models.md#model-registry) row, then the built-in `2700` (45 min). A value that was *not*
|
|
213
|
+
explicit is scaled by the resolved (post-clamp) effort: up to `high` ×1, `xhigh` ×4/3,
|
|
214
|
+
`max`/`ultra`/`ultracode` ×2. QA and planner default to `xhigh`, so their built-in limit is
|
|
215
|
+
3600 s; dwarves default to `medium` and keep 2700 s. `<role>.resolved` records `timeout=` and
|
|
216
|
+
`timeout_source=` (`explicit`, `env`, `registry` or `default`, plus `+effort-scaled`).
|
|
217
|
+
`forge-parallel.sh run`/`retry --timeout S` sets it for a decomposed run (kept in the plan).
|
|
218
|
+
`FORGE_REGISTRY` points the dispatcher at an alternative registry file.
|
|
219
|
+
|
|
220
|
+
Only antigravity bounds its own runtime, and stock macOS has no `timeout` binary to wrap the
|
|
221
|
+
others in — so a hung backend used to block forever, and under a decomposed run one hung task
|
|
222
|
+
silently stalled the others. The default is deliberately generous: this is a backstop against
|
|
223
|
+
a wedged process, not a budget. A role killed by it has usually left a partial edit behind, so
|
|
224
|
+
`7` is worth reporting as such rather than as a clean failure.
|
|
225
|
+
|
|
226
|
+
On `3` or `4`, forge shows you the actual error rather than substituting a different model —
|
|
227
|
+
quietly swapping backends hides the fact that the one you picked is broken.
|
|
228
|
+
|
|
229
|
+
**Process hygiene.** Unless `FORGE_ORPHAN_GUARD=off` (or the run is a Fractal one), the harness
|
|
230
|
+
is started in its own session, and after it exits any process still alive in that session is
|
|
231
|
+
listed in `<role>.orphans` and stopped, so a backgrounded measurement cannot outlive the
|
|
232
|
+
dispatch. The timeout watchdog and the exit trap signal the whole session too.
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# what would this actually run?
|
|
236
|
+
bash scripts/forge-dispatch.sh dwarf sol:ultra --prompt-file /tmp/p --dry-run
|
|
237
|
+
|
|
238
|
+
# check a clamp before committing to a long run
|
|
239
|
+
bash scripts/forge-dispatch.sh qa gemini-pro:medium --prompt-file /tmp/p --dry-run
|
|
240
|
+
# effort=low
|
|
241
|
+
# clamped=medium -> low (gemini-pro offers low and high, but no medium)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## `scripts/forge-solo.sh`
|
|
245
|
+
|
|
246
|
+
The whole single-task run: memory injection, prompt assembly, the dwarf dispatch, the diff
|
|
247
|
+
capture, the QA dispatch, and the ledger writes.
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
forge-solo.sh <run-dir> --repo <dir> --dwarf <spec> [--qa <spec>]
|
|
251
|
+
[--approach <file>] [--yolo-dwarf] [--yolo-qa]
|
|
252
|
+
[--native-review] [--no-memory] [--timeout <s>] [--dry-run] [--ui | --no-ui]
|
|
253
|
+
[--fail-first]
|
|
254
|
+
[--fractal | --no-fractal] [--fractal-<limit> <n>]
|
|
255
|
+
[--dwarf-low <pool>] [--dwarf-medium <pool>] [--dwarf-high <pool>] [--retry]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
You write two files into the run directory; forge does the rest:
|
|
259
|
+
|
|
260
|
+
| You write | Is |
|
|
261
|
+
|---|---|
|
|
262
|
+
| `prompt.md` | the implementation instruction (required) |
|
|
263
|
+
| `goal.txt` | one line, what was asked — given to the reviewer as intent (optional) |
|
|
264
|
+
|
|
265
|
+
| It writes | Is |
|
|
266
|
+
|---|---|
|
|
267
|
+
| `dwarf.last` / `qa.last` | each role's final message |
|
|
268
|
+
| `changes.diff` | exactly what the reviewer read |
|
|
269
|
+
| `verdict` | `PASS`, `FAIL`, `UNKNOWN` or `NOCHANGES` |
|
|
270
|
+
| `<role>.{input,log,resolved,cmd}` | the prompt, the transcript, the resolution, the command |
|
|
271
|
+
| `fractal-selection.json` | persisted backend choice; enabled runs include their managed run ID |
|
|
272
|
+
|
|
273
|
+
With Fractal, per-step dispatch artifacts live in the managed run while the solo directory
|
|
274
|
+
retains the aggregate diff and Forge QA result. `--retry` starts a new Fractal attempt;
|
|
275
|
+
`forge fractal resume RUN_ID` continues preserved execution and pipeline checkpoints.
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
RUN="$(mktemp -d /tmp/forge-XXXXXX)"
|
|
279
|
+
echo "add retry with backoff to the HTTP client" > "$RUN/goal.txt"
|
|
280
|
+
echo "Add exponential backoff to src/http.py, capped at 5 attempts." > "$RUN/prompt.md"
|
|
281
|
+
|
|
282
|
+
bash scripts/forge-solo.sh "$RUN" --repo ~/dev/api --dwarf sol:high --qa opus
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Exit codes:** `0` reviewed · `2` usage · `3` not a git repository · `4` a dispatch failed ·
|
|
286
|
+
`5` **no changes or review invalidated** · `7` a dispatch timed out · `8` a dispatch hit an
|
|
287
|
+
**infrastructure failure** (quota, auth, rate limit, network, empty output): nothing was
|
|
288
|
+
judged, fix the cause and run again. A dwarf that exits 0 with an empty answer *and* changes
|
|
289
|
+
nothing is reported as `8`, not `5` — it never really ran.
|
|
290
|
+
|
|
291
|
+
The dwarf is given the same implementer rules as in a decomposed run (no commits, no
|
|
292
|
+
background processes, finish measurements before the last message). If it commits anyway, the
|
|
293
|
+
run still reviews its changes, says so, and prints the `git reset --soft <old HEAD>` that would
|
|
294
|
+
turn them back into uncommitted changes; forge never resets anything itself. Orphan processes
|
|
295
|
+
and promised-later-work notes appear under "implementer guard notes".
|
|
296
|
+
|
|
297
|
+
`5` is the one worth recognising on sight. Headless dwarves genuinely stop to ask a
|
|
298
|
+
clarifying question that nothing can answer; the run ends having spent the quota and changed
|
|
299
|
+
nothing, with the question sitting in `dwarf.last`.
|
|
300
|
+
|
|
301
|
+
Two things it gets right that are easy to get wrong by hand, and that fail *silently* rather
|
|
302
|
+
than loudly:
|
|
303
|
+
|
|
304
|
+
- **`.forge/` is excluded from the capture.** Forge rewrites its own memory in the working
|
|
305
|
+
tree at the end of every run, so left in, it reaches the reviewer as a file the dwarf
|
|
306
|
+
appears to have touched — which a good reviewer correctly flags as scope creep.
|
|
307
|
+
- **New files are diffed against `/dev/null`.** A `git status` line says only `?? calc.py`.
|
|
308
|
+
A dwarf whose entire task was to add a file would have had its actual code reviewed by
|
|
309
|
+
nobody, while the run still reported a clean QA pass.
|
|
310
|
+
|
|
311
|
+
The run directory must live outside the repository — anything forge writes inside the working
|
|
312
|
+
tree shows up in the dwarf's own diff. `forge-solo.sh` refuses rather than letting that happen
|
|
313
|
+
quietly.
|
|
314
|
+
|
|
315
|
+
## `scripts/forge-parallel.sh`
|
|
316
|
+
|
|
317
|
+
Decomposed runs: many dwarves in isolated worktrees, per-task QA, only passing work merged.
|
|
318
|
+
Bash 3.2 entrypoints use a Python standard-library coordinator to schedule eligible tasks.
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
forge-parallel.sh plan <plan-dir> --repo <dir> [routing flags] [--planner <spec>] [--no-memory]
|
|
322
|
+
[--decompose-level L] [--shadow-qa <spec>[,..]|none] [--shadow-rate R]
|
|
323
|
+
[--explore E] [--ui | --no-ui] [--fail-first | --no-fail-first]
|
|
324
|
+
forge-parallel.sh run <plan-dir> [--max-parallel N] [--yolo-dwarf] [--yolo-qa] [--dry-run]
|
|
325
|
+
[--verify <cmd>] [--setup <cmd>] [--timeout S]
|
|
326
|
+
[--retry-failed N] [--infra-retries M]
|
|
327
|
+
[--qa-threshold P0|P1|P2|P3|none] [--verify-retries N]
|
|
328
|
+
[--fractal | --no-fractal] [--fractal-<limit> <n>]
|
|
329
|
+
forge-parallel.sh retry <plan-dir> <task-id> [--dwarf <spec>] [--timeout S]
|
|
330
|
+
[--qa-threshold Pn|none] [--verify-retries N]
|
|
331
|
+
forge-parallel.sh accept <plan-dir> <task-id> --reason "<why>" --approved
|
|
332
|
+
forge-parallel.sh review <plan-dir> [--qa <spec>] [--yolo-qa] [--qa-threshold Pn]
|
|
333
|
+
forge-parallel.sh integrate <plan-dir> --approved [--final-review <qa-spec>] [--verify-retries N]
|
|
334
|
+
forge-parallel.sh split <plan-dir> <new-plan-dir> --tasks <id,id> [--dry-run]
|
|
335
|
+
forge-parallel.sh combine <new-plan-dir> <plan-dir> <plan-dir>... [--verify <cmd>] [--dry-run]
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
| Subcommand | Does |
|
|
339
|
+
|---|---|
|
|
340
|
+
| `plan` | validate `tasks.tsv`, resolve difficulty → concrete dwarf/qa specs, compute waves, render the approval table |
|
|
341
|
+
| `run` | schedule ready tasks; per task: worktree → dwarf → diff → QA → status; merge passing tasks onto the integration branch |
|
|
342
|
+
| `retry` | re-run **one** failed task in the worktree it already has, with its reviewer's findings in the prompt |
|
|
343
|
+
| `integrate` | **never automatic** — merge the integration branch into your branch |
|
|
344
|
+
| `accept` | **only on your explicit instruction** — merge a `FAIL`/`UNKNOWN` task's reviewed work anyway, recording why |
|
|
345
|
+
| `review` | **opt-in, spends QA quota** — one reviewer reads the whole combined result; read-only |
|
|
346
|
+
| `split` / `combine` | move tasks into a plan of their own / join fully merged plans into one |
|
|
347
|
+
|
|
348
|
+
| Flag | Subcommands | Remembered in the plan | Means |
|
|
349
|
+
|---|---|---|---|
|
|
350
|
+
| `--timeout S` | run, retry | `timeout` | per-dispatch timeout in seconds (`0` disables); wins over `FORGE_TIMEOUT` |
|
|
351
|
+
| `--retry-failed N` | run | no — this run only | re-queue a task the reviewer rejected up to `N` more times inside the run |
|
|
352
|
+
| `--infra-retries M` | run | no — this run only | wait out up to `M` infrastructure stops instead of pausing |
|
|
353
|
+
| `--qa-threshold Pn` | run, retry | `qa_threshold` | least severe finding that still blocks; milder ones become known issues; `none` clears |
|
|
354
|
+
| `--verify-retries N` | run, retry, integrate | `verify_retries` | reruns of a failed verify command (default `1`, `0` = strict single run) |
|
|
355
|
+
|
|
356
|
+
**Exit codes:** `0` ok · `2` usage or validation · `3` precondition (not a git repo, …) ·
|
|
357
|
+
`5` some task failed QA, or the combined verification failed · `6` integration conflict ·
|
|
358
|
+
`8` **paused on an infrastructure failure** (quota, auth, rate limit, network): no attempt was
|
|
359
|
+
spent and nothing was judged — fix the cause and run the same command again.
|
|
360
|
+
|
|
361
|
+
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).
|
|
362
|
+
|
|
363
|
+
## `scripts/forge-memory.sh` and `scripts/forge-install.sh`
|
|
364
|
+
|
|
365
|
+
See [project memory](memory.md#scriptsforge-memorysh) and [install](install.md#scriptsforge-installsh).
|
package/docs/dataset.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
Deleting a run keeps what it taught the dataset. `forge runs rm <run-dir>` first imports the run
|
|
20
|
+
**strictly** (every event must be stored, or nothing is deleted), then writes a self-describing
|
|
21
|
+
archive under `<data home>/archive/`: a `.tar.gz` whose `FORGE_ARCHIVE.json` records the run
|
|
22
|
+
dir's original path, run id and dataset uid, so `forge dataset import` maps it back to the same
|
|
23
|
+
run later. It records `run_delete_started` and `run_deleted` events around the removal. The same
|
|
24
|
+
import also reads a plan's `escalations.tsv` (with who decided: `policy`, `retry` or `pin`) and
|
|
25
|
+
`control.log`, so human interventions made with `forge control` are in the dataset as
|
|
26
|
+
`control` events. See [forge runs rm](commands.md#forge-runs-rm).
|
|
27
|
+
|
|
28
|
+
Capture is fail-open and never read by anything that builds a prompt. See
|
|
29
|
+
[references/dataset.md](../references/dataset.md) for the event schema and its invariants.
|