@codedology/code-forge 0.13.0 → 0.14.1
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 +22 -0
- package/README.md +136 -428
- package/docs/README.md +1 -1
- package/docs/reference/blocks.json +207 -1
- package/docs/reference/config.md +2 -0
- package/package.json +1 -1
- package/schema/code-forge.schema.json +8 -0
- package/skill/references/adapters/claude-code.md +1 -1
- package/skill/references/adapters/solo.md +1 -1
- package/skill/references/code.md +3 -3
- package/skill/references/ledger.md +4 -2
- package/skill/references/proof.md +1 -1
- package/skill/references/review.md +13 -6
- package/skill/references/security.md +5 -3
- package/skill/scripts/forge +1 -1
- package/src/cli/block.mjs +103 -31
- package/src/cli/report.mjs +2 -2
- package/src/cli/review-file.mjs +47 -35
- package/src/cli/upgrade.mjs +95 -15
- package/src/install/link.mjs +12 -6
- package/src/ledger/export.mjs +1 -1
- package/src/ledger/report.mjs +9 -3
- package/src/review/accept-hit.mjs +78 -0
- package/src/review/agent-waiver.mjs +201 -0
- package/src/review/gate-check.mjs +33 -24
- package/src/review/reopen.mjs +35 -14
- package/src/state/config-snapshot.mjs +1 -0
- package/src/util/forbidden.mjs +22 -0
- package/src/worker/queue.mjs +18 -2
package/README.md
CHANGED
|
@@ -1,462 +1,170 @@
|
|
|
1
1
|
# @codedology/code-forge
|
|
2
2
|
|
|
3
|
-
A CLI
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
In the next release:
|
|
14
|
-
|
|
15
|
-
In 0.13.0:
|
|
16
|
-
|
|
17
|
-
- **Every block gets the proof rule, with or without a `context` key (B118).** `code-forge context pack` no longer refuses a config with no `context` key. The pack then holds the block header and the proof rule.
|
|
18
|
-
- **Safer block open and close (B118).** `block open` refuses an owned or test path that has spaces and names no file, a common shell quoting slip. `block close` warns when the block has no green gates run.
|
|
19
|
-
- **Clean rule checks on Codex logs (B119).** Run `codex exec --json` and pass the log to `block close --transcript`. code-forge then checks only the commands Codex ran and the files it wrote. Agent messages, reasoning and command output no longer give false rule breaks. The close reason names each rule break once.
|
|
20
|
-
- **Gate results are recorded again (B120).** `gates run --run <r> --block <id>` now writes its `gate.done` row also when no gate uses `{test_files}`. Before, the row was missing, so `block close` warned after a green run and `status` showed no gate result.
|
|
21
|
-
- **Fair share between blocks (B101).** Set `review.fair_share: true` and each free review slot goes to the block with the fewest running reviews. A block with many queued files no longer makes another block wait. Without the key, the order stays oldest first.
|
|
22
|
-
- **Locks hold across processes (B105).** Ticket claims and the locks for files, blocks and the budget row now work across worker processes. Lock files live in `~/.code-forge/locks`. A lock of a dead process is taken over safely. A bad lock, or a break lock left by a crashed process, blocks its key until you remove it, and `code-forge doctor` names it.
|
|
23
|
-
- **Watch waits for the whole fix (B121).** In watch mode, a file's first commit is reviewed at once. A later commit of a file that already has a review is held, and a `watch.held` row records it. `review-file --wait-block` then queues one review for the file's latest content. A half-done fix commit no longer uses up the file's review rounds.
|
|
24
|
-
- **One registry file per worker (B106).** Each worker writes its own file in `.code-forge/workers/` and keeps it fresh with its heartbeat. A new worker starts only when the live count is under the limit, which is 1 for now. The count and the new file are written under one lock, so two workers that start at the same time cannot both run. A file of a dead worker is removed at the next start. A file that cannot be read blocks the start, and `code-forge doctor` names it.
|
|
25
|
-
- **The join shows findings before it rechecks (B122).** Sometimes the coder commits again before reading the last review. At `review-file --wait-block`, such a file is not reviewed again yet. The join answers `findings` with the old ticket, so the coder reads and fixes them first. The next join rechecks the latest content once. A blind commit no longer counts as a stall round.
|
|
26
|
-
- **A reopen clears old stop findings (B123).** After `block reopen` and a fresh review of the new content, the close no longer asks you to waive the findings of the old stop. Only the fresh review's findings count.
|
|
27
|
-
- **The test suite passes on machines that use code-forge on itself (B126).** A leak test no longer counts files that were already in the repo's `.code-forge` folder.
|
|
28
|
-
|
|
29
|
-
## What's new in 0.12
|
|
30
|
-
|
|
31
|
-
In 0.12.0:
|
|
32
|
-
|
|
33
|
-
- **Faster fix rounds (B99).** `code-forge gates run --run <r> --block <id> --changed` runs only the tests of files changed since the last green gate run, and `{changed_files}` passes only the changed files to lint or format gates. It falls back to the normal scope when it cannot be sure.
|
|
34
|
-
- **Write while reviews run (B100).** With `review.file_loop: overlap`, the coder enqueues each green file and keeps working. Before it ends, `forge review-file --wait-block <id> --run <r>` waits once for every file of the block.
|
|
35
|
-
- **Reopen after any stop (B114, #17).** Every review stop now records the content it reviewed. An older stop with unknown content can be reopened when the current content was never reviewed. A malformed `TESTS` line now gets its own clear error.
|
|
36
|
-
- **Python `*_test.py` tests pair with their source (B115).** Fix rounds and review packets now find `widget_test.py` for `widget.py`, as they already found `test_widget.py`.
|
|
37
|
-
- **Commit watch (B104).** Set `review.file_loop: watch` and the coder just commits each green file. The worker sees the new commits, queues each owned file for review and drops older pending reviews of the same file. `review-file --wait-block` waits for them all.
|
|
38
|
-
- **The proof rule travels with every block (B117).** Every context pack and every reviewer now carry one rule. Red→green: each new or changed test must fail on the old code first, then pass on the new code. No hand mutations. Proof scales with risk, and nothing is added that the task did not ask for.
|
|
39
|
-
|
|
40
|
-
## What's new in 0.11
|
|
41
|
-
|
|
42
|
-
In 0.11.0:
|
|
43
|
-
|
|
44
|
-
- **The release moves the README What's new list (B108).** `npm run release` now moves the "In the next release:" bullets under "In X.Y.Z:". A minor or major release starts a new "What's new in X.Y" heading. The empty anchor stays for the next block. The release refuses an empty CHANGELOG [Unreleased] or a missing anchor before it changes anything, and a failed check puts the README back with the other files. The checks now include `gen-config-doc --check`. `docs/releasing.md` has a releasing checklist.
|
|
45
|
-
- **The close writes the ticket lines (B96).** The coder's final report no longer needs a `reviewed <path> ticket <id>` line per file. `block close` prints one for every file the review gate accepts (approved, waived or answered), with the queue's ticket. `--json` and the block's done file carry them as `reviewed: [{file, ticket, via}]`. With `--report`, a hand line that names another ticket prints `WARN report ticket mismatch <path>` on stderr, and the close goes on.
|
|
46
|
-
- **A big-diff file steps up to a full review (B109).** A low-risk file whose diff is too big for the quick review budget used to stop with `split_required`, and splitting it only made the diff bigger. Now the review plans again as one full L2 session. If the diff fits the full budget, the file is reviewed. The `review.plan` row records the step as `step_up`.
|
|
47
|
-
- **A file that was too big can be reviewed again (B110).** A first-round `split_required` result ran no review. After you raise the budget and run `run reload`, `review-file` (or `review-file --fresh`) tries again with the same ticket. A recheck stop still needs `block reopen` or `block waive`.
|
|
48
|
-
- **A recheck that did not really review never stalls (B111).** A recheck on unchanged content runs no session and counts no round; it returns `reason: 'no-fix-hunks'`. A recheck answer that skips an open finding is a broken answer, not a "still open". So the stall rule sees only real rechecks. The recheck summary now shows each session's status and tokens.
|
|
49
|
-
- **Paired files for the reviewer, part 1 (B97).** code-forge can now find a changed file's test file (or a test's source file) by name, and list its test names or exported symbols in a small `## paired` packet section. The section is dropped first when the packet is too big. A reviewer can also ask for a new, untracked test file when the block owns and changed it. B98 sends these to the reviewers.
|
|
50
|
-
- **Reviewers see the paired test file (B98).** When a block changes `src/a.mjs` and `test/a.test.mjs`, the reviewer of `src/a.mjs` now gets the test names in a `## paired` section, in the first review and in rechecks. Tests named with `block open --tests` count too. The reviewer is told those tests exist, so it no longer reports them as missing. It can still ask for a test file's body, even a new untracked one the block owns.
|
|
51
|
-
- **Faster reviews (B112).** A review ticket reads the diffs of the block's other changed files only when the review asks for them, and only once.
|
|
52
|
-
- **No leftover workers (B113).** A worker stops by itself when its run record or its HOME is removed. `npm test` now fails when a test leaves a worker running.
|
|
53
|
-
|
|
54
|
-
## What's new in 0.10
|
|
55
|
-
|
|
56
|
-
In 0.10.0:
|
|
57
|
-
|
|
58
|
-
- **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.
|
|
59
|
-
- **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>`.
|
|
60
|
-
- **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`.
|
|
61
|
-
- **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`.
|
|
62
|
-
- **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.
|
|
63
|
-
- **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.
|
|
64
|
-
- **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.
|
|
65
|
-
- **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.
|
|
66
|
-
- **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.
|
|
67
|
-
- **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.
|
|
68
|
-
- **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.
|
|
69
|
-
- **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.
|
|
70
|
-
- **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.
|
|
71
|
-
- **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.
|
|
72
|
-
|
|
73
|
-
## What's new in 0.9
|
|
74
|
-
|
|
75
|
-
In 0.9.0:
|
|
76
|
-
|
|
77
|
-
- **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).
|
|
78
|
-
- **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).
|
|
79
|
-
- **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).
|
|
80
|
-
- **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.
|
|
81
|
-
- **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).
|
|
82
|
-
- **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).
|
|
83
|
-
- **`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).
|
|
84
|
-
- **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.
|
|
85
|
-
- **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.
|
|
86
|
-
- **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.
|
|
87
|
-
- **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.
|
|
88
|
-
- **`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.
|
|
89
|
-
- **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.
|
|
90
|
-
- **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.
|
|
91
|
-
- **`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.
|
|
92
|
-
|
|
93
|
-
## What's new in 0.8
|
|
94
|
-
|
|
95
|
-
In 0.8.0:
|
|
96
|
-
|
|
97
|
-
- **Run only the tests a block touches.** `block open --tests <paths>` names the block's test
|
|
98
|
-
files. A gate argv item exactly `{test_files}` becomes those files. When the block owns more
|
|
99
|
-
files than `gates.full_suite_threshold_files`, or no test file is known, the full suite runs.
|
|
100
|
-
The ledger row says which one ran. A gate can also be `{argv, env}`. Env values are never
|
|
101
|
-
printed. Gate env is not a secret store.
|
|
102
|
-
- **Laravel works under export, checked live.** A Laravel app on PHPUnit (no Pest) is now
|
|
103
|
-
detected. Export copies the Composer `vendor` folder instead of linking it, so the tests load
|
|
104
|
-
the block's code, not the main tree's. A live check (`CODE_FORGE_LIVE_PHP=1`) runs a Laravel
|
|
105
|
-
app on PHPUnit and on Pest through the export.
|
|
106
|
-
- **One git worktree per block.** With `proof.isolation: worktree`, `block open` gives each block
|
|
107
|
-
its own git worktree and branch (`proof.worktree.dir`, `branch`, `base`). Blocks in different
|
|
108
|
-
trees may own the same files. Nothing is pushed. `block close --remove-worktree` removes the
|
|
109
|
-
tree and keeps the branch. Gates, reviews, the close check and the mutation proof of that
|
|
110
|
-
block all run on the block's tree, never on the main checkout.
|
|
111
|
-
- **A context pack for coders.** Set `context: {rules, lessons, commands, max_lines}`.
|
|
112
|
-
`code-forge context pack --run <r> --block <id>` writes one file with the block's header,
|
|
113
|
-
the build and test commands, the project rules and the lessons, cut to `max_lines`. It prints
|
|
114
|
-
the path and a token estimate, and writes a signed `context.pack` row. Review packets now
|
|
115
|
-
carry the same rules and lessons. With no `context` key, nothing changes.
|
|
116
|
-
- **Coders prove a green test run.** A coder prints `TESTS <command> exit=<n>` just before its
|
|
117
|
-
COMPLETE sentinel. With `context.require_coder_tests: true` (fixed at `run start`),
|
|
118
|
-
`block close --report` refuses a report with no such line or a non-zero exit, even when
|
|
119
|
-
reviews are waived, and writes a signed `coder.tests` row when it passes.
|
|
120
|
-
- **Short status.** `code-forge status [--run <id>] [--json]` prints at most 10 lines per run:
|
|
121
|
-
state, mode, spend, and one line per open block with its level, model, last gate and open
|
|
122
|
-
findings. It is read-only. Every `block` verb takes `--json` and prints one JSON line, so an
|
|
123
|
-
orchestrator never has to read logs or poll transcripts.
|
|
124
|
-
- **A signal when a block ends.** Every block end writes `~/.code-forge/runs/<run>/blocks/<id>.done.json`
|
|
125
|
-
(status, commit, spend, open findings). With `hooks.on_block_end` (fixed at `run start`),
|
|
126
|
-
code-forge also runs your command once per block end, with the block id, status and file path
|
|
127
|
-
in its env, under a timeout, and writes a signed `hook.ran` row. A failing hook only warns.
|
|
128
|
-
- **Breaking: coders no longer push or open draft PRs by default.** `autonomy.coder_may_push` and
|
|
129
|
-
`autonomy.coder_may_open_draft_pr` now default to `false`. `init` asks both (default no) and
|
|
130
|
-
writes your answers. To keep the old behaviour, set both to `true` in `.code-forge.yml`.
|
|
131
|
-
- **Outside review rounds next to code-forge cost.** `code-forge ledger outside-review --run <r>
|
|
132
|
-
--pr <n> --rounds <n> --findings <n> [--link <url>] [--block <id>]…` records how many rounds an
|
|
133
|
-
outside reviewer needed on a PR (a later call for the same PR replaces it). `report` gets a
|
|
134
|
-
14th section, `outside_review`: per PR, the rounds and findings next to the code-forge cost
|
|
135
|
-
of its blocks.
|
|
136
|
-
- **A walk-through for brief-only runs.** [docs/brief-mode.md](docs/brief-mode.md) walks one task
|
|
137
|
-
from a brief to a closed block with an outside reviewer: related tests, a worktree, the context
|
|
138
|
-
pack, the done file and hook, `status`, and the outside review rounds in `report`. A test runs
|
|
139
|
-
the page's own config and steps, so the page and the CLI stay the same.
|
|
140
|
-
|
|
141
|
-
## What's new in 0.7
|
|
142
|
-
|
|
143
|
-
In 0.7.7:
|
|
144
|
-
|
|
145
|
-
- **Work from a brief, with no plan.** `run start --mode brief` marks the run as brief-only.
|
|
146
|
-
Then `block open` without `--level` picks the lane from the rules: the owned files,
|
|
147
|
-
`--lines` and `proof.tiers.high.paths`. A signed `decision` row records it with
|
|
148
|
-
`source: rules`. `--level` still wins, and `report` shows the mode of each run.
|
|
149
|
-
|
|
150
|
-
In 0.7.6:
|
|
151
|
-
|
|
152
|
-
- **An outside reviewer can replace the local review.** Set `review.external: {required: true,
|
|
153
|
-
name: <reviewer>}` in `.code-forge.yml`. `block close` then skips the per-file review check
|
|
154
|
-
and writes a signed `gate.reviews_waived` row with `by: config`. It needs no TTY and works
|
|
155
|
-
under autopilot. All other close checks still run. The key is fixed at `run start`, and a
|
|
156
|
-
coder can never own `.code-forge.yml`.
|
|
157
|
-
|
|
158
|
-
In 0.7.5:
|
|
159
|
-
|
|
160
|
-
- **An owned directory owns the files inside it, everywhere.** A block that owns `src/feature`
|
|
161
|
-
now owns `src/feature/a.swift` for `block open`, `block claim`, `block rebase`, the scope gate,
|
|
162
|
-
proof and the review worker, not only for `block close`. `block open` refuses a second block
|
|
163
|
-
that owns a file or folder inside it (or a folder around it), so two coders can no longer edit
|
|
164
|
-
the same files at once. A path that is already a file when the block opens owns only itself.
|
|
165
|
-
|
|
166
|
-
In 0.7.4:
|
|
167
|
-
|
|
168
|
-
- **Code moved between files is no longer read as deleted.** When a block moves code from one
|
|
169
|
-
file to another, each file's review packet now says where the lines went (or came from), so the
|
|
170
|
-
reviewer of the old file stops reporting the removal as a lost feature, also on rechecks. Every
|
|
171
|
-
hunk is still reviewed.
|
|
172
|
-
|
|
173
|
-
In 0.7.3:
|
|
174
|
-
|
|
175
|
-
- **A model that keeps failing the answer format gets a stand-in.** When a reviewer's answer
|
|
176
|
-
fails the schema twice on the same packet and you set `review.second_levels` for that level, the
|
|
177
|
-
worker retries that packet once with the second model, and the ledger records it. Each failed
|
|
178
|
-
answer's shape (its keys, types and schema errors, never its text) is logged, so you can see
|
|
179
|
-
what went wrong.
|
|
180
|
-
|
|
181
|
-
In 0.7.2:
|
|
182
|
-
|
|
183
|
-
- **Long documents get reviewed.** The packet budget (`review.budgets.full_in`) is now 32,000
|
|
184
|
-
tokens, and a Markdown file still too large is reviewed section by section instead of refused;
|
|
185
|
-
a `split_required` result now says its size and the budget.
|
|
186
|
-
|
|
187
|
-
In 0.7.1:
|
|
188
|
-
|
|
189
|
-
- **Short clean reviews count.** A clean pass (no findings, every hunk acknowledged, a summary)
|
|
190
|
-
needs only 40 output tokens on any diff size, so a correct short "no defect" review is no
|
|
191
|
-
longer refused as `too_short`.
|
|
192
|
-
|
|
193
|
-
In 0.7.0:
|
|
194
|
-
|
|
195
|
-
- **The close gate now checks every file.** `block close` could close a block with critical
|
|
196
|
-
findings still open: files inside an owned folder were skipped, and so was work committed
|
|
197
|
-
before `block open` or done in another worktree. Now every reviewed file is checked, a newer
|
|
198
|
-
failed review beats an older approval, a critical needs your waiver, a change outside the
|
|
199
|
-
block's files is refused, and `--no-require-reviews` asks you at a terminal.
|
|
200
|
-
|
|
201
|
-
## What's new in 0.6
|
|
202
|
-
|
|
203
|
-
In 0.6.1:
|
|
204
|
-
|
|
205
|
-
- **Never relax a rule alone.** A new skill rule (R17): the orchestrator and the delegate never
|
|
206
|
-
change, relax or remove a limit, threshold, budget, gate or review requirement. When a limit
|
|
207
|
-
blocks work they stop, show the data, propose options and wait for you.
|
|
208
|
-
- **Fixes from using code-forge on itself.** A verb run from a subfolder now uses the project's
|
|
209
|
-
ledger and config. `plan check` reads the list form the template shows. `facts` checks a flag
|
|
210
|
-
with `grep -rn -- <flag> <source folder>` instead of `--help`, so the check runs in the
|
|
211
|
-
delegate's sandbox.
|
|
212
|
-
|
|
213
|
-
In 0.6.0:
|
|
214
|
-
|
|
215
|
-
- **Autopilot.** Step away for up to 24 hours. `code-forge autopilot start` grants a delegate (a
|
|
216
|
-
fresh closed-book L2 or L3 session, never Codex) a few of your decisions: waive a warning or a
|
|
217
|
-
nit, one extra fix round past the review cap, the coder level. The orchestrator asks the
|
|
218
|
-
delegate first (`autopilot ask`) and acts only on an answer it acted on. A fixed deny list in
|
|
219
|
-
the code keeps the rest yours: critical and proof waivers, skipping reviews, plan and design
|
|
220
|
-
approval, any limit or rule change, budget raises, merges, destructive actions. Every answer is
|
|
221
|
-
a signed ledger row; each waiver opens a GitHub issue. See [docs/autopilot.md](docs/autopilot.md).
|
|
222
|
-
- **Budget per category.** `--budget review=<usd>,coding=<usd>` pauses a category at `--stop-at`
|
|
223
|
-
(default 0.9) of its cap until you return. `autopilot approve` (only you, at a terminal) changes
|
|
224
|
-
one setting until a time and puts it back by itself. While a grant is active, `run reload`
|
|
225
|
-
refuses any limit key.
|
|
226
|
-
- **A live log for your return.** In Claude Code the orchestrator keeps one Claude Docs page per
|
|
227
|
-
run with two tabs: Binnacle (status at a glance, decisions, blocks, open questions, actions only
|
|
228
|
-
you can take, incidents, timeline) and Full log (every event, newest first). `autopilot status`
|
|
229
|
-
and `autopilot stop` print its link; without the connector they print two Markdown files in the
|
|
230
|
-
run dir (`autopilot binnacle`, `autopilot log`).
|
|
231
|
-
- **From 0.5.x, not listed before:** two files of one block can no longer both take the block's one
|
|
232
|
-
L3 patch rung (0.5.0), and a maintainer can install a tagged release before it is on npm
|
|
233
|
-
([getting-started](docs/getting-started.md#keeping-it-up-to-date), 0.5.1).
|
|
234
|
-
|
|
235
|
-
## What's new in 0.5
|
|
236
|
-
|
|
237
|
-
- **Parallel review.** The worker reviews `review.parallel_tickets` files at once (default 3), with
|
|
238
|
-
a session limit per provider (`review.provider_concurrency`), backoff on rate limits, and
|
|
239
|
-
`budget.usd` still holding. `code-forge review` now waits on all files under one `--max`
|
|
240
|
-
deadline and prints each result as it finishes. `code-forge doctor` shows the numbers;
|
|
241
|
-
`npm run bench:review` measured 6 reviews in 12 s at 1 and 4 s at 3.
|
|
242
|
-
- **`code-forge facts` verifies again.** It dropped every answer in 0.4.0; now answers match, and a check
|
|
243
|
-
that breaks the read-only rules marks only its own claim as not counted, with the reason.
|
|
244
|
-
- **Clearer budget refusals.** A session refused because other running sessions hold the budget says
|
|
245
|
-
how much they hold and what this session would cost.
|
|
246
|
-
- **Plan approval in plan mode.** The skill shows a checked plan to you in the harness's plan mode
|
|
247
|
-
(Claude Code: EnterPlanMode → ExitPlanMode) before any block starts.
|
|
248
|
-
|
|
249
|
-
## What's new in 0.4
|
|
250
|
-
|
|
251
|
-
- **Cost control.** Set `budget.usd` per run: one warning at 80%, no new session at 100%. Every
|
|
252
|
-
session row carries an estimated `usd`; `report` and `run status` show the spend, and
|
|
253
|
-
`ledger add coder --usd` records spend code-forge did not see.
|
|
254
|
-
- **Cheaper, faster fixes.** One review round that leaves 2 or more warnings climbs the coder one
|
|
255
|
-
level (`escalation.*`). Docs and contract blocks code at L1 or higher and skip multimodel review;
|
|
256
|
-
a file with risk 0–1 gets one reviewer (`review.single_reviewer_max_risk`).
|
|
257
|
-
- **Change the config mid-run.** `code-forge run reload --run <id>` re-reads `.code-forge.yml`
|
|
258
|
-
without stopping open blocks.
|
|
259
|
-
- **Stricter plans.** `plan check` refuses a block whose level is not the lane recorded with
|
|
260
|
-
`jev ask lane --block <id>` (or `--rules` without Jev), and prints the lane of every block.
|
|
261
|
-
`block close --report <file>` fails a coder report that does not name a review ticket per file.
|
|
262
|
-
- **Codex is refused for closed-book roles** (reviewer, judge, System 2, plan author): it always
|
|
263
|
-
has a shell. See [Security model](#security-model).
|
|
264
|
-
- **Steadier reviews.** A timed-out review session is retried once; `review.session_timeout_s`
|
|
265
|
-
defaults to 300; a live worker with a fresh heartbeat is never reported down.
|
|
266
|
-
- **Better error reports.** `logs report --with-doctor` adds a cleaned setup check; errors list the
|
|
267
|
-
last 5 command names; recovered problems are logged as warnings; an error that a newer version
|
|
268
|
-
fixes tells you to upgrade instead of filing it.
|
|
269
|
-
- **Earlier checks.** `validate` refuses an effort the level's provider cannot take (for example
|
|
270
|
-
`xhigh` on an openai level), so nothing fails when the session starts.
|
|
271
|
-
|
|
272
|
-
Fixed in 0.3.1 and 0.3.2: Claude reviewer sessions no longer fail at once on the `--json-schema`
|
|
273
|
-
flag; Grok answers are read from Grok's own answer envelope; Jev `score` questions (such as `risk`)
|
|
274
|
-
no longer fall back to rules; and a clean review of a tiny diff (20 added lines or fewer) needs only
|
|
275
|
-
40 output tokens, so it is no longer refused as `too_short`.
|
|
276
|
-
|
|
277
|
-
## What ships
|
|
278
|
-
|
|
279
|
-
- A CLI (`code-forge`), installed globally with `npm install -g @codedology/code-forge`; `code-forge
|
|
280
|
-
init` then links the skill into every detected harness (Claude Code, Codex, Grok, …).
|
|
281
|
-
- One Agent Skill (`skill/SKILL.md` + `references/`) that is prose only — every fact (model ids,
|
|
282
|
-
efforts, commands, thresholds, paths) lives in config or in the CLI, never in the skill text.
|
|
283
|
-
- A JSON Schema for `.code-forge.yml` (`schema/code-forge.schema.json`), documented in
|
|
284
|
-
`docs/reference/config.md` (generated — see below).
|
|
285
|
-
|
|
286
|
-
See the skill's `skill/references/` for the full architecture, decision layer, review engine, proof
|
|
287
|
-
policy and security model; `docs/reference/blocks.json` lists the build blocks.
|
|
3
|
+
A CLI and Agent Skill for cross-model, parallel, evidence-gated feature delivery.
|
|
4
|
+
|
|
5
|
+
Latest: 0.14.1 - see [CHANGELOG.md](CHANGELOG.md)
|
|
6
|
+
|
|
7
|
+
## The problem
|
|
8
|
+
|
|
9
|
+
An agent can write code quickly, but you still have to decide what to build and how to check it.
|
|
10
|
+
Long tasks lose context, parallel edits collide, and a green test can miss the intended behavior.
|
|
11
|
+
code-forge splits work into owned blocks, gives each change a fresh review, and records proof.
|
|
12
|
+
You approve the plan and keep control of budgets, permissions, and landing the result.
|
|
288
13
|
|
|
289
14
|
## Install
|
|
290
15
|
|
|
16
|
+
Requires Node.js >= 22 and git. Install the CLI with `npm install -g @codedology/code-forge`.
|
|
17
|
+
The scoped npm name is only for installation; the command is `code-forge`.
|
|
18
|
+
The unscoped npm package `code-forge` is an unrelated tool.
|
|
19
|
+
|
|
20
|
+
Inside your repository, run the setup wizard:
|
|
21
|
+
|
|
291
22
|
```bash
|
|
292
|
-
npm install -g @codedology/code-forge
|
|
293
23
|
code-forge init
|
|
294
24
|
```
|
|
295
25
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
engine), every one with a default on Enter. Gates and proof settings come from the project:
|
|
301
|
-
`init` prints what it found, marks what it left blank, and lets you use, customize or leave them
|
|
302
|
-
for later. Non-interactively:
|
|
26
|
+
Press Enter for defaults for tools, harnesses, providers, multimodel review, keys, and engine.
|
|
27
|
+
The wizard detects gates and proof settings, marks blanks, and lets you use, customize, or defer
|
|
28
|
+
them. It writes `.code-forge.yml` and links the skill into detected harnesses. Re-running it
|
|
29
|
+
keeps what it already wrote. For a first try without a System-1 (Jev) key:
|
|
303
30
|
|
|
304
31
|
```bash
|
|
305
32
|
code-forge init --no-interaction --no-jev
|
|
306
33
|
```
|
|
307
34
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
`--jev-env MY_JEV_KEY` once you have one. A second run of `init` changes nothing it already wrote.
|
|
35
|
+
When ready, use `--jev-ref <1Password item ID|link|op://vault/item/field>` or
|
|
36
|
+
`--jev-env MY_JEV_KEY` instead of `--no-jev`. See [setup details](docs/getting-started.md).
|
|
311
37
|
|
|
312
|
-
|
|
313
|
-
skill installs made with `--copy`). See [docs/getting-started.md](docs/getting-started.md#keeping-it-up-to-date).
|
|
38
|
+
### What ships
|
|
314
39
|
|
|
315
|
-
|
|
40
|
+
- The `code-forge` CLI and one prose-only [Agent Skill](skill/SKILL.md), with supporting
|
|
41
|
+
[references](skill/references/). Model IDs, efforts, commands, thresholds, and paths come from
|
|
42
|
+
config or the CLI.
|
|
43
|
+
- A JSON Schema for `.code-forge.yml` and its generated [configuration reference](docs/reference/config.md).
|
|
44
|
+
- An [example repository](examples/) and a [build-block map](docs/reference/blocks.json).
|
|
316
45
|
|
|
317
|
-
|
|
46
|
+
## 5-minute quickstart
|
|
47
|
+
|
|
48
|
+
After setup, check the configuration, selected model, and installed links:
|
|
318
49
|
|
|
319
50
|
```bash
|
|
320
|
-
code-forge validate
|
|
321
|
-
code-forge resolve L1
|
|
322
|
-
code-forge doctor --quick
|
|
323
|
-
code-forge list
|
|
324
|
-
code-forge keys list
|
|
325
|
-
code-forge models
|
|
326
|
-
code-forge --help
|
|
51
|
+
code-forge validate
|
|
52
|
+
code-forge resolve L1
|
|
53
|
+
code-forge doctor --quick
|
|
54
|
+
code-forge list
|
|
55
|
+
code-forge keys list
|
|
56
|
+
code-forge models
|
|
57
|
+
code-forge --help
|
|
327
58
|
code-forge version
|
|
328
59
|
```
|
|
329
60
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
code-forge review # verdict + fix list per changed file; exit 0 only if all approved
|
|
336
|
-
```
|
|
61
|
+
`resolve` prints the provider, model, effort, fallback, and CLI for a level. `doctor --quick`
|
|
62
|
+
checks config, links, and key resolution; `keys list` prints sources and expiry, never values,
|
|
63
|
+
and warns with less than one hour left.
|
|
337
64
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
65
|
+
Write a brief describing the change and how you will know it works. In your agent, invoke
|
|
66
|
+
`/code-forge full path/to/brief.md`: it plans, hardens, asks you to approve the plan, then codes.
|
|
67
|
+
Use `/code-forge plan|harden|code <file>` for one phase at a time.
|
|
68
|
+
Set a per-run `budget.usd` before starting paid sessions: one warning at 80%, no new session at 100%.
|
|
69
|
+
The [first-test tutorial](docs/tutorial-first-test.md) walks through a complete delivery;
|
|
70
|
+
[brief mode](docs/brief-mode.md) covers one small task without a plan.
|
|
343
71
|
|
|
344
|
-
|
|
72
|
+
### Review only
|
|
345
73
|
|
|
346
|
-
|
|
347
|
-
(`bin/code-forge.mjs`), so this list is exactly `code-forge --help`'s output plus each verb's own
|
|
348
|
-
usage line.
|
|
74
|
+
For code you already wrote, run this in the repository:
|
|
349
75
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
| `doctor` | `code-forge doctor [--quick] [--json] [--cwd <dir>]` |
|
|
354
|
-
| `tools` | `code-forge tools [--json]` · `code-forge tools install [<id>…] [--yes] [--dry-run]` — see and install the recommended tools (claude, codex, gemini, grok, op, solo) |
|
|
355
|
-
| `validate` | `code-forge validate [--file <path>]` |
|
|
356
|
-
| `resolve` | `code-forge resolve <L0\|L1\|L2\|L3>` |
|
|
357
|
-
| `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>` |
|
|
358
|
-
| `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`) |
|
|
359
|
-
| `worker` | `code-forge worker --run <id> [--cwd <dir>] [--poll-ms <n>] [--once]` — started detached by `run start`, never by a coder |
|
|
360
|
-
| `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 |
|
|
361
|
-
| `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`) |
|
|
362
|
-
| `spawn` | `code-forge spawn --level L0\|L1\|L2\|L3 --role <role> --brief <file> [--schema <file>] [--cwd <dir>] [--run <id>] [--block <id>] [--timeout <seconds>] [--background]` |
|
|
363
|
-
| `s2` | `code-forge s2 --packet <file.json> [--run <id>] [--block <id>] [--timeout <seconds>]` |
|
|
364
|
-
| `author` | `code-forge author --job plan\|harden --brief <file> [--facts <file>] [--draft <file>] [--answers <file>] [--out <file>] [--run <id>] [--timeout <seconds>]` |
|
|
365
|
-
| `facts` | `code-forge facts --brief <file> [--sources <path>…] [--out <file>] [--run <id>] [--timeout <seconds>]` |
|
|
366
|
-
| `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) · …` |
|
|
367
|
-
| `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) |
|
|
368
|
-
| `gates` | `code-forge gates detect\|run\|secret-scan\|safe-edit\|scope\|acceptance\|transcript-grep --cwd <dir> …` |
|
|
369
|
-
| `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 |
|
|
370
|
-
| `keys` | `code-forge keys list \| set <name> [--op <item-id\|link\|op://ref> [--cache-hours <1-24>]] \| test <name> [--ref <ref>] \| remove <name>` |
|
|
371
|
-
| `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 "..."]` |
|
|
372
|
-
| `report` | `code-forge report --slug <slug> [--json] [--export <dir>]` — 13 sections, then the spend per run (open blocks included) and the total |
|
|
373
|
-
| `models` | `code-forge models [--refresh --from-cli-caches]` |
|
|
374
|
-
| `list` | `code-forge list` |
|
|
375
|
-
| `remove` | `code-forge remove [<harness>] [--scope project\|global]` |
|
|
376
|
-
| `upgrade` | `code-forge upgrade [--source <path>]` |
|
|
377
|
-
| `logs` | `code-forge logs [--last N] [--json]` · `logs summary [--days N] [--json]` · `logs clear [--yes]` · `logs path` — the local error log (`~/.code-forge/logs/errors.jsonl`): errors, warnings, and `[fixed in X.Y.Z]` marks |
|
|
378
|
-
| `logs report` | `code-forge logs report [--last N] [--kind K] [--verb V] [--note "text"] [--include-warnings] [--with-doctor] [--no-ai] [--allow-old] [--force] [--dry-run] [--yes]` — share selected errors as a public GitHub issue; you see the full text first and say yes once. An error a newer version fixes is not filed unless `--force` |
|
|
379
|
-
| `autopilot` | `code-forge autopilot start --run <id> --until <ISO-8601 with offset> --delegate <L2\|L3> --allow <scope,…> [--deny <scope,…>] [--budget <category>=<usd>,…] [--stop-at <0..1>] [--yes]` · `autopilot status --run <id> [--json]` · `autopilot stop --run <id>` (both print the live log's link, or the two Markdown files) · `autopilot ask --run <id> --scope <scope> --question <text> [--options a,b,…] [--context-file <path>] [--block <id>] [--file <path>] [--finding <id>] [--json]` · `autopilot waive\|round\|level … --decision <id>` · `autopilot approve --run <id> --key <dot.path> --value <json> --until <time>` (owner only, at a terminal) · `autopilot binnacle --run <id> [--json\|--markdown] [--link <https url>]` · `autopilot log --run <id> [--json\|--markdown]` — the owner's time-boxed grant to a delegate; see [docs/autopilot.md](docs/autopilot.md) |
|
|
380
|
-
| `help` / `version` | `code-forge --help` (or no verb) · `code-forge --version` |
|
|
381
|
-
|
|
382
|
-
`run`, `block`, `worker`, `spawn`, `s2`, `author`, `facts` and `review-file` are what the Agent
|
|
383
|
-
Skill's loop calls during a real block; you will not usually type them by hand, but they are plain
|
|
384
|
-
CLI verbs like any other and every one of them is exercised by this package's own test suite.
|
|
76
|
+
```bash
|
|
77
|
+
code-forge review
|
|
78
|
+
```
|
|
385
79
|
|
|
386
|
-
|
|
80
|
+
It reviews the branch against the merge base with the default branch, or uncommitted work on
|
|
81
|
+
the default branch, using fresh closed-book sessions. It runs no planner, coder, or proof.
|
|
82
|
+
Narrow with `--files <paths…>`, choose `--base <ref>`, explain with `--intent "<text>"`, or use
|
|
83
|
+
`--json`. Exit 0 means all approved or nothing to review; 1 means a finding, stop, or unavailable
|
|
84
|
+
review; 2 means usage. See [review-only details](docs/review-only.md).
|
|
387
85
|
|
|
388
|
-
|
|
389
|
-
a per-project key, so tampering by a different user or a rewritten history is detectable.
|
|
390
|
-
`doctor` always prints this line — the signature is not a defense against an attacker who
|
|
391
|
-
already runs code as you, and no part of code-forge claims otherwise.
|
|
392
|
-
- **Keys never reach a coder process.** Provider and Jev keys resolve only inside the worker or the
|
|
393
|
-
orchestrator's own CLI calls (`env:<NAME>` → OS keychain → 1Password, cached for
|
|
394
|
-
`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.
|
|
395
|
-
- **A forbidden-command list** stops a coder from starting its own worker, waiving a review, or
|
|
396
|
-
running other orchestrator-only actions — rendered into each provider's own deny-list mechanism
|
|
397
|
-
(`--disallowedTools` for Claude, an execpolicy rules file plus prose for Codex).
|
|
398
|
-
- **Closed-book reviews.** Reviewers, judges, System 2 and the plan author see the packet and
|
|
399
|
-
nothing else: Claude runs them with no tools, Grok with every tool denied. Codex (provider
|
|
400
|
-
`openai`) has no mode without a shell, so code-forge refuses it for those roles: `validate`
|
|
401
|
-
warns, `resolve` marks the level `closed_book: "refused"`, `doctor` fails its isolation row, and
|
|
402
|
-
the session is never started. Codex coders are unchanged. `review.allow_open_book_codex: true`
|
|
403
|
-
accepts the risk and keeps Codex in those roles, with a warning on every surface.
|
|
404
|
-
- **The error log stays on your machine.** A failed verb is logged to
|
|
405
|
-
`~/.code-forge/logs/errors.jsonl` with flag names but never flag values, and with home folder,
|
|
406
|
-
project, emails, `op://` references and 1Password item IDs replaced. `logs report` cleans the
|
|
407
|
-
text twice (built-in rules, then an AI check), stops on anything that looks like a key, shows
|
|
408
|
-
you the full issue and sends nothing without your yes. `CODE_FORGE_NO_ERROR_LOG=1` turns the log,
|
|
409
|
-
the warnings and the command list off. Every field is listed in [docs/privacy.md](docs/privacy.md).
|
|
410
|
-
- **No mutation testing.** Neither this package's own tests nor the product it ships run mutation
|
|
411
|
-
testing (the owner's ruling R14/Q16, 2026-09-25). Coders do not make hand mutations either: each new
|
|
412
|
-
or changed test is proven red→green, and a weak assertion is fixed by a stronger assertion. Proof is plain unit and feature tests with exact
|
|
413
|
-
assertions, plus a red→green runner that proves a new test fails before the fix and passes after (`node:test`
|
|
414
|
-
built in; any other runner through a `proof.runners` entry that writes a JUnit report).
|
|
415
|
-
|
|
416
|
-
## Configuration reference
|
|
417
|
-
|
|
418
|
-
`schema/code-forge.schema.json` is the source of truth for `.code-forge.yml`.
|
|
419
|
-
[docs/reference/config.md](docs/reference/config.md) lists every key with its type and default.
|
|
420
|
-
Keys added in 0.4, 0.5 and 0.6 (`review.parallel_tickets` and `review.provider_concurrency` are
|
|
421
|
-
new in 0.5, `autopilot.min_confidence` in 0.6):
|
|
422
|
-
|
|
423
|
-
| Key | Default | What it does |
|
|
424
|
-
|---|---|---|
|
|
425
|
-
| `budget.usd` | none | per-run spend stop in USD: one warning at 80%, no new session at 100% |
|
|
426
|
-
| `escalation.after_rounds_with_warnings` | `1` | rounds with many warnings at one level before the coder climbs (`0` turns it off) |
|
|
427
|
-
| `escalation.warning_threshold` | `2` | how many open warnings make a round "heavy" (any critical counts too) |
|
|
428
|
-
| `levels.coder_floor_docs` | `L1` | the lowest level that codes a docs or contract block |
|
|
429
|
-
| `review.single_reviewer_max_risk` | `1` | at or below this risk a file gets one reviewer and no judge |
|
|
430
|
-
| `review.multimodel_for_docs` | `false` | let docs and contract blocks use multimodel review too |
|
|
431
|
-
| `review.allow_open_book_codex` | `false` | let Codex run reviewer, judge, System 2 and plan author anyway |
|
|
432
|
-
| `review.session_timeout_s` | `300` | a review session that runs longer is killed and retried once |
|
|
433
|
-
| `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 |
|
|
434
|
-
| `review.parallel_tickets` | `3` | review tickets the worker runs at once (1 to 16); `1` reviews one file at a time |
|
|
435
|
-
| `review.provider_concurrency` | anthropic `4`, openai `2`, xai `2` | review sessions at once per provider |
|
|
436
|
-
| `autopilot.min_confidence` | `0.7` | the lowest delegate confidence that is acted on; below it the question goes to you |
|
|
437
|
-
|
|
438
|
-
`code-forge block open … --kind code|docs|contract` sets a block's kind when its file endings do
|
|
439
|
-
not say it. The reference page is generated:
|
|
86
|
+
## How it works
|
|
440
87
|
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
|
|
88
|
+
```text
|
|
89
|
+
plan -> code -> review -> proof -> land
|
|
90
|
+
^ | |
|
|
91
|
+
| +<--fix-+
|
|
92
|
+
+-- human approval after hardening
|
|
444
93
|
```
|
|
445
94
|
|
|
446
|
-
|
|
95
|
+
The skill checks and hardens the plan before your approval. Coders work in blocks with explicit
|
|
96
|
+
owned files and acceptance clauses; independent blocks can run in parallel. A worker runs fresh
|
|
97
|
+
reviewer sessions outside the coder's sandbox. Fix rounds are bounded; unresolved work stops.
|
|
98
|
+
Tests and red→green proof establish that a change meets its acceptance clauses before closing.
|
|
99
|
+
You control the final merge and publish permissions; coders cannot push or open draft PRs by
|
|
100
|
+
default. See [the workflow](docs/how-it-works.md) and [concepts](docs/concepts.md).
|
|
447
101
|
|
|
448
|
-
|
|
449
|
-
npm install
|
|
450
|
-
npm test # node --import ./test/helpers/isolate.mjs --test 'test/**/*.test.mjs'
|
|
451
|
-
npm run typecheck # tsc --checkJs --noEmit
|
|
452
|
-
```
|
|
102
|
+
## Key commands
|
|
453
103
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
104
|
+
| Command | Use it to |
|
|
105
|
+
|---|---|
|
|
106
|
+
| `code-forge init` | Configure the project and install the skill |
|
|
107
|
+
| `code-forge doctor --quick` | Check config, links, and keys |
|
|
108
|
+
| `code-forge review` | Review existing changes without a coding run |
|
|
109
|
+
| `code-forge run start\|status\|reload\|end` | Manage a run and inspect its spend |
|
|
110
|
+
| `code-forge block open\|close\|stop` | Track owned work and enforce its acceptance gates |
|
|
111
|
+
| `code-forge review-file` | Enqueue a file review or wait for its ticket |
|
|
112
|
+
| `code-forge proof tier\|red-green` | Choose proof strength and prove a test fails before the fix |
|
|
113
|
+
| `code-forge gates detect\|run` | Discover and run project checks |
|
|
114
|
+
| `code-forge keys list\|set\|test\|remove` | Manage key references without printing secrets |
|
|
115
|
+
| `code-forge report` | Inspect recorded outcomes and costs |
|
|
116
|
+
| `code-forge logs` | Inspect local errors; `logs report` previews a public issue |
|
|
117
|
+
| `code-forge upgrade` | Refresh installed skill copies after upgrading the package |
|
|
118
|
+
| `code-forge --help` | List every verb; each verb prints its own usage on bad arguments |
|
|
119
|
+
|
|
120
|
+
The skill normally calls `run`, `block`, `worker`, `spawn`, `s2`, `author`, `facts`, and
|
|
121
|
+
`review-file` for you. See the [workflow](docs/how-it-works.md) for these lower-level operations.
|
|
122
|
+
To upgrade, run `npm install -g @codedology/code-forge@latest`, then `code-forge upgrade` for a version summary and release notes; add `--plain` for just the install lines.
|
|
123
|
+
|
|
124
|
+
### Configuration reference
|
|
125
|
+
|
|
126
|
+
[schema/code-forge.schema.json](schema/code-forge.schema.json) is the source of truth.
|
|
127
|
+
The reference lists every key, type, and default, including budget, escalation, coder floors,
|
|
128
|
+
review risk, multimodel, concurrency, and timeout settings.
|
|
129
|
+
`review.routes` sends big files to another model with its own timeout and second level.
|
|
130
|
+
`block open --kind code|docs|contract` overrides the kind inferred from filenames.
|
|
131
|
+
Regenerate the reference with `node scripts/gen-config-doc.mjs`; add `--check` to check it.
|
|
132
|
+
|
|
133
|
+
## Supported agents
|
|
134
|
+
|
|
135
|
+
Use Claude Code, Codex, or Grok as agent harnesses, or Solo as the execution engine.
|
|
136
|
+
Gemini, Cursor, and Copilot have detection and skill linking only.
|
|
137
|
+
See [agent support and limits](docs/overview.md) for adapters and degraded modes.
|
|
138
|
+
Closed-book role restrictions are described below.
|
|
139
|
+
|
|
140
|
+
## Security model
|
|
457
141
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
142
|
+
Review and gate rows are HMAC-signed: `signer: same-user boundary only`. A process running as
|
|
143
|
+
you can read the signing key; this does not defend against that process. `doctor` states the limit.
|
|
144
|
+
Provider and Jev keys resolve only in the worker or orchestrator: environment → OS keychain →
|
|
145
|
+
1Password (cached for 8 hours by default, at most 24) → setup prompt. Keys never reach coders;
|
|
146
|
+
key commands print no values and output is redacted. Provider deny lists restrict coder actions.
|
|
147
|
+
|
|
148
|
+
Reviewers, judges, System 2, and the plan author see only their packet: Claude has no tools and
|
|
149
|
+
Grok has every tool denied. Codex always has a shell, so those roles are refused by default;
|
|
150
|
+
`review.allow_open_book_codex: true` opts into the risk with warnings.
|
|
151
|
+
Errors stay in a local, cleaned log. `logs report` cleans twice, checks for keys, previews the
|
|
152
|
+
issue, and sends only with your yes; `CODE_FORGE_NO_ERROR_LOG=1` disables logging.
|
|
153
|
+
Proof uses unit/feature tests and red→green, with no mutation testing or hand mutations.
|
|
154
|
+
See [security details](skill/references/security.md) and [privacy](docs/privacy.md).
|
|
155
|
+
|
|
156
|
+
## Links
|
|
157
|
+
|
|
158
|
+
- [Documentation](docs/): setup, concepts, tutorials, and reference pages.
|
|
159
|
+
- [CHANGELOG.md](CHANGELOG.md): all per-version release history.
|
|
160
|
+
- Roadmap: [public feature ideas](https://claude.ai/artifact/BmeWyqRxZYsWr7eH5vBtdF)
|
|
161
|
+
|
|
162
|
+
### Development
|
|
163
|
+
|
|
164
|
+
The package ships plain ESM `.mjs` files with no build step. In a checkout, run `npm install`,
|
|
165
|
+
`npm test`, and `npm run typecheck`. Check the generated config reference before releasing.
|
|
166
|
+
Record changes with `npm run changelog -- <type> "<text>"`; record fixed error reports with
|
|
167
|
+
`npm run known-fix -- add <fp> <version> "<summary>"`. `npm run release -- <bump> [--dry-run]`
|
|
168
|
+
bumps versions, releases the CHANGELOG, updates the optional Latest line, checks, commits, and
|
|
169
|
+
tags. Publish with `npm publish`, then push the tag; CI creates the GitHub release.
|
|
170
|
+
See [releasing](docs/releasing.md).
|