@codedology/code-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 +114 -0
- package/README.md +46 -7
- package/docs/reference/blocks.json +618 -1
- package/docs/reference/config.md +36 -0
- package/package.json +1 -1
- package/schema/code-forge.schema.json +89 -0
- package/skill/references/adapters/claude-code.md +1 -1
- package/skill/references/adapters/solo.md +2 -2
- package/skill/references/adapters/subprocess.md +12 -2
- package/skill/references/code.md +21 -7
- package/skill/references/ledger.md +2 -2
- package/skill/references/proof.md +77 -2
- package/skill/references/review.md +29 -4
- package/skill/references/security.md +5 -5
- package/skill/scripts/forge +1 -1
- package/skill/templates/coder-brief.md +4 -2
- package/src/autopilot/binnacle.mjs +9 -3
- package/src/cli/block.mjs +300 -33
- package/src/cli/jev.mjs +22 -3
- package/src/cli/keys.mjs +156 -21
- package/src/cli/proof.mjs +35 -7
- package/src/cli/review-file.mjs +264 -13
- package/src/cli/spawn.mjs +44 -3
- package/src/config/validate.mjs +320 -5
- package/src/doctor/index.mjs +7 -5
- package/src/doctor/local.mjs +116 -8
- package/src/doctor/probes.mjs +38 -0
- package/src/engines/builders/codex.mjs +44 -4
- package/src/engines/sandbox-dirs.mjs +257 -0
- package/src/keys/store.mjs +128 -21
- package/src/ledger/write.mjs +7 -1
- package/src/proof/junit.mjs +530 -0
- package/src/proof/red-green.mjs +57 -9
- package/src/proof/red-parse.mjs +2 -0
- package/src/proof/runners.mjs +472 -0
- package/src/proof/xcresult.mjs +285 -0
- package/src/review/answers.mjs +445 -0
- package/src/review/deletion.mjs +106 -0
- package/src/review/engine.mjs +117 -31
- package/src/review/fixloop.mjs +70 -28
- package/src/review/gate-check.mjs +378 -80
- package/src/review/lenses/A.md +1 -0
- package/src/review/lenses/B.md +1 -0
- package/src/review/lenses/full.md +1 -0
- package/src/review/lenses/quick.md +1 -0
- package/src/review/lenses/recheck.md +1 -0
- package/src/review/reopen.mjs +256 -0
- package/src/review/route.mjs +232 -0
- package/src/review/schema-fallback.mjs +77 -22
- package/src/review/session-retry.mjs +44 -9
- package/src/review/stop-exits.mjs +15 -0
- package/src/review/test-quality.mjs +201 -0
- package/src/review/verb-forms.mjs +39 -0
- package/src/session/spawn.mjs +39 -2
- package/src/state/block.mjs +13 -3
- package/src/state/config-snapshot.mjs +39 -0
- package/src/state/run.mjs +4 -0
- package/src/util/forbidden.mjs +11 -1
- package/src/util/tmp.mjs +16 -4
- package/src/worker/engine.mjs +75 -9
- package/src/worker/loop.mjs +82 -15
- package/src/worker/queue.mjs +265 -10
- package/src/worker/review-state.mjs +346 -51
- package/src/worker/ticket.mjs +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,120 @@ waits on a second real consumer (plan §10.4, Q17).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.10.0] — 2026-10-13
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `keys.cache_hours` (1–24 h, default 8) and `keys set --op … --cache-hours <n>` set how long a key read from 1Password
|
|
14
|
+
stays cached; a lower value shortens an existing cached key at the next read, `keys set --op` refuses an invalid value
|
|
15
|
+
and other readers warn and use 8 h (B84, #14).
|
|
16
|
+
- `keys list` and `doctor` warn when a cached 1Password key has less than 1 hour left, and `jev ask` prints a re-link
|
|
17
|
+
command (`code-forge keys set jev --op <ref>`, the ref shell-quoted when needed) when the cached key expired and
|
|
18
|
+
1Password did not answer; the key index keeps the `op://` reference (B85, #14).
|
|
19
|
+
- `src/proof/junit.mjs`: a fail-closed JUnit XML reader and RED/GREEN classifier for `proof red-green` (no DTD or
|
|
20
|
+
entities, 8 MiB cap, only failed assertions count as RED; a SwiftPM bare failure needs a matching XCTest console
|
|
21
|
+
line); used by `proof.runners` from B87 (B86, #7).
|
|
22
|
+
- `proof.runners`: `proof red-green` proves a non-`node:test` file through the matching runner's argv and its JUnit
|
|
23
|
+
report; the list is frozen in the run snapshot, validated by rule 17 `proof-runners-invalid`, and the row carries
|
|
24
|
+
`runner`, `env_keys` and `failed_tests` (B87, #7).
|
|
25
|
+
- `swift` adapter for `proof.runners`: anchored `{test_filter}` (file base name or `Suite/test` case), reads the XCTest
|
|
26
|
+
report and its Swift Testing sibling, `swiftc` compile errors give `RED_INVALID compile`; opt-in live check
|
|
27
|
+
`CODE_FORGE_LIVE_SWIFT=1` verified on Swift 6.3.3 (B88, #7).
|
|
28
|
+
- PHP red→green through the `junit` adapter, verified live on Laravel 13 with PHPUnit 12 and Pest 4
|
|
29
|
+
(`CODE_FORGE_LIVE_PHP=1`); captured reports replace the hand-written PHP fixtures (B89, #7).
|
|
30
|
+
- The `xcodebuild` adapter for `proof.runners`: `xcode` keys, `{only_testing}` and `{result_bundle}` tokens, a precheck
|
|
31
|
+
for full Xcode and an available simulator (`xcode-missing`, `destination-unavailable`), a fail-closed `xcresulttool`
|
|
32
|
+
reader, and `RED_INVALID compile` for a build failure; fixtures captured from Xcode 26.6 (B102, #7).
|
|
33
|
+
- A live `xcodebuild` red→green check on an iOS simulator (`CODE_FORGE_LIVE_XCODE=1`), verified with Xcode 26.6 on an
|
|
34
|
+
iPhone 17 simulator; it skips with a reason without full Xcode or an available simulator (B103, #7).
|
|
35
|
+
- `review.routes`: size-based review routing. A file with at least `min_lines` lines is reviewed (L2) or judged (L3) by
|
|
36
|
+
the rule's model, with its own session timeout and second level; one signed `review.route` row per routed level;
|
|
37
|
+
config rule 18 `review-routes-invalid` (B90, #10).
|
|
38
|
+
- A `## test-quality` section in review packets lists the lines of a test file that read a source file and assert on its
|
|
39
|
+
text; every reviewer lens gets one rule to judge those lines (a hint, not a finding); recheck packets get the rule but
|
|
40
|
+
no section (B92, #10).
|
|
41
|
+
- `coder.sandbox` with `profile: workspace|toolchain|full` and `add_dirs`: `toolchain` gives the Codex coder one
|
|
42
|
+
`--add-dir` per entry, `full` runs it with `-s danger-full-access` and `doctor` warns; entries that are, hold or sit
|
|
43
|
+
inside a protected dir (home, `~/.ssh`, `~/.codex`, `~/.code-forge`, the run temp root, …) are refused
|
|
44
|
+
`sandbox-dir-refused` after symlinks are followed; the key is fixed for the run and `forge spawn --role coder --run`
|
|
45
|
+
refuses a changed live value `sandbox-changed` (B93, #10).
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- A timed-out review session is a broken result like a schema miss: at a packet's second broken result the second level
|
|
50
|
+
(`review.second_levels.<level>`, or a routed rule's `second`) is tried once in the same ticket;
|
|
51
|
+
`review.session_timeout` notes carry `packet_hash` and are signed, and `review.schema_fallback` gains `trigger:
|
|
52
|
+
schema|timeout` (B91, #10).
|
|
53
|
+
- The skill sends ONE fix message per block: after the coder's first COMPLETE it waits for every `review-file` ticket
|
|
54
|
+
and the block's tests, then sends every failing test and every open finding together; a later finding waits for the
|
|
55
|
+
next round, and the per-file round cap still counts per file (B94, #10).
|
|
56
|
+
- `block waive` and `block reopen` are human-only: they ask for a yes at a terminal, have no `--yes`, exit 2 and record
|
|
57
|
+
nothing with stdin or stdout not a terminal, and refuse a bad id, path, control character, unowned file or unknown
|
|
58
|
+
finding before asking; an autopilot grant does not change this; the prompt does not prove a human, since a
|
|
59
|
+
pseudo-terminal passes it (B80, #10).
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- The JUnit reader accepts the real SwiftPM 6.3 bare XCTest failure (`message="failure"`), not only `failed`; captured
|
|
64
|
+
Swift reports replace the hand-written fixtures (B88, #7).
|
|
65
|
+
- A missing class in Laravel 13's JSON-escaped AI-agent console summary is now read as `import`, not `error` (B89, #7).
|
|
66
|
+
|
|
67
|
+
## [0.9.0] — 2026-10-12
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- review-file --answers <ids> --of <source>: a fresh L2 session judges a fix made in another owned file; resolved ids
|
|
72
|
+
get signed review.answered rows bound to both content hashes, and the close gate counts a still-current answer like a
|
|
73
|
+
waiver (answered list on gate.review_waived_all).
|
|
74
|
+
- block reopen <id> --run <r> --file <path> --reason <text>: a human-only verb that restarts a stopped file on changed
|
|
75
|
+
content (or a lost one on its current content) with a full round 1; signed review.reopened row, one per anchor seq;
|
|
76
|
+
refusal codes reopen-same-content, reopen-tampered, reopen-not-stopped, reopen-block-not-open, reopen-not-owned,
|
|
77
|
+
reopen-config, reopen-already-recorded, reopen-write-failed.
|
|
78
|
+
- A stopped `review-file` answer carries `exits`, and the gate's `review_cap` and stopped-file `unreviewed` detail end
|
|
79
|
+
with the same exits (B73, issue #12).
|
|
80
|
+
- The review packet of a deleted owned file carries a `## deleted file` note: up to 20 tracked or untracked paths that
|
|
81
|
+
still name its basename (one bounded `git grep`, secret-like and control-character paths left out), `no references
|
|
82
|
+
found`, or `references not checked` (B74, issue #8).
|
|
83
|
+
- `review-file --fresh` drops a cached result that never counted and queues the ticket again; counted results refuse
|
|
84
|
+
`fresh-needs-reopen`, tampered ones `fresh-tampered`, and the cached marker is never moved (B75, issue #10 item 4).
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- Review state is saved under ~/.code-forge/runs/<run>/review-state/ instead of the temp root; older state files are
|
|
89
|
+
moved once after an anchor check; doctor warns about missing state files of active runs (#15)
|
|
90
|
+
- Review state: the reviewed text is stored as a git blob (reviewed_content_blob in the signed review.state body), so a
|
|
91
|
+
restored state keeps reviewed_content after the file changed; a missing, malformed or mismatching blob falls back to
|
|
92
|
+
the full-file review.
|
|
93
|
+
- A `patch_check` that closes at least one finding open before the patch (by id) and is under
|
|
94
|
+
`review.max_rounds_per_file` continues the fix loop at L2; a patch that closes nothing still stops
|
|
95
|
+
`l3_patch_exhausted` (B73, issue #12).
|
|
96
|
+
- The skill and docs name the review exits in order, say where review state lives and how the ledger rebuilds it; the
|
|
97
|
+
coder brief names `review-file --answers`, and the security reference lists `block reopen` as forbidden to a coder
|
|
98
|
+
(B76).
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
|
|
102
|
+
- A lost review state file is rebuilt from the signed ledger and recorded as review.state_restored; rounds, findings and
|
|
103
|
+
stops stay; with no ledger copy the ticket is refused as review-state-lost, not tampered (#15)
|
|
104
|
+
- A file whose every finding is cleared by accepted waivers counts as reviewed (reviewed_by_waiver) and block close
|
|
105
|
+
writes a signed gate.review_waived_all row; unknown severities are human-only (#9)
|
|
106
|
+
- Test isolation guard: new files of a run that existed before the test process (its lock, key or run directory) no
|
|
107
|
+
longer count as leaks; a new run id or any other new path still fails the process.
|
|
108
|
+
- `review-file --answers` reads the severity of every `review.cap` id from the signed refusal rows, so an id the close
|
|
109
|
+
cannot count is refused before a reviewer session (B79).
|
|
110
|
+
- The answers packet checks the source file with the secret-path rule, redacts each part before it is cut, keeps every
|
|
111
|
+
part and the whole packet inside the budget, and refuses `packet-too-large` when the fixed text alone is over it
|
|
112
|
+
(B79).
|
|
113
|
+
- `block reopen` refuses a non-string `tmp.root` as `reopen-config`, and `reopen-write-failed` names the error code,
|
|
114
|
+
never a path (B79).
|
|
115
|
+
- The ledger rotation race test forces the order of the two racers with an `afterLink` hook instead of scheduling them,
|
|
116
|
+
so it no longer fails at random under load (B81).
|
|
117
|
+
- The worker restart test waits up to 5 s for killed sessions to exit instead of checking once, so it no longer fails at
|
|
118
|
+
random under load (B82).
|
|
119
|
+
- `review-file --fresh`: a failed restore of the done marker no longer leaves the ticket looking pending; it writes a
|
|
120
|
+
refused `fresh-restore-failed` marker or keeps the claim, `block reopen` clears leftover claims, and the messages say
|
|
121
|
+
which state was left (B83).
|
|
122
|
+
|
|
9
123
|
## [0.8.0] — 2026-10-12
|
|
10
124
|
|
|
11
125
|
### Added
|
package/README.md
CHANGED
|
@@ -8,6 +8,43 @@ for cross-model, parallel, evidence-gated feature delivery — on Claude Code, C
|
|
|
8
8
|
> `examples/` have all landed (`docs/reference/blocks.json` lists every build block). What changed
|
|
9
9
|
> in each version is in [CHANGELOG.md](CHANGELOG.md).
|
|
10
10
|
|
|
11
|
+
## What's new in 0.9
|
|
12
|
+
|
|
13
|
+
In the next release:
|
|
14
|
+
|
|
15
|
+
- **Choose how long a 1Password key stays cached (B84).** Set `keys.cache_hours` (1 to 24, default 8) in `.code-forge.yml`, or `keys set <name> --op <ref> --cache-hours <n>` for one key. A lower value shortens keys that are already cached at the next read.
|
|
16
|
+
- **Warnings before a cached key runs out (B85).** `keys list` and `doctor` warn when a 1Password key has less than 1 hour left. When the cached key expired and 1Password does not answer, `jev ask` prints the exact command to re-link it: `code-forge keys set jev --op <ref>`.
|
|
17
|
+
- **A test report reader for red-green proof (B86).** code-forge can now read a JUnit XML test report (XCTest, Swift Testing, PHPUnit, Pest, pytest). A missing, broken or empty report, or an error that is not a failed assertion, never counts as red. B87 connects it to `proof red-green`.
|
|
18
|
+
- **Red-green proof for any test runner (B87).** A new `proof.runners` list in `.code-forge.yml` names a runner per test-file glob: an adapter (`junit` or `swift`), an argv with `{test_file}`, `{test_id}`, `{test_filter}` and `{report}`, optional `env` and `timeout_s`. `proof red-green` runs that argv and reads its JUnit report, so PHPUnit, Pest, XCTest or pytest tests can be proven. The list is fixed at `run start`; a bad entry refuses the proof and never falls back to `node:test`.
|
|
19
|
+
- **Red-green proof for Swift (B88).** A `proof.runners` entry with `adapter: swift` runs `swift test --parallel --filter {test_filter} --xunit-output {report}` and reads both the XCTest and the Swift Testing reports. The test filter is anchored, so a similar suite or test name is never picked up. A test that does not compile at base is `RED_INVALID compile` (a test of a new API needs the human waiver). Checked live with Swift 6.3.3 and Xcode 26.6.
|
|
20
|
+
- **Red-green proof for PHP (B89).** A `proof.runners` entry with `adapter: junit` and `[php, artisan, test, "{test_file}", --filter, "{test_filter}", --log-junit, "{report}"]` proves PHPUnit and Pest tests in a Laravel app. A test of a class the block added is `RED_INVALID import`, also when Laravel prints its AI-agent JSON summary. Checked live with PHP 8.4, Laravel 13, PHPUnit 12 and Pest 4.
|
|
21
|
+
- **Red-green proof for Xcode projects (B102).** A `proof.runners` entry with `adapter: xcodebuild` and an `xcode` object (`scheme`, `destination`, `test_target`) proves XCTest and Swift Testing tests through `xcodebuild test` on a simulator or on macOS. code-forge checks first that full Xcode and the simulator are there, runs only the named suite with `-only-testing`, and reads the result bundle. A build failure is `RED_INVALID compile`. code-forge never boots, creates or deletes a simulator.
|
|
22
|
+
- **Xcode red-green checked live (B103).** An opt-in live check (`CODE_FORGE_LIVE_XCODE=1`) proves XCTest and Swift Testing tests red→green through `xcodebuild test` on an iPhone simulator. It skips with a reason when full Xcode or a simulator is missing. Verified with Xcode 26.6.
|
|
23
|
+
- **Big files go to a big-context reviewer (B90).** Set `review.routes` once, for example `{min_lines: 400, model: <id>, session_timeout_s: 900}`. Files with that many lines get that model and timeout. No more editing `.code-forge.yml` per file. Each routed file gets a signed `review.route` row.
|
|
24
|
+
- **Timeouts reach the second level (B91).** A timeout now counts as a broken result, like an answer that fails the schema. At the second broken result on one file, the second-level model is tried at once, in the same ticket. You no longer wait for a second ticket.
|
|
25
|
+
- **Test-quality hint (B92).** A test that reads a source file and checks its text is a weak test. The review packet now lists those lines for the reviewer. The reviewer decides if it is a problem. The list is a hint, not a finding.
|
|
26
|
+
- **More room for the Codex coder (B93).** New setting `coder.sandbox`. With `profile: toolchain`, the Codex coder may also write to the folders you list in `add_dirs`, such as a build cache. With `profile: full`, the Codex sandbox is off and `doctor` warns you. Secret folders like `~/.ssh` are always refused. The setting is fixed for the whole run.
|
|
27
|
+
- **One fix round per block (B94).** The skill now waits for every review and test of a block. Then it sends the coder ONE fix message with every failing test and every open finding. It never sends findings one at a time.
|
|
28
|
+
- **Waive and reopen ask you at a terminal (B80).** `block waive` and `block reopen` now ask the human for a yes in their own terminal. There is no `--yes`. With no terminal they record nothing. The prompt is a speed bump, not proof of a human: a pseudo-terminal passes it.
|
|
29
|
+
|
|
30
|
+
In 0.9.0:
|
|
31
|
+
|
|
32
|
+
- **A lost review state is rebuilt, not reset.** When the review state file of a file is gone (for example, macOS cleaned its temp folder), the worker rebuilds it from the signed ledger and writes a `review.state_restored` row. Rounds, open findings and stops stay as they were. If the ledger cannot rebuild it, the ticket is refused as `review-state-lost`, not `tampered` (#15).
|
|
33
|
+
- **Review state no longer lives in the temp folder.** It is saved under `~/.code-forge/runs/<run>/review-state/`, so a temp cleanup or a worker restart does not touch it. A state file from an older run is moved there once, after a check against its signed anchor. `code-forge doctor` warns when a state file of an active run is missing and says whether the ledger can rebuild it (#15).
|
|
34
|
+
- **Waiving every finding is a real way out.** A file whose signed review on its current content left findings, all cleared by accepted waivers, now counts as reviewed (`reviewed_by_waiver`, never approved). `block close` writes one signed `gate.review_waived_all` row for it. A critical still needs a human waiver, and a finding with an unknown severity does too (#9).
|
|
35
|
+
- **Tests no longer fail because of your own live run.** The test guard used to fail when a code-forge run you had open wrote its lock file during `npm test`. Now new files of a run that existed before the tests are not counted as leaks. A new run or any other new file still fails the tests.
|
|
36
|
+
- **A restore brings back the exact reviewed text.** The reviewed text is now also kept as a git object, and the signed ledger points to it. After a lost state file is rebuilt, the next round reviews only what changed since the last review, even when the file changed. If git has removed the object, the round reviews the full file, as before (#15).
|
|
37
|
+
- **A fix in another file can answer a finding.** `review-file <file> --block <id> --answers <ids> --of <source>` asks a fresh reviewer whether a change in another owned file of the block fixes findings of the source file. Each finding it judges `resolved` gets a signed `review.answered` row, and the source file can then close as `reviewed_by_waiver` with an `answered` list. If either file changes later, the answer no longer counts. The answering file still needs its own approval (#9).
|
|
38
|
+
- **`block reopen` restarts a stopped file.** After you change a file whose review stopped, `code-forge block reopen <id> --run <r> --file <path> --reason <text>` starts a fresh round 1 for it. A file whose review state is lost can be reopened on its current content. Only a human may run it: a coder's command line is blocked, like `block waive`. The block's one L3 step stays used. The same content is refused, so you cannot simply roll again (#12, #15).
|
|
39
|
+
- **Safer answers packets and clearer reopen errors (B79).** An id named only by a `review.cap` row with no recorded severity is refused before any reviewer session. The answers packet checks the source file for secrets, stays inside the packet budget and refuses `packet-too-large` instead of going over it. `block reopen` refuses a bad `tmp.root` and names the cause of a failed write.
|
|
40
|
+
- **A last-chance patch that fixes something is progress (B73).** When the L3 patch closes at least one old finding and the file is under the round cap, the fix loop goes on at L2 instead of stopping `l3_patch_exhausted`. A stopped answer from `review-file` and the gate's `review_cap` detail now list the exits: `block reopen`, `block waive`, `review-file --answers`, re-decompose.
|
|
41
|
+
- **A steadier test suite (B81).** The ledger rotation race test forces the race order through a test hook, so it no longer fails at random under load.
|
|
42
|
+
- **Deleted files get a useful review (B74).** When a block deletes an owned file, the review packet says the file is deleted and lists up to 20 files that still name it, so the reviewer can look for dangling references. A deletion still needs an approval.
|
|
43
|
+
- **`review-file --fresh` (B75).** Runs a file's review again only when the cached result never counted (`stale`, `unavailable`, or a non-verdict refusal such as `other-run`). A counted result is refused `fresh-needs-reopen` and names `block reopen` and `block waive`; a tampered one is refused `fresh-tampered`. A coder may use it.
|
|
44
|
+
- **Another steadier test (B82).** The worker restart test waits for killed sessions to exit instead of checking once, so it no longer fails at random under load.
|
|
45
|
+
- **The review exits, in one place (B76).** `skill/references/review.md` §5, `code.md` and `docs/how-it-works.md` name the ways out of a stopped file in order: fix and the human's `block reopen`, `review-file --answers`, `block waive`, re-decompose. They also say `block attempt` never resets review state and that a lost state file is rebuilt from the ledger.
|
|
46
|
+
- **`review-file --fresh` fails closed (B83).** When a cached result cannot be put back, the ticket gets a refused `fresh-restore-failed` marker (or keeps its claim), so the worker does not run it by itself. `block reopen` clears it. Messages name the error code only.
|
|
47
|
+
|
|
11
48
|
## What's new in 0.8
|
|
12
49
|
|
|
13
50
|
In 0.8.0:
|
|
@@ -239,7 +276,7 @@ code-forge validate # loads and validates .code-forge.yml
|
|
|
239
276
|
code-forge resolve L1 # {provider, model, effort, fallback, cli} for a level
|
|
240
277
|
code-forge doctor --quick # config + links + key resolution only
|
|
241
278
|
code-forge list # what is installed where, and whether it still resolves
|
|
242
|
-
code-forge keys list # NAME / SOURCE / BACKEND / EXPIRES — never a value
|
|
279
|
+
code-forge keys list # NAME / SOURCE / BACKEND / EXPIRES — never a value; WARN under 1 h left
|
|
243
280
|
code-forge models # the model catalog per provider
|
|
244
281
|
code-forge --help # every verb, one per line
|
|
245
282
|
code-forge version
|
|
@@ -273,7 +310,7 @@ usage line.
|
|
|
273
310
|
| `validate` | `code-forge validate [--file <path>]` |
|
|
274
311
|
| `resolve` | `code-forge resolve <L0\|L1\|L2\|L3>` |
|
|
275
312
|
| `run` | `code-forge run start [--cwd <dir>] [--run <id>] [--engine <e>] [--worker-pid <pid>]` · `run start --reattach --run <id> [--worker-pid <pid>]` · `run status --run <id>` (with spent and budget USD) · `run reload --run <id>` (re-read `.code-forge.yml` mid-run) · `run end --run <id>` |
|
|
276
|
-
| `block` | `code-forge block open <id> --run <r> [--level L<n>] --owned <paths…> --acceptance <file> [--brief <file>] [--attempt <n>] [--base <sha>] [--lines <n>] [--kind code\|docs\|contract]` · `block attempt\|rebase <id> --run <r>` · `block close <id> --run <r> [--transcript <file>] [--report <file>] [--no-require-reviews]` · `block claim <id> <path> --run <r>` · `block stop <id> --run <r> --reason <text>` · `block waive <id> <finding-id> --run <r> --file <path> --reason <text>` (human-only) |
|
|
313
|
+
| `block` | `code-forge block open <id> --run <r> [--level L<n>] --owned <paths…> --acceptance <file> [--brief <file>] [--attempt <n>] [--base <sha>] [--lines <n>] [--kind code\|docs\|contract]` · `block attempt\|rebase <id> --run <r>` · `block close <id> --run <r> [--transcript <file>] [--report <file>] [--no-require-reviews]` · `block claim <id> <path> --run <r>` · `block stop <id> --run <r> --reason <text>` · `block waive <id> <finding-id> --run <r> --file <path> --reason <text>` · `block reopen <id> --run <r> --file <path> --reason <text>` (both human-only: you run them in your own terminal, they ask for a yes, and there is no `--yes`) |
|
|
277
314
|
| `worker` | `code-forge worker --run <id> [--cwd <dir>] [--poll-ms <n>] [--once]` — started detached by `run start`, never by a coder |
|
|
278
315
|
| `review` | `code-forge review [--base <ref>] [--files <path…>] [--acceptance <file> \| --intent "<text>"] [--run <id>] [--max <seconds>] [--json] [--keep-run]` — review only: no coder, no proof, never closes a block |
|
|
279
316
|
| `review-file` | `code-forge review-file <path> --block <id> [--run <id>]` (enqueue) · `review-file --wait <ticket> [--max <seconds>s]` (poll, default 90s; still running at `--max` prints `status: pending, reason: wait_timeout`) |
|
|
@@ -282,10 +319,10 @@ usage line.
|
|
|
282
319
|
| `author` | `code-forge author --job plan\|harden --brief <file> [--facts <file>] [--draft <file>] [--answers <file>] [--out <file>] [--run <id>] [--timeout <seconds>]` |
|
|
283
320
|
| `facts` | `code-forge facts --brief <file> [--sources <path>…] [--out <file>] [--run <id>] [--timeout <seconds>]` |
|
|
284
321
|
| `plan` | `code-forge plan check <plan-file> [--facts <sheet>] [--slug <slug>]` — every block's level must be the lane recorded by `jev ask lane --block <id>`; prints `lanes: B1 L1 (rules) · …` |
|
|
285
|
-
| `proof` | `code-forge proof tier --file <path> --risk <0-3> [--security] [--cwd <dir>]` · `proof export <block> --run <r> [--remove]` · `proof lock\|unlock\|restore <block> --run <r>` · `proof red-green <block> --run <r> --test <file[::case]> [--mechanism revert\|assertion-deletion]` |
|
|
322
|
+
| `proof` | `code-forge proof tier --file <path> --risk <0-3> [--security] [--cwd <dir>]` · `proof export <block> --run <r> [--remove]` · `proof lock\|unlock\|restore <block> --run <r>` · `proof red-green <block> --run <r> --test <file[::case]> [--mechanism revert\|assertion-deletion]` (a non-`node:test` file runs through its `proof.runners` entry) |
|
|
286
323
|
| `gates` | `code-forge gates detect\|run\|secret-scan\|safe-edit\|scope\|acceptance\|transcript-grep --cwd <dir> …` |
|
|
287
324
|
| `jev` | `code-forge jev ask <question-id> --state <file> [--cwd <dir>] [--slug <slug>] [--key-ref <ref>] [--block <id>] [--plan <file>] [--rules]` — `--rules` answers `lane`, `risk` or `security_sensitive` without Jev; writes to the project's ledger slug |
|
|
288
|
-
| `keys` | `code-forge keys list \| set <name> [--op <item-id\|link\|op://ref>] \| test <name> [--ref <ref>] \| remove <name>` |
|
|
325
|
+
| `keys` | `code-forge keys list \| set <name> [--op <item-id\|link\|op://ref> [--cache-hours <1-24>]] \| test <name> [--ref <ref>] \| remove <name>` |
|
|
289
326
|
| `ledger` | `code-forge ledger tail --slug <slug> [--n\|-n <count>]` · `ledger calibration --slug <slug> [--question <id>]` · `ledger outcome --slug <slug> --pr <n> --ci red\|green\|reverted` · `ledger outcome --slug <slug> --scan-git [--cwd <dir>] [--days <n>]` · `ledger add coder --run <r> --block <b> --usd <n> [--note "..."]` |
|
|
290
327
|
| `report` | `code-forge report --slug <slug> [--json] [--export <dir>]` — 13 sections, then the spend per run (open blocks included) and the total |
|
|
291
328
|
| `models` | `code-forge models [--refresh --from-cli-caches]` |
|
|
@@ -308,8 +345,8 @@ CLI verbs like any other and every one of them is exercised by this package's ow
|
|
|
308
345
|
`doctor` always prints this line — the signature is not a defense against an attacker who
|
|
309
346
|
already runs code as you, and no part of code-forge claims otherwise.
|
|
310
347
|
- **Keys never reach a coder process.** Provider and Jev keys resolve only inside the worker or the
|
|
311
|
-
orchestrator's own CLI calls (`env:<NAME>` → OS keychain → 1Password, cached
|
|
312
|
-
setup only). `keys list`/`keys test` never print a value; every stdout/stderr path is redacted.
|
|
348
|
+
orchestrator's own CLI calls (`env:<NAME>` → OS keychain → 1Password, cached for
|
|
349
|
+
`keys.cache_hours`: default 8 h, at most 24 h → ask at setup only). `keys list`/`keys test` never print a value; every stdout/stderr path is redacted.
|
|
313
350
|
- **A forbidden-command list** stops a coder from starting its own worker, waiving a review, or
|
|
314
351
|
running other orchestrator-only actions — rendered into each provider's own deny-list mechanism
|
|
315
352
|
(`--disallowedTools` for Claude, an execpolicy rules file plus prose for Codex).
|
|
@@ -327,7 +364,8 @@ CLI verbs like any other and every one of them is exercised by this package's ow
|
|
|
327
364
|
the warnings and the command list off. Every field is listed in [docs/privacy.md](docs/privacy.md).
|
|
328
365
|
- **No mutation testing.** Neither this package's own tests nor the product it ships run mutation
|
|
329
366
|
testing (Ricardo's ruling R14/Q16, 2026-09-25). Proof is plain unit and feature tests with exact
|
|
330
|
-
assertions, plus a red→green runner that proves a new test fails before the fix and passes after
|
|
367
|
+
assertions, plus a red→green runner that proves a new test fails before the fix and passes after (`node:test`
|
|
368
|
+
built in; any other runner through a `proof.runners` entry that writes a JUnit report).
|
|
331
369
|
|
|
332
370
|
## Configuration reference
|
|
333
371
|
|
|
@@ -346,6 +384,7 @@ new in 0.5, `autopilot.min_confidence` in 0.6):
|
|
|
346
384
|
| `review.multimodel_for_docs` | `false` | let docs and contract blocks use multimodel review too |
|
|
347
385
|
| `review.allow_open_book_codex` | `false` | let Codex run reviewer, judge, System 2 and plan author anyway |
|
|
348
386
|
| `review.session_timeout_s` | `300` | a review session that runs longer is killed and retried once |
|
|
387
|
+
| `review.routes` | none | big files go to another model: a file with at least `min_lines` lines is reviewed by the rule's `model`, with its own `session_timeout_s` and `second` level |
|
|
349
388
|
| `review.parallel_tickets` | `3` | review tickets the worker runs at once (1 to 16); `1` reviews one file at a time |
|
|
350
389
|
| `review.provider_concurrency` | anthropic `4`, openai `2`, xai `2` | review sessions at once per provider |
|
|
351
390
|
| `autopilot.min_confidence` | `0.7` | the lowest delegate confidence that is acted on; below it the question goes to you |
|