@giamme/forge 0.11.0 → 0.12.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 +47 -0
- package/SKILL.md +4 -2
- package/VERSION +1 -1
- package/docs/artifacts.md +46 -12
- package/docs/commands.md +48 -9
- package/docs/decomposed-runs.md +43 -2
- package/docs/forge-ui.md +27 -6
- package/docs/reviews.md +31 -6
- package/package.json +1 -1
- package/references/dataset.md +3 -1
- package/references/decompose.md +159 -17
- package/references/harnesses.md +13 -1
- package/references/ui.md +14 -4
- package/scripts/forge-control.py +268 -25
- package/scripts/forge-dispatch.sh +80 -3
- package/scripts/forge-guard.py +156 -15
- package/scripts/forge-issues.py +1 -1
- package/scripts/forge-lib-plans.sh +9 -3
- package/scripts/forge-lib-review.sh +22 -3
- package/scripts/forge-lib-task.sh +51 -4
- package/scripts/forge-lib-verify.sh +137 -6
- package/scripts/forge-parallel-options.sh +59 -0
- package/scripts/forge-parallel.sh +212 -28
- package/scripts/forge-ripwire.py +1 -1
- package/scripts/forge-route.py +157 -5
- package/scripts/forge-schedule.py +687 -50
- package/scripts/forge-ui.py +8 -4
- package/scripts/forge-verify.py +878 -0
- package/scripts/forge_dataset/forecast.py +29 -4
- package/scripts/forge_dataset/harvest.py +10 -4
- package/scripts/forge_verify_reports.py +225 -0
- package/ui/README.md +19 -4
- package/ui/docs/api.md +139 -25
- package/ui/forge_ui/control.py +26 -7
- package/ui/forge_ui/export.py +20 -7
- package/ui/forge_ui/reader.py +307 -11
- package/ui/forge_ui/server.py +16 -0
- package/ui/forge_ui/static/app.js +2 -1
- package/ui/forge_ui/static/controls.js +217 -33
- package/ui/forge_ui/static/findingsview.js +37 -12
- package/ui/forge_ui/static/gantt.js +14 -9
- package/ui/forge_ui/static/index.html +1 -0
- package/ui/forge_ui/static/panel.js +2 -1
- package/ui/forge_ui/static/runmodel.js +92 -11
- package/ui/forge_ui/static/scene3d.js +9 -5
- package/ui/forge_ui/static/settings.js +48 -12
- package/ui/forge_ui/static/style.css +60 -0
- package/ui/forge_ui/static/verifyview.js +324 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,53 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and versions follow the format `{major}.{minor}[.{patch}]` ([...] parts appear only when non-zero).
|
|
7
7
|
|
|
8
|
+
## [0.12] - 2026-10-27
|
|
9
|
+
|
|
10
|
+
Decomposed runs can now be steered while they run and stop cleanly when interrupted: drain, stop, retry or resize a live run from forge control or forge-ui, an infrastructure stop pauses only the model or CLI it hit, and verification can run as parallel lanes that rerun only what failed and name the failing tests.
|
|
11
|
+
|
|
12
|
+
### Highlights
|
|
13
|
+
|
|
14
|
+
- A running decomposed plan can be steered: `forge control drain` lets running tasks finish and starts nothing new until `forge control resume`; `forge control stop` ends the run once running tasks are done (exit 130 without verifying, unless every task merged; not-started tasks stay pending for the next `run`), and `stop --now` interrupts them; `forge control set <plan> max-parallel N` changes how many tasks run at once.
|
|
15
|
+
- Verification can run as lanes: declare them in `.forge/verify.d/` (one file per lane) or with `run --verify-lane 'name[options]=command'`, and forge runs them side by side (`--verify-parallel`, 3 by default), reruns only a lane that failed, and calls a lane that passed on rerun flaky. Lanes can read JUnit or TAP reports to name the failing tests, and a baseline of known failures keeps those from failing the run. The run summary and the whole-run review name each lane and its state.
|
|
16
|
+
- An infrastructure stop no longer pauses the whole decomposed run: a rate limit pauses only that model and a quota or sign-in stop only that CLI, each with its own wait and --infra-retries budget, while tasks routed elsewhere keep running. `forge control show` lists the active pauses.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- `run --infra-backoff` sets how long forge waits between infrastructure retries: `exp:<base>[,<cap>]` (the default, `exp:60`), `linear:<start>,<step>[,<cap>]` or a list of waits such as `10,20,30`. `forge control set <plan> infra-backoff` changes it while the run goes on, and each wait message names the shape it used.
|
|
21
|
+
- A running decomposed plan can retry a stopped or failed task, optionally on another model (`forge control retry <plan> <task> [--dwarf <spec>]`), and pick up a row you added to tasks.tsv (`forge control add <plan> <task>`) without ending the run. The scheduler applies or refuses each request at its next pass and records the outcome in control.log.
|
|
22
|
+
- `run --infra-fallback`: when an implementer's model is at capacity, the task moves at once to the next model of its own tier pool instead of waiting, and the move is recorded like an escalation. The busy model is still paused and counted, so a pool that is entirely at capacity still ends the run.
|
|
23
|
+
- forge-ui now shows a verification while it runs: its current step, last output line and idle time, and, for a lanes verification, each lane's state, runs, test counts and failing tests, with known failures marked.
|
|
24
|
+
- forge-ui serves every verification log, each lane's and each rerun's, as a numbered tail or in 400-line pages, so the cause of a failed verification can be read without opening the run dir.
|
|
25
|
+
- The verification panel in forge-ui now follows a running verification live (current step, last line, elapsed time, a warning after five silent minutes, the log's tail) and, when it fails, opens on the failing tests, marked new or known, each linking to its line in the log.
|
|
26
|
+
- forge-ui's Execution view shows verification lanes as their own rows, with every run and rerun at its real time, and the 3D finish node shows one light per lane; a verification that is still running reads RUNNING instead of its previous result.
|
|
27
|
+
- `--escalate-effort` (on `run` and `retry`, or `forge control set <plan> escalate-effort on`): when a task has failed its escalation limit on the top tier's model, forge retries it once more at the next effort that model accepts before stopping it with a split suggestion. Turning it on also releases tasks the policy already stopped.
|
|
28
|
+
- forge-ui's Controls panel can now drain, resume and stop a live run (gracefully or at once), change max parallel, the infrastructure backoff and the effort step, and retry a stopped task now with a chosen model. It also shows each infrastructure pause with a countdown, and whether a queued retry was applied or refused.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- The forecast `run` prints before dispatching lists the tasks that don't have enough history yet on one line instead of a row each, and is a single line when no task has enough history, so a new setup no longer opens every run with a table of "not enough history" rows. `forge dataset forecast <plan>` still shows every task.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- When the plan forecast that `run` prints runs out of its time budget while saving, it no longer leaves a stray `.forecast.json.<pid>` file in the plan.
|
|
37
|
+
- Interrupting a decomposed run no longer leaves an implementer or reviewer CLI running: forge waits up to 10 s (FORGE_INTERRUPT_GRACE) for each task to stop its harness, and a harness left behind by a killed run is stopped when the next run starts.
|
|
38
|
+
- Interrupting `forge-parallel.sh run` (Ctrl-C or SIGTERM) no longer goes on to verify a half-merged integration branch: the run stops, frees the plan lock within seconds, exits 130 and prints the command that continues each interrupted task. A signal during verification stops the whole verify command and skips its rerun.
|
|
39
|
+
- A task that finished just as a decomposed run was interrupted is now reaped first: its passing work still merges and its result is kept, and only the tasks still running are marked INTERRUPTED.
|
|
40
|
+
- On macOS, a Ripwire context call whose output was too long or that ran too long no longer fails with a PermissionError; it is skipped with its reason, as intended.
|
|
41
|
+
|
|
42
|
+
## [0.11.1] - 2026-10-26
|
|
43
|
+
|
|
44
|
+
A bug-fix release for forge-ui and forge issues: the Settings and Open findings views keep your edits and selections honest, forge ui open handles a read-only server with another configuration, and refused labels and warnings say what's wrong.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- forge-ui's Open findings view files exactly what its preview showed, even if you change the scope or the plausible toggle while the drafts load, and shows forge's notes when nothing was filed. Findings hidden by a filter are no longer counted or acted on, and "Select shown open" counts only shown findings toward its limit of 25.
|
|
49
|
+
- forge-ui's Settings page no longer drops a repository-switch confirm when the run list changes. It warns before saving over a file that changed on disk while a confirm was open, and a failed read keeps your unsaved edits on screen with a note instead of replacing the page with an error.
|
|
50
|
+
- `forge ui open` resolves a `FORGE_REGISTRY` that starts with `~` the same way forge's commands do, and replaces a read-only forge-ui running with another configuration instead of refusing to open.
|
|
51
|
+
- The docs now match the code on who creates `control.lock`, `forge config set` and `unset` needing `--repo`, when `forge runs rm` keeps a run directory, and a Fractal plan's hidden pin control.
|
|
52
|
+
- `forge issues` prints its warnings as `warning: …` in the listing too, as it already did for dismissals.
|
|
53
|
+
- When forge-ui refuses an issue label, its message now names the rule the label broke (blank, over 50 characters, starting with `-`, or holding control characters).
|
|
54
|
+
|
|
8
55
|
## [0.11] - 2026-10-26
|
|
9
56
|
|
|
10
57
|
Reviews now remember the last round: a retry's review starts from the previous findings, and a repeated whole-run review from the last report. forge dataset can forecast a plan before it runs and grade how often each reviewer's PASS held, and forge-ui shows a superseded final review as OUTDATED instead of FAIL.
|
package/SKILL.md
CHANGED
|
@@ -57,8 +57,10 @@ For explanation requests, explain the workflow without spending model quota.
|
|
|
57
57
|
overrides a reviewer, so run it (with the user's `--reason` and
|
|
58
58
|
`--approved`) only on the user's explicit instruction; never self-accept.
|
|
59
59
|
- When you report a run, read `<plan>/control.log` and mention any human change made mid-run
|
|
60
|
-
(a threshold, a budget, a model pin; `forge control show <plan>`
|
|
61
|
-
control, pin or delete a run with `forge control` /
|
|
60
|
+
(a threshold, a budget, a model pin, a drain, stop or queued retry; `forge control show <plan>`
|
|
61
|
+
lists them). Never set a control, pin, `drain|stop|retry` or delete a run with `forge control` /
|
|
62
|
+
`forge runs rm` unless the user asks. Exit `130` / `INTERRUPTED`: the run was signalled or
|
|
63
|
+
stopped; relay the `retry` lines it printed.
|
|
62
64
|
- Exit `8` / status `INFRA` is a quota, auth or network stop, not a task failure and no
|
|
63
65
|
attempt was spent: report it, say what to fix, and re-run only when told. For a multi-task
|
|
64
66
|
plan, offer the opt-in whole-run review (`review`, or `integrate --final-review <qa-spec>`);
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.12
|
package/docs/artifacts.md
CHANGED
|
@@ -15,7 +15,7 @@ as if the dwarf had written it.
|
|
|
15
15
|
<role>.cmd the exact command line executed
|
|
16
16
|
<role>.log full transcript
|
|
17
17
|
<role>.last the final message — read this first
|
|
18
|
-
<role>.infra only after an infrastructure failure: class, retry_after, detail
|
|
18
|
+
<role>.infra only after an infrastructure failure: class, retry_after, detail, harness, model
|
|
19
19
|
<role>.orphans only when processes were left running after the harness exited
|
|
20
20
|
<role>.session session id reported by claude, openclaude or codex; absent when the dispatch published none
|
|
21
21
|
<role>.continue only when the dispatch was asked to continue a reviewer session: requested=, mode=continued|failed, reason=
|
|
@@ -49,9 +49,10 @@ A decomposed run adds:
|
|
|
49
49
|
tasks/<id>/attempt, attempts.tsv attempts spent; one audit row per entry (incl. refunded stops)
|
|
50
50
|
tasks/<id>/known_issues.md, qa.gate findings tolerated by --qa-threshold, and the gate's decision
|
|
51
51
|
tasks/<id>/guard.txt what forge observed about the implementer (self-commit, orphans, promises)
|
|
52
|
-
tasks/<id>/infra.txt, resume, noretry infrastructure stop record; QA-only resume marker; no-progress marker
|
|
52
|
+
tasks/<id>/infra.txt, resume, noretry infrastructure stop record (<role>.infra plus stage=); QA-only resume marker; no-progress marker
|
|
53
|
+
tasks/<id>/<role>.harness only while a guarded dispatch runs: its harness's pid and start time, for forge-guard.py stop
|
|
53
54
|
tasks/<id>/qa_threshold optional per-task blocking threshold: P0-P3, or none (exempt from the plan's)
|
|
54
|
-
tasks/<id>/escalations.tsv epoch, attempt, from-spec, to-spec, source (policy|retry|pin); older rows have 4 columns
|
|
55
|
+
tasks/<id>/escalations.tsv epoch, attempt, from-spec, to-spec, source (policy|retry|pin|fallback); older rows have 4 columns
|
|
55
56
|
tasks/<id>/escalation.pin a human's one-shot model for the next full retry: one dwarf spec on one line
|
|
56
57
|
tasks/<id>/escalation.pin.applying the pin while a retry has claimed it; removed once the retry is recorded
|
|
57
58
|
tasks/<id>/retry_findings.commit commit the carried review judged
|
|
@@ -64,17 +65,40 @@ A decomposed run adds:
|
|
|
64
65
|
tasks/<id>/retry_budget, retries.used live per-task retry budget (a number); retries spent (kept after the run)
|
|
65
66
|
results.tsv id status branch
|
|
66
67
|
timeout, qa_threshold, verify_retries options remembered from run/retry flags (also escalate_after)
|
|
68
|
+
escalate_effort on: the retry policy's effort step (--escalate-effort; absent = off)
|
|
69
|
+
infra_backoff, infra_fallback --infra-backoff's shape; on while --infra-fallback is set
|
|
70
|
+
max_parallel the concurrency limit: written by each run from --max-parallel, changed live by forge control
|
|
67
71
|
reviewer_session holds on; present while plan --reviewer-session is on
|
|
68
72
|
<final-review-dir>/review.meta final-review-<epoch>-<pid>/ or integrate-*/final-review/; base=, tip=, source=, spec=, threshold=, integration=, previous=, since=; session= and session_reason= while reviewer_session is set
|
|
69
|
-
control.log one JSON line per human change made with forge control
|
|
70
|
-
|
|
73
|
+
control.log one JSON line per human change made with forge control, and per request outcome
|
|
74
|
+
control.requests/ retry and add requests queued by forge control: one JSON file each, removed once settled
|
|
75
|
+
scheduler.live only while a scheduler runs: {"pid", "started"}
|
|
76
|
+
drain, stop only while a scheduler runs: forge control drain (empty) and stop (graceful|now)
|
|
77
|
+
infra.paused only while something is paused on infrastructure: {"scopes": [...]}
|
|
78
|
+
control.lock the lock that serialises changes to the plan's control files, created by whichever takes it first (forge control, the scheduler or an escalation record) and left in place
|
|
71
79
|
retry_budget, infra_budget only while a scheduler runs: its live budgets (a number each)
|
|
72
80
|
integration.base commit the integration branch started from
|
|
73
|
-
verification.{status,exit,log,command,fingerprint} the combined verification
|
|
74
|
-
verification.{flaky,retry.log} only when a failing command passed on rerun
|
|
81
|
+
verification.{status,exit,log,command,fingerprint} the combined verification; status PASS, FAIL or INTERRUPTED (a signal stopped it)
|
|
82
|
+
verification.{flaky,retry.log} only when a failing command passed on rerun (lanes: flaky alone, per lane)
|
|
83
|
+
verification.commit the integration commit that was verified
|
|
84
|
+
verification.runs.tsv one row per run of the verify command or of a lane (below)
|
|
85
|
+
verification.run-<n>.log single command: each run's own copy of its log
|
|
86
|
+
verification.lanes.json lanes only: every lane's state, runs, step and tests, rewritten as they change
|
|
87
|
+
verification.lane.<name>.log lanes only: the lane's run in progress
|
|
88
|
+
verification.lane.<name>.run-<k>.log lanes only: each finished run of the lane
|
|
75
89
|
verification.coverage.txt suites the verify command does not run (advisory)
|
|
90
|
+
verify_cmd, verify.d/ the plan's --verify command, or its --verify-lane lanes (one file per lane)
|
|
91
|
+
verify_parallel lanes run at once (--verify-parallel; default 3)
|
|
76
92
|
```
|
|
77
93
|
|
|
94
|
+
`verification.runs.tsv` is tab-separated, one row per run: `n`, `kind` (`initial`, `rerun`, or
|
|
95
|
+
`jev_retry` for a single command), `exit`, `tree_changed` (`0`/`1`), `duration_s` and `log`. With
|
|
96
|
+
lanes each row has two more columns, `lane` and `started` (epoch seconds); lanes run side by
|
|
97
|
+
side, so `tree_changed` is `1` only when the whole verification was a single lane run that
|
|
98
|
+
changed the tree (`verification.lanes.json`'s `mutated` says whether it changed at all). In lanes
|
|
99
|
+
mode `verification.flaky` holds `lanes=<names>` and, per flaky lane, `<lane>.first_exit=` and
|
|
100
|
+
`<lane>.retries_used=`.
|
|
101
|
+
|
|
78
102
|
with worktrees and branches at:
|
|
79
103
|
|
|
80
104
|
```
|
|
@@ -85,11 +109,21 @@ forge/<run-id>-integration integration branch
|
|
|
85
109
|
|
|
86
110
|
`control.log` lines look like
|
|
87
111
|
`{"at": 1761200000.5, "actor": "ui", "action": "set", "task": null, "key": "qa-threshold", "value": "P2", "previous": "P1"}`
|
|
88
|
-
(`actor` is `cli` or `ui`; `action` is `set`, `pin
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
112
|
+
(`actor` is `cli` or `ui`; `action` is `set`, `pin`, `unpin`, `drain`, `resume`, `stop`, `retry` or
|
|
113
|
+
`add`; `key` is the control's name, or `pin`; `task` is null for a plan-wide control). A queued
|
|
114
|
+
`retry` or `add` also carries its `request` id, and the scheduler later appends the outcome under
|
|
115
|
+
the same id:
|
|
116
|
+
`{"at": 1761200030.1, "actor": "scheduler", "action": "retry", "task": "docs", "key": null, "value": "sol:high", "previous": null, "request": "…", "outcome": "refused", "reason": "the task is running"}`
|
|
117
|
+
(`outcome` is `applied` or `refused`). `scheduler.live`, `retry_budget`, `infra_budget`, the
|
|
118
|
+
per-task `retry_budget`, `drain`, `stop` and `infra.paused` exist only while the scheduler is live:
|
|
119
|
+
it publishes the flags it was given when it starts, re-reads them at every decision and removes
|
|
120
|
+
them when it stops, which is why `forge control` refuses a budget change, a drain or a stop outside
|
|
121
|
+
a live run. A request still queued then is refused (`run ended`, or `left by an earlier run` at the
|
|
122
|
+
next start). See [live controls](decomposed-runs.md#changing-a-run-while-it-works).
|
|
123
|
+
|
|
124
|
+
`infra.paused` holds one entry per paused scope: `scope` (`all`, `harness:<h>` or
|
|
125
|
+
`model:<h>/<m>`), `class`, `harness`, `model`, the `tasks` it holds, `cycle` (which wait this is),
|
|
126
|
+
`until` (epoch seconds, null while not waiting) and `exhausted` (its waits are used up).
|
|
93
127
|
|
|
94
128
|
The worktree root is a **sibling of the repo, never `TMPDIR`**. Isolated worktrees are never
|
|
95
129
|
pushed, so a temp root that gets cleaned takes the only copy of that work with it.
|
package/docs/commands.md
CHANGED
|
@@ -16,8 +16,8 @@ harness (`/forge`); this command installs forge and drives its optional tools.
|
|
|
16
16
|
| `forge version [--check]` | the installed version, and whether a newer release is out |
|
|
17
17
|
| `forge fractal …` | opt-in Fractal execution; see [the command group](fractal.md#forge-fractal-command-group) |
|
|
18
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 `
|
|
20
|
-
| `forge config show
|
|
19
|
+
| `forge control show\|set\|pin\|unpin\|drain\|resume\|stop\|retry\|add PLAN_DIR …` | change a live plan: `set` takes `qa-threshold`, `timeout`, `escalate-after`, `escalate-effort` (`on`/`off`), `verify-retries`, `infra-backoff` (a backoff shape; `none` drops it), `retry-budget`, `infra-retries` or `max-parallel` (1-64) (the last three 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. While a scheduler runs: `drain` starts nothing new until `resume` (a run with nothing left to start ends as usual); `stop [--now]` ends the run once the running tasks finish (`--now` interrupts them; `run` exits 130 without verifying, unless every task had merged by then: it then verifies and exits 0 as usual); `retry PLAN_DIR TASK [--dwarf SPEC]` and `add PLAN_DIR TASK` (a row appended to `tasks.tsv`) queue a request the scheduler applies or refuses. `show` (`--json` for JSON) also says whether the run is drained or stopping and lists its infrastructure pauses. Every change and every request's outcome is logged in `control.log`. Exit 2 invalid input, 3 refused. See [live controls](decomposed-runs.md#changing-a-run-while-it-works) |
|
|
20
|
+
| `forge config show [--repo DIR] [--json]` / `forge config set <key> <value> --repo DIR [--json]` / `forge config unset <key> --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` (that one does not need `--repo`). `-` as a value reads stdin. Exit 2 on invalid input |
|
|
21
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
22
|
| `forge issues RUN [--apply] …` | file the review findings a run left open as GitHub issues; see [below](#forge-issues) |
|
|
23
23
|
| `forge ui open\|status\|stop` | forge-ui, the run viewer; see [the command group](forge-ui.md#forge-ui-command-group) |
|
|
@@ -41,7 +41,8 @@ solo run), so a run started meanwhile fails to start instead of racing the delet
|
|
|
41
41
|
What counts as the run's is decided from the run id, not read from the run directory: a worktree
|
|
42
42
|
under `<repo>/../.forge-worktrees/<run id>/` on `forge/<run id>/<task>` or
|
|
43
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
|
|
44
|
+
is `dirty`; neither is touched, and a dirty one keeps the run directory only when `--worktrees`
|
|
45
|
+
was asked. Branches are reported
|
|
45
46
|
`merged` or `UNMERGED`, so you see what deleting them would lose. `--dry-run` changes nothing and
|
|
46
47
|
reports; `--yes` skips the prompt for the run id (needed without a terminal); `--json` prints one
|
|
47
48
|
object, on failure too. Exit 0 ok, 2 refused input, 3 busy or the run is active, 4 failed during
|
|
@@ -190,8 +191,13 @@ forge-dispatch.sh dwarf <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>
|
|
|
190
191
|
forge-dispatch.sh qa <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--yolo] [--dry-run]
|
|
191
192
|
[--native-review [--review-base <ref>]]
|
|
192
193
|
forge-dispatch.sh planner <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>] [--dry-run]
|
|
194
|
+
forge-dispatch.sh efforts --spec <spec>
|
|
193
195
|
```
|
|
194
196
|
|
|
197
|
+
`efforts` prints the efforts the spec's pairing accepts, weakest first, one per line (nothing
|
|
198
|
+
when the pairing has no effort dial); a literal model id with a harness takes that harness's
|
|
199
|
+
whole ladder. It never dispatches and spends no quota. The retry policy's effort step reads it.
|
|
200
|
+
|
|
195
201
|
| Option | Meaning |
|
|
196
202
|
|---|---|
|
|
197
203
|
| `--prompt-file <f>` | file holding the prompt (required for `dwarf`/`qa`) |
|
|
@@ -209,7 +215,7 @@ forge-dispatch.sh planner <spec> --prompt-file <f> [--repo <dir>] [--run-dir <d>
|
|
|
209
215
|
`8` an **infrastructure failure** (quota or usage limit, auth, rate limit, network, or an
|
|
210
216
|
empty answer) — nothing about the work was judged, so callers pause instead of counting a
|
|
211
217
|
failure. On `8`, `<run-dir>/<role>.infra` holds `class=`, `retry_after=`, `detail=`, `rc=`,
|
|
212
|
-
`role=`.
|
|
218
|
+
`role=`, `harness=`, `model=`.
|
|
213
219
|
|
|
214
220
|
**Timeout precedence.** An explicit `--timeout`, then `FORGE_TIMEOUT` (an explicit `0` wins
|
|
215
221
|
and disables the watchdog), then the optional fifth `timeout` column of the model's
|
|
@@ -327,15 +333,21 @@ forge-parallel.sh plan <plan-dir> --repo <dir> [routing flags] [--planner <
|
|
|
327
333
|
[--reviewer-session | --no-reviewer-session]
|
|
328
334
|
[--explore E] [--ui | --no-ui] [--fail-first | --no-fail-first]
|
|
329
335
|
forge-parallel.sh run <plan-dir> [--max-parallel N] [--yolo-dwarf] [--yolo-qa] [--dry-run]
|
|
330
|
-
[--verify <cmd>
|
|
331
|
-
[--
|
|
336
|
+
[--verify <cmd> | --verify-lane 'name[opts]=cmd' ...]
|
|
337
|
+
[--verify-parallel N] [--setup <cmd>] [--timeout S]
|
|
338
|
+
[--retry-failed N] [--infra-retries M] [--infra-backoff SHAPE]
|
|
339
|
+
[--infra-fallback | --no-infra-fallback]
|
|
332
340
|
[--qa-threshold P0|P1|P2|P3|none] [--verify-retries N]
|
|
341
|
+
[--escalate-after N] [--escalate-effort | --no-escalate-effort]
|
|
333
342
|
[--fractal | --no-fractal] [--fractal-<limit> <n>]
|
|
334
343
|
forge-parallel.sh retry <plan-dir> <task-id> [--dwarf <spec>] [--timeout S]
|
|
335
344
|
[--qa-threshold Pn|none] [--verify-retries N]
|
|
345
|
+
[--verify <cmd> | --verify-lane 'name[opts]=cmd' ...] [--verify-parallel N]
|
|
346
|
+
[--escalate-after N] [--escalate-effort | --no-escalate-effort]
|
|
336
347
|
forge-parallel.sh accept <plan-dir> <task-id> --reason "<why>" --approved
|
|
337
348
|
forge-parallel.sh review <plan-dir> [--qa <spec>] [--yolo-qa] [--qa-threshold Pn]
|
|
338
349
|
forge-parallel.sh integrate <plan-dir> --approved [--final-review <qa-spec>] [--verify-retries N]
|
|
350
|
+
[--verify-parallel N]
|
|
339
351
|
forge-parallel.sh split <plan-dir> <new-plan-dir> --tasks <id,id> [--dry-run]
|
|
340
352
|
forge-parallel.sh combine <new-plan-dir> <plan-dir> <plan-dir>... [--verify <cmd>] [--dry-run]
|
|
341
353
|
```
|
|
@@ -354,17 +366,44 @@ forge-parallel.sh combine <new-plan-dir> <plan-dir> <plan-dir>... [--verify <c
|
|
|
354
366
|
|---|---|---|---|
|
|
355
367
|
| `--timeout S` | run, retry | `timeout` | per-dispatch timeout in seconds (`0` disables); wins over `FORGE_TIMEOUT` |
|
|
356
368
|
| `--retry-failed N` | run | no — this run only | re-queue a task the reviewer rejected up to `N` more times inside the run |
|
|
357
|
-
| `--infra-retries M` | run | no — this run only | wait out up to `M` infrastructure stops instead of
|
|
369
|
+
| `--infra-retries M` | run | no — this run only | wait out up to `M` infrastructure stops per paused scope (a model, a harness, or everything) instead of ending the run |
|
|
370
|
+
| `--infra-backoff SHAPE` | run | `infra_backoff` | the waits between those stops when the provider gave no retry-after: `exp:B[,C]`, `linear:S,T[,C]` or `list:a,b,...` in seconds (default `exp:60`) |
|
|
371
|
+
| `--infra-fallback` | run | `infra_fallback` | a dwarf stopped by a rate limit moves to the next healthy model of its tier pool instead of waiting (off by default; `--no-infra-fallback` turns it off) |
|
|
358
372
|
| `--qa-threshold Pn` | run, retry | `qa_threshold` | least severe finding that still blocks; milder ones become known issues; `none` clears |
|
|
359
|
-
| `--verify-retries N` | run, retry, integrate | `verify_retries` | reruns of a failed verify command (default `1`, `0` = strict single run) |
|
|
373
|
+
| `--verify-retries N` | run, retry, integrate | `verify_retries` | reruns of a failed verify command, or of each failed lane (default `1`, `0` = strict single run) |
|
|
374
|
+
| `--verify-lane 'name[opts]=cmd'` | run, retry | `verify.d/<name>` | one verification lane; repeatable. Options as in a lane file, comma-separated (`group=g`, `first`, `retries=n`, `reports=dir`, `baseline=file`). The first one of an invocation replaces the plan's earlier lanes and `--verify`; see [verification lanes](../references/decompose.md#execution-checks-and-integration-verification) |
|
|
375
|
+
| `--verify-parallel N` | run, retry, integrate | `verify_parallel` | lanes run at once, 1 to 32 (default `3`) |
|
|
376
|
+
| `--escalate-after N` | run, retry | `escalate_after` | failed attempts on one model before the next goes a tier up (default `3`, `0` = off) |
|
|
377
|
+
| `--escalate-effort` | run, retry | `escalate_effort` | at the top tier, retry the same model once more at its next accepted effort before stopping (off by default; `--no-escalate-effort` turns it off) |
|
|
360
378
|
|
|
361
379
|
**Exit codes:** `0` ok · `2` usage or validation · `3` precondition (not a git repo, …) ·
|
|
362
380
|
`5` some task failed QA, or the combined verification failed · `6` integration conflict ·
|
|
363
381
|
`8` **paused on an infrastructure failure** (quota, auth, rate limit, network): no attempt was
|
|
364
|
-
spent and nothing was judged — fix the cause and run the same command again
|
|
382
|
+
spent and nothing was judged — fix the cause and run the same command again ·
|
|
383
|
+
`130` **interrupted or stopped** (a signal, or `forge control stop`): the running tasks are
|
|
384
|
+
`INTERRUPTED` and verification was skipped or stopped; the summary prints the `retry` for each.
|
|
365
385
|
|
|
366
386
|
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).
|
|
367
387
|
|
|
388
|
+
## `scripts/forge-verify.py`
|
|
389
|
+
|
|
390
|
+
The verification lane runner `run`, `retry` and `integrate` use when lanes are declared. You can
|
|
391
|
+
run it by hand to check or try a lanes directory:
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
forge-verify.py lanes --lanes-dir DIR [--checkout DIR] [--json]
|
|
395
|
+
forge-verify.py run --checkout DIR --out DIR --lanes-dir DIR [--parallel N] [--retries N]
|
|
396
|
+
[--fingerprint-cmd CMD]
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
`lanes` lists the lanes with their options and checks them (with `--checkout`, also that
|
|
400
|
+
`reports=` and `baseline=` stay inside it and the baseline exists). `run` runs them in the
|
|
401
|
+
checkout as a forge run does and writes `verification.lanes.json`, `verification.runs.tsv` and
|
|
402
|
+
the per-lane logs into `--out` (`--parallel` default 3, `--retries` default 1).
|
|
403
|
+
|
|
404
|
+
**Exit codes:** `0` every lane passed and the tree is unchanged · `1` a lane failed, or the tree
|
|
405
|
+
changed · `2` configuration error (nothing ran) · `130` interrupted.
|
|
406
|
+
|
|
368
407
|
## `scripts/forge-memory.sh` and `scripts/forge-install.sh`
|
|
369
408
|
|
|
370
409
|
See [project memory](memory.md#scriptsforge-memorysh) and [install](install.md#scriptsforge-installsh).
|
package/docs/decomposed-runs.md
CHANGED
|
@@ -193,6 +193,14 @@ all their child invocations and QA. See [decomposed Fractal execution](../refere
|
|
|
193
193
|
|
|
194
194
|
## Resuming an interrupted run
|
|
195
195
|
|
|
196
|
+
Ctrl-C (or a SIGTERM) on `run` stops the running tasks' process groups, waiting up to
|
|
197
|
+
`FORGE_INTERRUPT_GRACE` seconds (10 by default) before killing what is left, and stops any
|
|
198
|
+
harness that outlived its dispatch. A task that had already finished is reaped first (a PASS
|
|
199
|
+
still merges); only the tasks still running become `INTERRUPTED`, with their partial work kept
|
|
200
|
+
in the worktree. Verification is skipped, or stopped if it had started (`verification.status`
|
|
201
|
+
`INTERRUPTED`, not rerun). The summary lists each interrupted task with its `retry` command,
|
|
202
|
+
the plan lock is released, and `run` exits 130.
|
|
203
|
+
|
|
196
204
|
Run `run` again to skip MERGED tasks, merge saved PASS results after fingerprint checks,
|
|
197
205
|
and dispatch eligible pending tasks. Tasks paused on an infrastructure failure (`INFRA`) are
|
|
198
206
|
dispatched again without any flag, since nothing was wrong with the work. Failed and
|
|
@@ -200,6 +208,9 @@ interrupted tasks need an explicit `retry` (or `run --retry-failed N` for reject
|
|
|
200
208
|
Their worktrees and pinned baselines remain available. Concurrent run/retry/integrate
|
|
201
209
|
operations for the same plan are excluded by an advisory lock.
|
|
202
210
|
|
|
211
|
+
To pause a run on purpose, drain it instead of signalling it (see below): nothing is
|
|
212
|
+
interrupted, and `forge control resume` continues the same run.
|
|
213
|
+
|
|
203
214
|
For a Fractal-backed run, use `forge fractal resume RUN_ID` to recover recorded execution
|
|
204
215
|
and pipeline checkpoints. A task/subtree selector resumes only that execution scope.
|
|
205
216
|
Explicit `retry` retains the backend and frozen pools; a replacement dwarf must already
|
|
@@ -213,12 +224,35 @@ belong to that pool. See [recovery](../references/fractal.md#limits-and-lifecycl
|
|
|
213
224
|
forge control show <plan-dir> [--json] # every control, per-task overrides, pins, recent changes
|
|
214
225
|
forge control set <plan-dir> qa-threshold P2 # also --task <id>; P0-P3, none, or inherit (task only)
|
|
215
226
|
forge control set <plan-dir> retry-budget 3 [--task <id>] # automatic retries; live scheduler only
|
|
216
|
-
forge control set <plan-dir> infra-retries 2 # infrastructure waits; live scheduler only
|
|
227
|
+
forge control set <plan-dir> infra-retries 2 # infrastructure waits per scope; live scheduler only
|
|
228
|
+
forge control set <plan-dir> max-parallel 2 # tasks at once, 1-64; live scheduler only
|
|
229
|
+
forge control set <plan-dir> infra-backoff linear:60,60 # the next infrastructure wait; none = exp:60
|
|
230
|
+
forge control set <plan-dir> escalate-effort on # the effort step before a policy stop
|
|
217
231
|
forge control set <plan-dir> timeout|escalate-after|verify-retries <n>
|
|
218
232
|
forge control pin <plan-dir> <task> sol:high:codex # the model the next full retry uses, once
|
|
219
233
|
forge control unpin <plan-dir> <task>
|
|
220
234
|
```
|
|
221
235
|
|
|
236
|
+
And to steer the scheduler itself (each needs a live run, exit 3 otherwise):
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
forge control drain <plan-dir> # start nothing new; running tasks finish, the run waits for resume
|
|
240
|
+
forge control resume <plan-dir> # end the drain
|
|
241
|
+
forge control stop <plan-dir> # finish what runs, start nothing, end the run (exit 130)
|
|
242
|
+
forge control stop <plan-dir> --now # interrupt the running tasks too, like Ctrl-C
|
|
243
|
+
forge control retry <plan-dir> docs --dwarf sol:high # queue a retry of a stopped or failed task
|
|
244
|
+
forge control add <plan-dir> docs-fix # queue a row you appended to tasks.tsv (with its prompt.md)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
A stop skips verification and exits 130, unless every task had merged by then, and a drain
|
|
248
|
+
with nothing left to start lets the run end as usual: both act on work still to do.
|
|
249
|
+
`retry` and `add` only queue a request in `control.requests/`; the scheduler applies or refuses
|
|
250
|
+
it at its next pass and logs the outcome in `control.log` under the same request id (`forge
|
|
251
|
+
control show` lists the log). A retry is prepared exactly as `forge-parallel.sh retry` prepares one,
|
|
252
|
+
so a task the policy stopped needs `--dwarf`; it spends no automatic retry budget. An added row
|
|
253
|
+
may depend only on tasks the run already knows. Neither outlives the run that was live when it
|
|
254
|
+
was queued, and both are refused once the run is stopping.
|
|
255
|
+
|
|
222
256
|
Each change is validated, written under `control.lock`, and says when it applies:
|
|
223
257
|
|
|
224
258
|
- **The QA threshold is read once per attempt**, at the start of the task's next attempt; the
|
|
@@ -244,8 +278,15 @@ Each change is validated, written under `control.lock`, and says when it applies
|
|
|
244
278
|
worktree. A marker the next retry will discard is reported as `pinned`.
|
|
245
279
|
Fractal plans never apply pins, and a MERGED task refuses one.
|
|
246
280
|
- **Who decided an escalation.** The last column of `tasks/<id>/escalations.tsv` is `policy`
|
|
247
|
-
(`--escalate-after`), `retry` (a typed `retry --dwarf`)
|
|
281
|
+
(`--escalate-after`), `retry` (a typed `retry --dwarf`), `pin` or `fallback`
|
|
282
|
+
(`--infra-fallback` moved a task off a model at capacity); rows from before it was added
|
|
248
283
|
have four columns and read as `policy`.
|
|
284
|
+
- **Max parallel and the backoff apply at the next decision.** A lower `max-parallel` lets the
|
|
285
|
+
running tasks finish and never stops one; `infra-backoff` shapes the next infrastructure wait,
|
|
286
|
+
not the one already counting down.
|
|
287
|
+
- **The effort step re-decides stopped tasks.** Turning `escalate-effort` on clears the policy's
|
|
288
|
+
stop markers, so a task stopped at the top tier is tried at its model's next effort on its
|
|
289
|
+
next retry.
|
|
249
290
|
|
|
250
291
|
Every change is appended to `control.log` (one JSON line: `at`, `actor` `cli` or `ui`, `action`,
|
|
251
292
|
`task`, `key`, `value`, `previous`) and recorded in the dataset as a `control` event, so a run's
|
package/docs/forge-ui.md
CHANGED
|
@@ -55,6 +55,20 @@ following its log as it grows. It is read from the agent CLI's own log, whicheve
|
|
|
55
55
|
wrote it (as plain text for those that log no events yet), or for an older claude run from
|
|
56
56
|
Claude's session file on this machine.
|
|
57
57
|
|
|
58
|
+
The *Verification* node opens the run's verification in the inspector. While it runs you see
|
|
59
|
+
for how long, the step a lane announced (`::forge step`, see
|
|
60
|
+
[verification lanes](../references/decompose.md#execution-checks-and-integration-verification))
|
|
61
|
+
and its last printed line, a warning after five minutes with no output, and the live output of
|
|
62
|
+
the lane that printed last (or of the one you choose). Once it fails, the failing tests come
|
|
63
|
+
first, by lane and marked new or known (from the lanes' JUnit or TAP reports), each with its
|
|
64
|
+
message, an excerpt and a link that opens the lane's log at that line; a lane without reports
|
|
65
|
+
shows the end of its log and the step it ended in. Below, every lane with its state (flaky and
|
|
66
|
+
known called out), time, runs and test counts; a lane's name opens its output. A single verify
|
|
67
|
+
command shows the newest of its logs. On the *Execution*
|
|
68
|
+
view the verification has rows of its own after the tasks, one per lane with a bar per run and
|
|
69
|
+
reruns marked (a single command's runs sit back to back, dashed, because only their durations
|
|
70
|
+
are known), and its finish node counts the lanes and reruns.
|
|
71
|
+
|
|
58
72
|
### Controls
|
|
59
73
|
|
|
60
74
|
forge-ui reads everything, and it changes things only by calling forge's own commands: it
|
|
@@ -64,12 +78,19 @@ indistinguishable from the same command typed in a terminal, except that `contro
|
|
|
64
78
|
`ui` instead of `cli`. Every change asks you to confirm and says when it takes effect.
|
|
65
79
|
|
|
66
80
|
- **Run controls** (a plan's inspector): the QA threshold, the per-attempt timeout, how many
|
|
67
|
-
failures before escalating,
|
|
68
|
-
and
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
failures before escalating, the effort step, verification retries, the infrastructure backoff,
|
|
82
|
+
and, while a scheduler is live, the retry and infrastructure-retry budgets and max parallel.
|
|
83
|
+
A live run also gets **Drain** (start nothing new; *Resume* ends it), **Stop** (finish what
|
|
84
|
+
runs, then end the run) and **Stop now** (interrupt the running tasks), and one line per
|
|
85
|
+
infrastructure pause: the model or harness it holds, the class, its tasks, and a countdown to
|
|
86
|
+
its next try, or *budget used up*. A task has its own panel for a threshold override
|
|
87
|
+
(including *None*, which exempts it from the run's threshold), its own retry budget, a
|
|
88
|
+
**model pin**: the model its next full retry uses, once, and, on a live run, **Retry now**
|
|
89
|
+
for a task that stopped or failed, on the policy's choice or a model you name. A retry is
|
|
90
|
+
queued; the panel says *queued*, then *applied* or *refused* with the scheduler's reason.
|
|
91
|
+
Each is `forge control`; see [decomposed runs](decomposed-runs.md#changing-a-run-while-it-works).
|
|
92
|
+
A control that cannot apply (a budget with no live scheduler, a merged task) is disabled and
|
|
93
|
+
says why.
|
|
73
94
|
- **Open findings:** the review findings a run left open (tolerated by `--qa-threshold`,
|
|
74
95
|
PLAUSIBLE, or left by the whole-run review), for this run or every run of its repository.
|
|
75
96
|
Findings of an outdated review carry an "outdated review" marker, and findings a person
|
package/docs/reviews.md
CHANGED
|
@@ -103,15 +103,30 @@ decomposed task then ends as **`INFRA`**, not `ERROR`/`FAIL`, and:
|
|
|
103
103
|
- **no attempt is spent** — a dwarf-stage stop refunds the counter; a QA-stage stop keeps the
|
|
104
104
|
dwarf's committed work and re-runs **QA only** next time (`tasks/<id>/resume`, revalidated
|
|
105
105
|
against the branch tip and fingerprint before it is trusted);
|
|
106
|
-
- the scheduler
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
(`
|
|
106
|
+
- the scheduler pauses only what the stop is about: a **rate limit** pauses that model on that
|
|
107
|
+
harness, a **quota** or **auth** stop pauses that harness, and anything else (network, an
|
|
108
|
+
empty answer) pauses everything, letting running tasks drain. A task whose next dispatch
|
|
109
|
+
needs a paused model or harness waits; the others keep running. Unstarted tasks stay
|
|
110
|
+
`PENDING` (never `BLOCKED`), and once nothing else can run `run` exits **8**: fix the cause,
|
|
111
|
+
then run the same command again;
|
|
112
|
+
- `run --infra-retries M` waits instead — up to `M` waits per paused scope, using the provider's
|
|
113
|
+
retry-after hint when it gave one (capped at 6 hours) and otherwise the backoff shape — and
|
|
114
|
+
resumes that scope's tasks in the same run. `--infra-backoff` picks the shape: `exp:60` by
|
|
115
|
+
default (60 s doubling to 30 min; `FORGE_INFRA_BACKOFF` sets that base), `exp:<base>,<cap>`,
|
|
116
|
+
`linear:<start>,<step>[,<cap>]` or `list:<a>,<b>,...`. `forge control set infra-backoff`
|
|
117
|
+
changes it for the next wait, and `forge control show` (and forge-ui) list each pause with
|
|
118
|
+
the time left;
|
|
119
|
+
- `run --infra-fallback` moves an implementer stopped by a rate limit to the next model of its
|
|
120
|
+
own tier pool that nobody paused, at once and with no attempt spent (recorded in
|
|
121
|
+
`escalations.tsv` with source `fallback`); a pinned task, or a pool with no healthy member,
|
|
122
|
+
waits as above;
|
|
111
123
|
- verification is skipped for a paused run (it is unfinished); the next `run` verifies at its end.
|
|
112
124
|
|
|
125
|
+
For a planned outage, `forge control drain <plan>` lets the running tasks finish and starts
|
|
126
|
+
nothing new until `forge control resume <plan>`, inside the same run.
|
|
127
|
+
|
|
113
128
|
`.infra` (`dwarf.infra`/`qa.infra`) holds `class=`, `retry_after=`, `detail=`, `rc=`,
|
|
114
|
-
`role=`. Detection is deliberately strict: strong phrases only, and ordinary text that merely
|
|
129
|
+
`role=`, `harness=`, `model=`. Detection is deliberately strict: strong phrases only, and ordinary text that merely
|
|
115
130
|
mentions "rate limit" in a reply that otherwise succeeded is never classified. A false
|
|
116
131
|
positive costs a pause, not a spent attempt. Under Fractal a dwarf-side infrastructure stop
|
|
117
132
|
still collapses to Fractal's own "failed" handling; QA-side stops propagate as above.
|
|
@@ -297,6 +312,16 @@ intermittent failure can be a real bug, so it is never passed off as a clean pas
|
|
|
297
312
|
that changes the tree is never retried. This deterministic rerun comes before Jev's optional
|
|
298
313
|
model-assisted triage, which then does not run.
|
|
299
314
|
|
|
315
|
+
With [verification lanes](../references/decompose.md#execution-checks-and-integration-verification)
|
|
316
|
+
the rerun is per lane: only a lane that failed runs again, alone, and a lane that passes on its
|
|
317
|
+
rerun is `flaky`. The run is then a pass, but `run`/`retry`/`integrate` print
|
|
318
|
+
`FLAKY: lane <name> failed once and passed on rerun`, and `verification.flaky` records each
|
|
319
|
+
such lane (`lanes=`, `<lane>.first_exit=`, `<lane>.retries_used=`); a lane whose every failing
|
|
320
|
+
test is in its baseline prints `known failures only: lane <name>`. A whole-run review's
|
|
321
|
+
verification summary lists every lane with its state (`unit: pass`, `db: flaky`, ...) and says
|
|
322
|
+
again which lane failed, which passed only on a rerun ("so its pass is not clean") and which
|
|
323
|
+
failed only on known tests. In lanes mode there is no whole-command rerun and no Jev triage.
|
|
324
|
+
|
|
300
325
|
## Native review
|
|
301
326
|
|
|
302
327
|
`--native-review` switches a codex reviewer to its purpose-built reviewer, for a diff too large
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@giamme/forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Multi-model coding with a reviewer that reads the code: plan, build in parallel worktrees, review every real diff, merge only what passes.",
|
|
5
5
|
"keywords": ["claude-code", "codex", "opencode", "agent-skill", "code-review", "multi-model"],
|
|
6
6
|
"license": "MIT",
|
package/references/dataset.md
CHANGED
|
@@ -350,7 +350,9 @@ run.
|
|
|
350
350
|
wave), and the expected number of first-try passes.
|
|
351
351
|
- It never creates the store, and prints nothing when the store is missing or has no history.
|
|
352
352
|
|
|
353
|
-
`forge-parallel.sh run` prints the same block before it dispatches
|
|
353
|
+
`forge-parallel.sh run` prints the same block before it dispatches, shortened: the tasks without
|
|
354
|
+
enough history share one line instead of a row each, and when no task has enough, the whole block
|
|
355
|
+
is one line pointing at `forge dataset forecast <plan>`. It runs with a time budget
|
|
354
356
|
(`FORGE_FORECAST_BUDGET_S`, default 3 seconds), prints one line and moves on if reading the
|
|
355
357
|
history takes longer, never prints errors and never changes the exit code. `--no-forecast` or
|
|
356
358
|
`FORGE_FORECAST=off` turn it off. The block is written to the plan as `forecast.json` and
|