Repository navigation
Releases
v0.23.0
Changed
npm run releasenow accepts a package up to 35 MB (was 20 MB): the Go port made the four native binaries about 15 MB each, so the 0.23.0 package is 28.3 MB; the refusal readspublished package must be under 35 MB(B605)block closeruns in Go for late and cap rows whose file, finding or open id is an object or array (Node's[object Object]and joined text, or Node'sarg.replaceAll is not a functionerror for a file it cannot quote) and for plain-text or Codex transcripts with JavaScript-only whitespace (NBSP, U+2028, BOM); before, these closes handed over to Node (close-gates-format, close-transcript-format). A routine close under aclose:routinegrant now prints Node'sopened beforewarning once per gate load and joins every routine failure into theclose-not-routinereason, byte-equal to Node (B590)block closeruns in Go when a changed file matchesreview.excludeor the default lock-file list: the file leaves the review set, gets agate.review_excludedrow and anot reviewedline, and an npm lock gets Node's lock check andlockfileblocker; before, every such close handed over to Node (close-excluded-file). A lock shape Go cannot judge like Node hands over with the new reason close-lockfile-format (B587)block closeruns in Go for a transcript that is not valid UTF-8 (decoded as Node does, each bad byte run one U+FFFD), a Claude Code log with an escaped surrogate pair, and agent waiver and reopen rows whose fields hold objects or arrays (--jsonprints them in the ledger line's key order); before, these closes handed over to Node (close-transcript-format, close-gates-format) (B583)- Go reads the Node version when it runs (
node --versiononce per process,CODE_FORGE_NODEelsenodeonPATH), not the build machine's: error-log rows, the gate reuse stamp and thelogs reportNode line match the node that runs;logs reportno longer hands over when no Node version is known and printsunknown(B585) factswith a Codex (openai) step in thelevels.L0ladder (first, as a fallback, or from a top-levelprovider: openai) now runs in Go byte-equal to Node instead of handing over: the read-onlycodex execcall in the snapshot, the packet on stdin, the OpenAI-strict schema file, the-oanswer, the fallback moves on usage limit, 401, 503, timeout and exit, the answer checks, the sheet and the ledger rows;review.allow_open_book_codexdoes not change it, as in Node (B582)- A fix-loop recheck with a block base runs in Go byte-equal to Node's packet builder for every peer case: one peer, several peers (named and imported kept, the rest dropped), a moved-code hint alone, a moved hint plus cross-file evidence, over the budget (the cut line, or no evidence), no peers and no base;
worker --run <id>serves such a recheck of a .js file end to end with no hand-over row (B564) block readyno longer hands over to Node when the workspace path holds secret-like text such aseyJ,AKIA,AIzaorsk-(a random temp folder name did this once on CI); like Node, it masks only the run's signer key, and output that would show that key still runs in Node (B565)- Go no longer needs a
nodeon PATH forcontext packandcloud-coder: with no Node, the pack's## code-forgeline names the install'sbin/code-forgelauncher instead of refusing (with Node found, the pack bytes are unchanged), andcloud-coderrunsreview-fileandledger add coderin this Go binary instead of the Node router (B572) - The Go binary is required:
bin/code-forgeno longer falls back to Node. With no binary for the platform and arch, a missing file or one without execute permission (and forsetup, a binary that crashes), it prints one stderr message with<platform>-<arch>, the expected path and the fix (sh <package>/scripts/install.sh, thennpm i -g @codedology/code-forgeif that fails) and exits 69, a code no verb uses;CODE_FORGE_NATIVE=0still runs the Node router. Newscripts/install.sh(POSIX sh, shipped) checks the binary for this OS and processor, restores a lost execute bit, runs--versionandinternal version, compares the version withpackage.jsonand prints OK or the problem and onefix:line (exit 0 / 1); no network, no sudo, nopostinstall(B569) npm run releaseruns no Node on the laptop: it builds the four native release targets withgo buildfrom Go (same targets, flags, temp name, mode and printed lines asscripts/build-native.mjs; the Node version stamp comes fromnode --versionwhen a node is usable and staysunknownotherwise), and in place of the localgen-config-doc --check,gen-commands-doc --check,npm testandnpm run typecheckit requires the latestCIrun for HEAD to be completed with success, refusing before any write with one line naming HEAD and the run state;npm pack --dry-run,npm ls --jsonandclaude plugin validate .still run; the--no-checkswarning names the new list and the notes usage line namessh scripts/cf-release.sh release notes(B580)- The Node release scripts are gone:
scripts/release.mjs,release-site.mjs,docs-block.mjsandchangelog.mjsand their Node tests are deleted, after every case those tests checked was ported to the Go tool's goldens (74 new multi-step cases recorded from Node); the GitHub release workflow sets up Go and writes the notes withsh scripts/cf-release.sh release notes(same bytes), andscripts/gen-site-data.mjsreads CHANGELOG sections itself with the same output; nothing changes in the npm package (B574) - The maintainer release tools run in Go:
npm run release,npm run release:site,npm run docs-blockandnpm run changelogbuild and runnative/cmd/cf-releasethroughscripts/cf-release.sh, with the same arguments, output, exit codes, file edits and git commands as the Node scripts, checked against goldens recorded from Node; the Node scripts stay because tests, the site data generator and the release workflow still use them, and nothing new ships in the npm package (B570) - The native daemon's
statusno longer starts a Node helper: a block id outside printable ASCII is answered in Go when it is the one listed block or sits on a closed or stopped block (also forstatusandnative-status); with two or more such listed blocks the daemon answersstatus-unreadable, as it did with no Node, and the status command computes the status itself (B576) - The native rebuild in
gates runandblock rebaserunsgo buildin Go instead ofnode scripts/build-native.mjs --host: same env, ldflags,<binary>.<pid>.tmptemp name, mode 755, rename andnative-rebuild-failedtext; it works with no Node on PATH, and then leaves the binary's Node version atunknown(B575) factschecks more glob path claims in Go, like Node'spath.matchesGlob: braces ({a,b},{1..3}), backslashes,[:ascii:]and[:xdigit:], extglob openers with no)and non-ASCII text with Node's case folding. A Unicode POSIX class, an extglob that can close, a case-insensitive suffix with a sigma, a Codex L0 step (B551 is not on this base) and the gate's non-ISO dates (Node reads them in the local time zone) still hand over before any write (B577)block rebasethat hands a narrow state to Node no longer prints an autopilot expiry warning twice: a failed grant expiry or an approval not restored yet is reported once, by Node's own check; a key or file read error in such a warning names no path, as Node's (B584)block rebaseno longer starts a Node child: active and due autopilot approvals, run records with no orphans list, an odd sibling block or an unreadable config snapshot, falsy or invalidrebase_checkvalues and a missingHOMErun in Go with Node's output, run record and ledger rows; the few states Go cannot read hand over with a narrow namedrebase-*reason before any write (B578)- The Go worker, the daemon (
internal serve) and every Go verb (review,block close,block land, gates, status, proof export and the rest) record each child they start in the run root's pid registry like Node's exec:pids/<pid>.jsonwhile it runs, the owner pid, start time and run id in its environment, the lazy root released at exit; stdout and exit codes do not change (B573) block openserves its former Node fallbacks in Go, byte-equal to Node: an emptyproof.worktree.dirorbase,--afterstatuses that are not text, claim rows whose path is not text, the signer key and ledger checks with no--level, brief loop, name-too-long and read errors, acceptance and pipeline YAML errors, pipeline and outcome read errors, noHOMEand block ids such as__proto__; YAML forms Go does not reproduce, AJV schema wording, a torn ledger line, a failed home lookup and an unresolvable brief path hand over before any write under the new reasonsopen-acceptance-yaml,open-pipeline-form,open-outcome-form,open-level-ledger,open-home-lookupandopen-brief-cwd; Go's ELOOP and ENAMETOOLONG texts are libuv's, as Node prints them (B581)- CI on Linux is green again: the tools and init rows follow a platform seam, so the init wizard test replays its Mac golden (Homebrew hints, Solo.app) on Linux too; the
block closefake reviewer writes its result file then renames it, like the worker, so close never reads a half-written result; the Jev triage test waits for its fake server before it reads the requests (the race detector caught the bare read); the 25 ms Go hand-over check reports its number on CI runners instead of failing, because the same binary measured 10 to 63 ms there, and local runs keep the gate (B560). - A Go worker that hands its run to Node keeps the queue served while Node starts: it leaves a hand-over announcement that
review-file --waitreads as live and Node's boot prunes, so a waiting review no longer endsworker_downduring the hand-over (B561) - Go
doctorrecords each child it starts (CLI probes, pings and probe ses...
v0.22.1
Added
run status,run endandrun start --reattach(with or without--worker-pid) run in Go with the same output, exit codes, run record, mirror and signed ledger rows as Node, as dorunhelp, usage errors and unknown flags; a plainrun start,run start --add-workerandrun reloadstill hand over to Node with their own reason (B454)gates runruns in Go for every form Node completes: a run with no--runand no--block, custom, kind and formatter gates (pint and prettier in argv batches),repeat_new_testswith changed sources, JSNumberforms of--timeout-ms(0x,0o,0b, exponent), unknown flags, noHOME(the user's home folder), a--timeout-msover the timer limit (1 ms timer and Node's warning), an empty--runor--blockand a missing--cwd, all as Node; a bad gate config stops with one stderr line that names the cause and the fix; only a run record with a mismatchedrun_idor noworkspacestill hands over; a command that cannot start is a redspawn-errorgate; theblock landgates step and the batch land preflight run the same Go path (B450)block open,block claim,block stop,block closeandblock landno longer hand over to Node: help, unknown flags, errors and the error log run in Go,block closechecks light limits in Go, and every other case Go does not serve exits 1 with oneblock <sub>: refused: <cause> (<code>); <fix>line and writes nothing; only the land gates step still hands over (B450) (B451)block open,block claim,block stop,block closeandblock landserve help, unknown flags, errors and the error log in Go;block closechecks light limits in Go, reads only the closing block's rows (another block's rows no longer hand the close to Node) and prints Node's detail for arule_breakrow whose id is not text; no case is refused, and the cases Go does not serve yet still hand over to Node (B466 ports them) (B451)npm run release:site— afternpm publish, waits until npm serves the version, builds the site data in an
isolated worktree of the site repo, runs every site gate, commits onlysrc/data/site-data.jsonon
release-site/v<version>and deploys; a red gate deploys nothing;--dry-runstops before commit and deploy (B315)
Fixed
gates runhands a gate command that is an executable file with no#!line to Node again (Node runs it with/bin/shon Linux and refuses it on macOS; Go had shown a redspawn-errorgate);context packnamesnodeonPATHin the pack header whenCODE_FORGE_NODEdoes not resolve, as before B452, instead of refusing; the Go test forgates runwith noHOMEno longer writes~/.code-forge/queuein the real home; the Node parity tests now check the B449–B452 Go forms against Node instead of expecting a hand-over (B469)- status, review-file, context: fewer Node hand-overs — Go runs every
contextform,statusfor array run records, an infinite spend and broken run files, and thereview-fileenqueue worktree andrun-record-unreadablerefusals; Node stays only for a non-ASCII block id instatusand a few review-file states Go cannot read (B452) block rebaseruns in Go in every form (--help, closed and awaiting blocks,--head,--accept-changed,--accept-landed), andblock readyruns in Go withhooks.on_block_endand withclose.require_humanunder an active autopilot grant; only run state Go does not expect still hands over to Node (B449)- The config and command references now describe the merge gate as it runs:
gates.merge_gateruns the Go test selection for the merge, never the full suite, reuses a green gate on the same tree (gate_reused) and is always on in a batch;block landusage lists--push,--watch-ci,--copy-linksand batch land, andgates runusage lists--full,--preflightand--no-preflight(B444) npm run release:sitedeploys the merged site folderdocs-site/site/.pages-out(marketing pages plus/docs)
instead ofdist, which has no/docs;--deploy-dir <path>picks another folder inside the site root, and a
missing folder orindex.htmlafter the gates stops before commit and deploy (B446)block landoutput no longer says the merge gate runs the full suite:--no-merge-gatewarnsmerge gate skipped; the merged tree was not checked, a batch refuses it witha batch always runs the merge gate; --no-merge-gate is refused, a red gate stops withtests failed:and a missing test command withtest gate unavailable: configure gates.test before merging;helplists everyblock landflag and batch land (B447)code-forge ci watchsurvives the GitHub API rate limit: a rate-limit reply is never a CI result; it waits until the reset fromgh api rate_limit(else backs off 60 s doubling to 15 min), printsci watch: GitHub API rate limit; retry at HH:MM UTCper wait, and past--timeoutexits 4 withrate limit, gave upinstead of a failure; polling stays at one call per 30 s, and a second watch for the same repo and commit exits 0 without starting (B448)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.22.1
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.22.1/CHANGELOG.md
v0.22.0
Added
gates.merge_gate_links— repository-relative git-ignored paths (for examplelocal.properties,
app/google-services.json) are linked from the main checkout into the temporary merge-gate tree before setup; each
link must stay under the repository root. A retried land merges only the closed block head (B343b)block open --allow-api-mismatch— block open (Go) checks the brief's uses/extends lines against the code
(api-fit). A missing name or parameter exits 2 with anapi-fit:line;--allow-api-mismatchopens anyway and prints
each line as a note (B338)code-forge cloud-coder --run <r> --block <id>(Go) — runs a cloud coder from configcoder.cloud(submit, then
fetch until a patch or timeout), applies the patch to the block's owned files only and queues review; a patch fetched
at the deadline still lands (B342)code-forge reporthas a pace section: per-block and run pace in minutes; text,--jsonand--exportcarry the
same 18 sections (B341, B358)- heal queue: gates run, block rebase and block land queue a failure that passes by itself (a held lock, a transient git
error) in ~/.code-forge/heal/.jsonl and print heal: queued ; code-forge heal list|show|run retries each item
with backoff (15 s, 60 s, 240 s), removes a lock whose owner pid is dead, and marks needs_coder after --max-tries
(B429) - Main first:
block land --push(orland.push: true) pushes main after the merge; a rejected push queues a heal item
of kind land (argvblock land <ids> --run <r> --merge --push; already landed blocks only push) and exits 1;--watch-cistarts a detachedcode-forge ci watch, a new Go verb that follows the
commit's GitHub Actions runs and queues a heal item of kind ci naming the failing jobs, tests and block ids (B430) - Under an active autopilot grant an agent may run block close --decide without a terminal for transcript rule_break
hits and warning/nit findings; criticals stay with the owner; each decision is a signed close.decision row shown by
the new code-forge decisions list (B390)
Changed
- the skill's
block landtext no longer says the merge gate runs the full suite: it uses the Go test selection
(B404); newskill/references/code.md§5.1 tells the orchestrator how to use the changed-test selection, preflight,
close review wait, Go rebase replay, batch land,--push/--watch-ci, the heal queue and the machine test queue,
with pointer lines in SKILL.md (B443) - native
block closequeues a review for each changed owned file that has no review (also after an acceptance
amendment), waits once for all of them (review.close_wait_s, default 600), then stops withnot_approvedor
review_pending; close never approves a file itself (B339) - A Go verb that holds the run lock writes an owner file (pid, start token, verb) in
<run>.lockand removes it on release; a waiting Go verb breaks a lock whose owner process is gone or replaced (or, with no owner file, that is older than 10 minutes) once, logsbroke stale run lock (pid N)and takes it, so a crashed holder no longer blocks every verb until a human removes the dir; a lock with a live owner is never broken (B423) block land(Go) no longer stops with "land stopped at join: reviews did not finish" when a loaded machine misses the run daemon's fixed 2 s connect/ping deadline: the review join asks the daemon again until land's own--maxdeadline (thenwait_timeout); a dead daemon (connect refused, connection closed, invalid answer) still stops the join at once with the same message (B417)block closeandblock ready(Go) check thecode-forge-runs-accesstranscript rule themselves instead of handing any transcript with.code-forgetext to Node: plain-text logs and Claude Code JSONL logs get the same hits as Node after B415 (a Read/Bash/Glob/write-tool path or command word naming the run records, absolute or home-relative, hits; a heredoc body or quotedechotext a command only writes to a file does not;.code-forge.ymldoes not). Go also decides the git/gh/rm and code-forge launcher rules,sh -cwrappers, interpreter scripts and non-ASCII text, so acoder-forgepath orforge/r-…branch name no longer hands over; only Codex logs,.code-forge/reviewsand.code-forge/queuetext, invalid UTF-8, lone surrogates and JavaScript-only line separators still hand over (B416)- Go gate children start at nice 10 (or the engine's higher nice) before their own code runs: the engine starts each gate through a short copy of itself that sets its own nice and then execs the gate program with the same argv, environment and spawn errors. Before, the engine lowered the child after start, and on macOS that change could be lost while the child was still starting, leaving a gate (and the nice test) at nice 0 (B420)
gates run --changedand theblock land --mergeand batch-land merge gates (Go) run only real test files (*.test.*,*.spec.*,*_test.go,*Test.php,test_*.py,*_test.py,*Tests.swift): a changed helper, fixture or script undertest/is no longer run as a test or picked as a stem-paired test, and selects the tests that import it or name it by path instead. The owned-file test fallback, the no-JS changed scope andrepeat_new_testsskip such files the same way (B394)gates run --changedand the land gates select the CLI tests for a change to any verb module: Go's import graph countsbin/code-forge.mjsas importing everysrc/cli/*.mjsits router loads by readdir, andbin/code-forgeas importing the entry (a change tosrc/cli/version.mjsselected 0 tests before) (B373c)gates run(Go, every mode:--changed, full,block landand batch merge gates) runslint,typesandformatbefore the test gate. When one of them is red the test command never starts: its entry stays in the result (same order) withskipped: true,ok: false,reason: pre_gate_failedandpre_gates_failednaming the red gates,gate.donerecords the same reason, and the exit code stays 1, so two type errors no longer cost a 12-minute suite first (B418)block land <id> --mergeskips the merge-gate run when the merged tree equals the clean tree the block's last green gate ran on and that gate covered the merge selection:merge gate: reused green gate on tree <id> (gate_reused),merge_gate_reason: gate_reusedinland.timingand the--jsonlandedevent; a block on an older base still runs it.gate.donerows from a block worktree record thetreethey ran on (B393)- Batch
block land <id> <id>...(Go) runsgit merge-tree --write-treefor every block against the running result before any rebase, gate or suite. A block that would conflict is parked with reasonblock_rebase_conflictand its conflicting files (--jsonevent: parked,land.batchparked); the other blocks still gate and land. When every block conflicts, nothing lands and land exits 1 naming each block (B397) - Go tests that build a fixture repo (
gates run,gatesgo-only scope,review-file --wait/--wait-block,review wait-block,statusdirect) run fixture git in the fixture repo without inheritedGIT_*variables and start their code-forge children without them, so aGIT_DIR,GIT_INDEX_FILEorGIT_WORK_TREEfrom a hook or worktree no longer breaks them; a guard test reruns them with those variables set (B410) - Go tests in
native/gates,native/blockops,native/blockopenandnative/gatecheckrun fixture git with the fixture repo as the directory andgitx.ChildEnv()(no inheritedGIT_*), with a guard test that reruns them underGIT_DIR/GIT_INDEX_FILE/GIT_WORK_TREEpointing nowhere;cloud-codertakes its deadline from a replaceablecloudDeadline, so the fetch-timeout test expires after two polls instead of 2 s of wall time and no longer fails on a loaded machine (B411) gates run --run R --block B --changed(Go) selects its tests in Go and never runs or hands over to the full Node suite: the block's tests, owned and changed tests and the stem-paired tests of changed sources (any language), every test that imports a changed file (static and dynamic imports,require,new URL, path mentions anywhere in the closure, imports of deleted files), for a native changetest/compat/go.test.mjs, the compat tests named after the Go files and every test that builds or runs the native binary (B330), and the config golden test for a fixture, schema orsrc/config/change (B409). A changed test the runner cannot take is dropped, never widened; an empty selection skips the test gate. The reason isgo_onlyorimport_graph. Theblock land --mergemerge gate and the batch-land merge gate use the same selection (merge gate: scoped tests passed (...)for--merge) instead of the full suite; a test command without{test_files}gets the selection appended and never runs unscoped;go.test.mjsruns only for a native change.gates run --run R --block B --fullis the only local full suite (scope: full,reason: explicit) (B404)- In a code-forge worktree,
block rebaserebuilds the worktree's native binary (node scripts/build-native.mjs --host) when the rebase brings a change tonative/**orscripts/build-native.mjs, andgates run --run --blockrebuilds it before any gate when it is missing or older thannative/go.modor a non-testnative/**/*.gofile (the gate JSON showsnative_rebuilt: true). A failed build exits 1 namingnative-rebuild-failed; the gate then runs nothing. Compat tests no longer run a binary built on the old base (B408) - The close transcript check no longer counts a
~/.code-forge/runspath that a coder only writes as text: the body of acat > file <<'EOF'ortee fileheredoc (not piped on, no shell substitution) and quotedecho/printfarguments written intoplans/give nocode-forge-runs-accesshit. Real access still does:cat/ls/cd/<on the path, a...
v0.21.0
Added
npm run docs-blockwrites the docs brief for a release and stampsdocs/release-docs.jsonwhen the docs block ends.npm run releaserefuses when the docs stamp is not current (B312)node scripts/gen-site-data.mjs --tag vX.Y.Zexports release notes and commands from the tag for a local website update. It exports only run, completed-block and spend totals from the local ledger. The same tag and ledger inputs give the same JSON (B313)
Changed
block landdoes not run the full test suite again in the merge gate when the merged tree is the same as a tree that already had a green full run. It prints the reused tree id and records it on the land.timing row (B317)
Fixed
- A review that asked for a file the policy refuses now goes on to round 2 with the refusal line, instead of stopping as unavailable. The worker's review ledger row keeps only the needs_file diagnostics, never finding text (B311, #33)
parity-gates-customno longer fails at random under load: the test writes its fixture files completely before the Go engine reads them (B309)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.21.0
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.21.0/CHANGELOG.md
v0.20.0
Added
- The Go engine records each hand-over to Node in
~/.code-forge/native/handovers.jsonl: the command, the known subcommand and a reason code. Unknown words are stored asunknown, never as typed. SetCODE_FORGE_HANDOVER_LOG=0to turn it off (B282)
Changed
- More commands run fully in Go, with the same output and exit codes as Node.
docs/native-engine.mdlists the few cases that still hand over. These cases no longer hand over to Node:block closewith--auto-claim,--remove-worktreeand--no-require-reviews(B283), and with external review (B284)hooks.on_block_endon block claim, stop and close (B284)- active autopilot grants on block claim, stop, open and close (B285)
block openwith--after,--after-outcomeand no--level(B286)block ready,block waiveandblock reopen(B287)review-filewith--fresh,--answers,--of,--rebase-checkand a cached result that needs a fresh ticket (B288)gates runwith custom gates,repeat_new_tests, light blocks and flaky detection (B289)context pack(B290)block landwith plain,--merge,--no-merge-gate, grant and hook shapes (B291, B307)block close --decide,block human closeandblock human-pass(B292)
Fixed
npm run bench:blockcounts every command it starts, so the process count no longer drops below the number of runs when fast Go commands end between two samples. This made CI fail on Linux (B297)- A review recheck and the agent waiver judge now see the block's other changed files that a finding names or calls. The context is bounded and recorded. Before, a fix in another file of the block was not seen (B280, B306)
gates run --changedkeeps its scope after a rebase when the base move is safe, so one block no longer runs the full suite twice. It resets the scope when the base move is not safe and records the real fallback reason. A change in Go code now selects the affected parity tests (B294, B305)gates run --changedno longer passes Go_test.gofiles to the Node test runner. Before, every Go-only block failed to land (B301)- A reviewer that times out twice on the same file now falls back once to another configured model, chosen by measured speed and accuracy.
run reloadnow applies review-only keys when frozen keys differ, keeps the frozen keys and prints their names (B296) block rebase --accept-landedno longer deadlocks on the run lock, shows the Go error, leaves no lock after a refusal and no longer replays the commits of an earlier block (B299)- A stopping worker no longer creates a removed
HOMEagain (B303) - The merge gate of
block landnow runs in the right folder when the workspace path goes through a symlink, in Node and in Go (B307) - Tests no longer fail on a busy machine because of wall-clock limits (B300, B302)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.20.0
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.20.0/CHANGELOG.md
v0.19.1
Fixed
code-forge initasks for a level again when the answer is unreadable, is empty, or repeats the provider, model and effort of an earlier level, the L3 judge included. Before, init went to the end and stopped with "the resulting config is invalid, nothing written" (#31, B281)- The forbidden-command scan reads Codex coder logs again when they start with the plain "Reading additional input from stdin..." banner. The coder's stderr now goes to
session.err.log. Before, the banner switched the scan to plain text: brief text in command output gave false hits, and a realgit stashinside an escaped shell command was missed (#32, B293)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.19.1
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.19.1/CHANGELOG.md
v0.19.0
Added
- Go write kit: file locks, signed ledger rows and atomic state writes with the same bytes and lock rules as Node. No public verb (B272)
- Go runs every
statusform (status,--json,--run <id>) directly from disk, with no daemon and no lock; unreadable or unknown state hands over to Node (B273) - Go runs
review-file <file> --block <id>(plain enqueue);--fresh,--answers,--of,--rebase-checkand fresh-ticket cases hand over to Node (B274) - Go runs
block claimandblock stop; autopilot grants, pending approvals andhooks.on_block_endhand over to Node (B275) - Go runs
block openwith an explicit--level, including worktree creation; no--level,--after/--after-outcomeand autopilot cases hand over to Node (B276) - Go runs the plain agent
block close;--decide,--no-require-reviews,--auto-claim,--remove-worktree,ready, human-close, external reviewer, hooks and autopilot cases hand over to Node (B277) - Go runs
gates runfor built-in gates, with the same rows on cancel (SIGINT/SIGTERM); custom gates,repeat_new_tests, light blocks, flaky detection and othergatessubcommands hand over to Node (B278) - Go runs
block land(join, gates, close, merge) when every step can run in Go; it checks this before any write, so one land never mixes Go and Node steps (B279)
Fixed
block claimin Go resolves symbolic links in the workspace path before it checks overlap (B279)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.19.0
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.19.0/CHANGELOG.md
v0.18.0
Added
- Go runs
logs path,logs [--last] [--json]andlogs summary;logs clearandlogs reporthand over to Node (B247) - Go runs
ledger tail; otherledgercommands hand over to Node (B248) - Go runs
review-file --wait <ticket>(B266), andreview-file --wait-blockthrough the daemon; stopped files and unusual answers hand over to Node, which writes all signed rows (B267) - Go runs
status --json --run <id>through the daemon clientnative/daemonclient, with Node fallback (B268) npm run bench:verbscompares Node and Go per verb (time, memory, output parity, leftover processes);bench:blockadds the Go-firstentrylane (B265)
Changed
- Land gates run only the tests the block changed or affects; the full suite runs once per wave (B269)
block closefinds the final approved review tickets in the ledger, so a report needs no hand ticket lines (B270)
Fixed
- The CI timing check "Go handover budget rejects a 40 ms delay" no longer fails on a busy machine (B271)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.18.0
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.18.0/CHANGELOG.md
v0.17.0
Added
- Go config loader (
native/config, yaml.v3 pinned and vendored): reads.code-forge.ymlwith the same defaults, schema checks and error lines as the Node loader, checked byte for byte against goldens made by Node (B243) - Per-verb parity harness: runs each ported verb in Node and in Go on isolated copies of the same state, and compares output and state files field by field (B244)
code-forge <verb> --helpfor every verb, and a generated command referencedocs/reference/commands.md(checked byscripts/gen-commands-doc.mjs --check); a test fails when a doc names a verb that does not exist (B251)- The test gate reruns only the failing test files once, one at a time; a pass on rerun makes the gate green and marks those files
flakyinstatusandreport. Setgates.rerun_failed: 0to turn it off (B255) docs/step-by-step.md: the whole project workflow, step by step, from install to release (B252)
Changed
- npm
code-forgestarts the Go binary; unported verbs go to Node; native internal verbs are underinternal(B242) - On macOS,
npm testruns the suite in a sandbox that blocks writes to the real~/.code-forgeand$TMPDIR/code-forge, so a leak fails at once and other runs on the machine cannot cause false leaks; it printsleak guard: sandboxorleak guard: snapshot (<reason>)(B254) - The docs explain the Go entry and the Node fallback:
docs/getting-started.md,docs/how-it-works.md,docs/native-engine.md(B253)
Fixed
- A review of a Go file now lists the other Go files of the same package and shows the bodies of the functions its changed lines call, so a reviewer no longer reports a function in a sibling file as missing (B245)
- The test leak check ignores short-lived lock files and live-run control writes made by other code-forge runs on the same machine, fails closed when a process probe errors, and tracks children started with spawnSync/execFileSync, so gates no longer fail on false leaks (B246)
- The leak check ignores atomic temp files of other processes and temp files that vanish during the scan (B250)
- The leak check now sees that a lock file belongs to another live code-forge run on days 1-9 of a month (
pspads the date with two spaces), and retries a busy process check before it reports a leak (B258) - The Go config goldens no longer hold the package version, so a version bump in
npm run releaseno longer fails its own test step (B262) - The Go entry speed test compares the Go start with a matched Node start in pairs, so a busy machine no longer fails it; the 25 ms budget is unchanged (B257)
npm run releasenow also bumps the version pins indocs/step-by-step.md, and whennpm testfails it lists the failing test names and saves the full log to.code-forge-tmp/release-npm-test-*.log(B263)- A file rerun after a failed gate now finds test names whose duration has a space before the unit, such as
(12.5 ms)(B259) - The coder command check no longer flags spawn words that are only data inside a Python
json.loads(...)literal; a dynamic lookup such asgetattror__import__keeps the check on (B256)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.17.0
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.17.0/CHANGELOG.md
v0.16.3
Added
review.silence_timeout_s(default 60): a reviewer or judge session that prints nothing for this long is killed and counts as a timeout (B206, landed as B240)
Changed
-
A review answer with
passed: nulland findings is read as a failing review with its findings kept; with no findings it is unavailable (schema) and the fallback model reviews the file (B206, landed as B240) -
After a timeout, a silence kill or an at-capacity answer, the next fallback model runs at once instead of a second try of the same model; without a fallback list the old single retry stays (B206, landed as B240)
-
CI also runs on a push to a
ci-check-*branch and by hand (workflow_dispatch), so the pre-release check really runs before main moves (B239) -
The queue and parallel review tests check order and state with an injected clock, not short wall-clock deadlines, so they pass on a busy machine (B216, landed as B241)
npm: https://www.npmjs.com/package/@codedology/code-forge/v/0.16.3
Full changelog: https://github.com/ricardov03/code-forge/blob/v0.16.3/CHANGELOG.md