@codedology/code-forge 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +1 -1
- package/docs/reference/blocks.json +366 -1
- package/docs/reference/config.md +7 -0
- package/package.json +1 -1
- package/schema/code-forge.schema.json +22 -0
- package/scripts/first-use.mjs +11 -5
- package/skill/SKILL.md +2 -0
- package/skill/references/autopilot.md +2 -0
- package/skill/references/code.md +25 -1
- package/skill/references/review.md +10 -2
- package/skill/scripts/forge +1 -1
- package/src/autopilot/scopes.mjs +2 -1
- package/src/cli/block.mjs +235 -44
- package/src/cli/gates.mjs +36 -6
- package/src/cli/ledger.mjs +21 -2
- package/src/cli/report.mjs +14 -0
- package/src/cli/review-file.mjs +56 -16
- package/src/cli/run.mjs +44 -7
- package/src/cli/status.mjs +7 -3
- package/src/config/validate.mjs +13 -1
- package/src/gates/acceptance.mjs +7 -3
- package/src/gates/expand.mjs +25 -2
- package/src/gates/run.mjs +38 -8
- package/src/ledger/report.mjs +29 -7
- package/src/review/accept-hit.mjs +22 -4
- package/src/review/engine.mjs +30 -10
- package/src/review/finding.schema.json +2 -1
- package/src/review/fixloop.mjs +79 -14
- package/src/review/gate-check.mjs +22 -3
- package/src/review/lenses/recheck.md +3 -0
- package/src/review/packet.mjs +26 -0
- package/src/state/block.mjs +162 -20
- package/src/state/run.mjs +35 -8
- package/src/util/forbidden.mjs +14 -0
- package/src/util/reaper.mjs +3 -3
- package/src/worker/engine.mjs +60 -4
- package/src/worker/loop.mjs +19 -10
- package/src/worker/queue.mjs +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,24 @@ waits on a second real consumer (plan §10.4, Q17).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.15.0] — 2026-10-19
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Worker claim tests back up file-watch barriers with a short poll, so a busy file-event service no longer fails them
|
|
14
|
+
- Support up to four pinned review workers per run, add workers through run start, and verify result identities and dead ticket claims at block close (B107)
|
|
15
|
+
- Light blocks bound small changes to configurable file and line limits, batch their reviews, and run only block tests (B139)
|
|
16
|
+
- Human decision close combines finding waivers, agent acknowledgement and transcript acceptance in one confirmation; immutable `close.require_human` supports delegated `close:routine` grants for approved blocks without waivers or hits (B138)
|
|
17
|
+
|
|
18
|
+
- Clarify that human pass requires a note and accepts optional proof; verify an omitted proof is recorded as null and closes the block (B137b)
|
|
19
|
+
- UI acceptance can require human device checks: code close waits in `awaiting_human_check`, status and report list waiting blocks, and only a terminal-confirmed human pass or stop permits run completion (B137)
|
|
20
|
+
- Opt-in `gates.repeat_new_tests` repeats added or changed block tests after a passing gate, records signed repeat evidence and reports failures as `flaky-test` with the files and failing output (B136)
|
|
21
|
+
- Block open records the base branch; close warns when it moved, and closed worktree blocks can rebase while preserving reviewed file blobs or restoring the old head on refusal (B134)
|
|
22
|
+
- Rechecks include finding evidence, close unsupported current-line claims as stale, and keep repeated claim/evidence findings from escalating the review ladder on their own (B133)
|
|
23
|
+
- A changed lens budget after `run reload` refreshes cached `split_required` results and recheck stops on the same content, including with `--fresh`, and reports the old and new budgets (B132)
|
|
24
|
+
- Review risk counts added and removed lines; oversized quick Markdown packets step up to full before section packing, and the block join exposes per-file outcomes, reports split recovery steps and queues owned changes without earlier tickets (B131)
|
|
25
|
+
- CLI: missing ledger slugs name known projects; block open catches malformed path lists while allowing new plain paths and commas inside braces; worker startup names competing runs; process probes prefer `/bin/ps`; block close requires green gates when configured; human transcript acceptance can cover all rules on a line and its Codex completion (B135, B135b)
|
|
26
|
+
|
|
9
27
|
## [0.14.1] — 2026-10-15
|
|
10
28
|
|
|
11
29
|
### Changed
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"plans/code-forge-plan-v1.3.md §10.4",
|
|
5
5
|
"plans/NIGHT-LOG.md"
|
|
6
6
|
],
|
|
7
|
-
"block_count":
|
|
7
|
+
"block_count": 149,
|
|
8
8
|
"baseline_ids": ["B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8"],
|
|
9
9
|
"baseline_note": "Wave 0-1 blocks, landed before v1.3; depends_on may name them, but they have no entry under blocks.",
|
|
10
10
|
"blocks": {
|
|
@@ -2389,6 +2389,371 @@
|
|
|
2389
2389
|
"B130"
|
|
2390
2390
|
],
|
|
2391
2391
|
"note": "Install records get an optional version field. Summary: logo, 'code-forge <v>', '<old> -> <new>' / 'already on' / 'first versioned upgrade', kept record lines, first 5 CHANGELOG bullets, 'Full notes: <path>'."
|
|
2392
|
+
},
|
|
2393
|
+
"B131": {
|
|
2394
|
+
"title": "Budget split counts removed lines; Markdown steps up to full; join reports an outcome per file and queues owned files with no ticket",
|
|
2395
|
+
"wave": 14,
|
|
2396
|
+
"level": "L2",
|
|
2397
|
+
"status": "landed",
|
|
2398
|
+
"owned": [
|
|
2399
|
+
"src/review/engine.mjs",
|
|
2400
|
+
"src/cli/review-file.mjs",
|
|
2401
|
+
"skill/references/review.md",
|
|
2402
|
+
"docs/how-it-works.md",
|
|
2403
|
+
"CHANGELOG.md",
|
|
2404
|
+
"test/review/budget-step-up.test.mjs",
|
|
2405
|
+
"test/worker/wait-block.test.mjs",
|
|
2406
|
+
"test/worker/watch.test.mjs",
|
|
2407
|
+
"test/skill/structure.test.mjs"
|
|
2408
|
+
],
|
|
2409
|
+
"depends_on": [
|
|
2410
|
+
"B130"
|
|
2411
|
+
],
|
|
2412
|
+
"note": "split_required only above full_in; --wait-block files carry outcome (approved/findings/stopped/split_required/unavailable/null); split_required gives done:false with reason and next."
|
|
2413
|
+
},
|
|
2414
|
+
"B132": {
|
|
2415
|
+
"title": "A lens budget change reruns a split_required stop for the lens that was measured",
|
|
2416
|
+
"wave": 14,
|
|
2417
|
+
"level": "L2",
|
|
2418
|
+
"status": "landed",
|
|
2419
|
+
"owned": [
|
|
2420
|
+
"src/cli/review-file.mjs",
|
|
2421
|
+
"src/worker/ticket.mjs",
|
|
2422
|
+
"src/worker/queue.mjs",
|
|
2423
|
+
"src/review/fixloop.mjs",
|
|
2424
|
+
"skill/references/review.md",
|
|
2425
|
+
"CHANGELOG.md",
|
|
2426
|
+
"test/worker/fresh-split.test.mjs",
|
|
2427
|
+
"test/worker/fresh.test.mjs"
|
|
2428
|
+
],
|
|
2429
|
+
"depends_on": [
|
|
2430
|
+
"B131"
|
|
2431
|
+
],
|
|
2432
|
+
"note": "F2: --fresh re-queues a counted split_required stop when its lens budget changed; the stop keeps its real lens (full, recheck or patch_check)."
|
|
2433
|
+
},
|
|
2434
|
+
"B135": {
|
|
2435
|
+
"title": "Small CLI fixes: unknown ledger slugs, comma path lists, competing worker runs, /bin/ps, close needs green gates, accept-hit per line",
|
|
2436
|
+
"wave": 14,
|
|
2437
|
+
"level": "L1",
|
|
2438
|
+
"status": "landed",
|
|
2439
|
+
"owned": [
|
|
2440
|
+
"src/cli/report.mjs",
|
|
2441
|
+
"src/cli/ledger.mjs",
|
|
2442
|
+
"src/cli/block.mjs",
|
|
2443
|
+
"src/worker/loop.mjs",
|
|
2444
|
+
"src/worker/queue.mjs",
|
|
2445
|
+
"src/util/reaper.mjs",
|
|
2446
|
+
"src/state/run.mjs",
|
|
2447
|
+
"src/review/accept-hit.mjs",
|
|
2448
|
+
"skill/references/code.md",
|
|
2449
|
+
"CHANGELOG.md",
|
|
2450
|
+
"test/ledger/report.test.mjs",
|
|
2451
|
+
"test/ledger/cli.test.mjs",
|
|
2452
|
+
"test/ledger/calibration.test.mjs",
|
|
2453
|
+
"test/cli",
|
|
2454
|
+
"test/worker/registry.test.mjs",
|
|
2455
|
+
"test/util/reaper.test.mjs",
|
|
2456
|
+
"test/state/run.test.mjs",
|
|
2457
|
+
"test/review/close-gate.test.mjs",
|
|
2458
|
+
"test/review/close-gate-field.test.mjs",
|
|
2459
|
+
"test/review/gate-check.test.mjs"
|
|
2460
|
+
],
|
|
2461
|
+
"depends_on": [
|
|
2462
|
+
"B130"
|
|
2463
|
+
],
|
|
2464
|
+
"note": "Closed after review, then held: the full suite showed regressions. Its changes landed through B135b."
|
|
2465
|
+
},
|
|
2466
|
+
"B135b": {
|
|
2467
|
+
"title": "Finish B135: future test paths and brace globs allowed, first-use runs gates before close",
|
|
2468
|
+
"wave": 14,
|
|
2469
|
+
"level": "L1",
|
|
2470
|
+
"status": "landed",
|
|
2471
|
+
"owned": [
|
|
2472
|
+
"src/cli/report.mjs",
|
|
2473
|
+
"src/cli/ledger.mjs",
|
|
2474
|
+
"src/cli/block.mjs",
|
|
2475
|
+
"src/worker/loop.mjs",
|
|
2476
|
+
"src/util/reaper.mjs",
|
|
2477
|
+
"src/state/run.mjs",
|
|
2478
|
+
"src/review/accept-hit.mjs",
|
|
2479
|
+
"skill/references/code.md",
|
|
2480
|
+
"CHANGELOG.md",
|
|
2481
|
+
"test/ledger/report.test.mjs",
|
|
2482
|
+
"test/ledger/cli.test.mjs",
|
|
2483
|
+
"test/ledger/calibration.test.mjs",
|
|
2484
|
+
"test/cli",
|
|
2485
|
+
"test/worker/registry.test.mjs",
|
|
2486
|
+
"test/util/reaper.test.mjs",
|
|
2487
|
+
"test/state/run.test.mjs",
|
|
2488
|
+
"test/review/close-gate.test.mjs",
|
|
2489
|
+
"test/review/close-gate-field.test.mjs",
|
|
2490
|
+
"test/review/gate-check.test.mjs",
|
|
2491
|
+
"test/docs-marketing.test.mjs",
|
|
2492
|
+
"scripts/first-use.mjs",
|
|
2493
|
+
"test/first-use.test.mjs",
|
|
2494
|
+
"test/gates/placeholders.test.mjs",
|
|
2495
|
+
"test/proof/worktree-flow.test.mjs",
|
|
2496
|
+
"test/review/external.test.mjs"
|
|
2497
|
+
],
|
|
2498
|
+
"depends_on": [
|
|
2499
|
+
"B135",
|
|
2500
|
+
"B131"
|
|
2501
|
+
],
|
|
2502
|
+
"note": "Carries the reviewed B135 changes onto the B131 base. A false critical finding was cleared by an answers ticket (B71), not a waiver."
|
|
2503
|
+
},
|
|
2504
|
+
"B133": {
|
|
2505
|
+
"title": "A recheck must not repeat a stale finding: evidence in the recheck packet, current_lines quote, stale and repeated findings",
|
|
2506
|
+
"wave": 14,
|
|
2507
|
+
"level": "L2",
|
|
2508
|
+
"status": "landed",
|
|
2509
|
+
"owned": [
|
|
2510
|
+
"src/review/fixloop.mjs",
|
|
2511
|
+
"src/review/lenses/recheck.md",
|
|
2512
|
+
"src/review/finding.schema.json",
|
|
2513
|
+
"src/review/validate-review.mjs",
|
|
2514
|
+
"skill/references/review.md",
|
|
2515
|
+
"CHANGELOG.md",
|
|
2516
|
+
"test/review/fixloop.test.mjs",
|
|
2517
|
+
"test/review/validate-review.test.mjs",
|
|
2518
|
+
"test/review/recheck-real.test.mjs"
|
|
2519
|
+
],
|
|
2520
|
+
"depends_on": [
|
|
2521
|
+
"B132"
|
|
2522
|
+
],
|
|
2523
|
+
"note": "Stopped after review: the acceptance saved at open had a wrong stale rule. Its changes landed through B133b."
|
|
2524
|
+
},
|
|
2525
|
+
"B133b": {
|
|
2526
|
+
"title": "Finish B133: stale only when a quoted current_lines is not in the file; a missing quote keeps the old behaviour",
|
|
2527
|
+
"wave": 14,
|
|
2528
|
+
"level": "L2",
|
|
2529
|
+
"status": "landed",
|
|
2530
|
+
"owned": [
|
|
2531
|
+
"src/review/fixloop.mjs",
|
|
2532
|
+
"src/review/lenses/recheck.md",
|
|
2533
|
+
"src/review/finding.schema.json",
|
|
2534
|
+
"src/review/validate-review.mjs",
|
|
2535
|
+
"skill/references/review.md",
|
|
2536
|
+
"CHANGELOG.md",
|
|
2537
|
+
"test/review/fixloop.test.mjs",
|
|
2538
|
+
"test/review/validate-review.test.mjs",
|
|
2539
|
+
"test/review/recheck-real.test.mjs"
|
|
2540
|
+
],
|
|
2541
|
+
"depends_on": [
|
|
2542
|
+
"B133",
|
|
2543
|
+
"B135b"
|
|
2544
|
+
],
|
|
2545
|
+
"note": "Carries the B133 changes onto main with the corrected acceptance. Fixes issue #18."
|
|
2546
|
+
},
|
|
2547
|
+
"B134": {
|
|
2548
|
+
"title": "Block open records the base branch HEAD; close warns when the base has commits the block lacks; block rebase accepts a closed block and keeps reviewed file blobs",
|
|
2549
|
+
"wave": 14,
|
|
2550
|
+
"level": "L2",
|
|
2551
|
+
"status": "landed",
|
|
2552
|
+
"owned": [
|
|
2553
|
+
"src/state/block.mjs",
|
|
2554
|
+
"src/cli/block.mjs",
|
|
2555
|
+
"skill/references/code.md",
|
|
2556
|
+
"CHANGELOG.md",
|
|
2557
|
+
"test/state/block.test.mjs",
|
|
2558
|
+
"test/cli/block-rebase-closed.test.mjs",
|
|
2559
|
+
"test/cli/block-close-base-warning.test.mjs"
|
|
2560
|
+
],
|
|
2561
|
+
"depends_on": [
|
|
2562
|
+
"B135b"
|
|
2563
|
+
],
|
|
2564
|
+
"note": "Fixes issue #21. A fix round removed a false warning when the block commits on its own base branch."
|
|
2565
|
+
},
|
|
2566
|
+
"B136": {
|
|
2567
|
+
"title": "gates.repeat_new_tests: repeat the block's added or changed test files N times; a failed repeat is a red flaky-test gate with signed repeat evidence",
|
|
2568
|
+
"wave": 14,
|
|
2569
|
+
"level": "L2",
|
|
2570
|
+
"status": "landed",
|
|
2571
|
+
"owned": [
|
|
2572
|
+
"src/cli/gates.mjs",
|
|
2573
|
+
"src/gates/run.mjs",
|
|
2574
|
+
"src/gates/expand.mjs",
|
|
2575
|
+
"src/config/validate.mjs",
|
|
2576
|
+
"schema/code-forge.schema.json",
|
|
2577
|
+
"src/ledger/report.mjs",
|
|
2578
|
+
"docs/reference/config.md",
|
|
2579
|
+
"skill/references/code.md",
|
|
2580
|
+
"CHANGELOG.md",
|
|
2581
|
+
"test/gates/run.test.mjs",
|
|
2582
|
+
"test/gates/cli.test.mjs",
|
|
2583
|
+
"test/gates/changed.test.mjs",
|
|
2584
|
+
"test/config/cli-validate.test.mjs",
|
|
2585
|
+
"test/ledger/report.test.mjs",
|
|
2586
|
+
"test/docs-config.test.mjs",
|
|
2587
|
+
"test/config/schema-coverage.test.mjs"
|
|
2588
|
+
],
|
|
2589
|
+
"depends_on": [
|
|
2590
|
+
"B134"
|
|
2591
|
+
],
|
|
2592
|
+
"note": "Fixes issue #20. A false critical finding (signed row callback) was cleared by making the sign-and-append call explicit."
|
|
2593
|
+
},
|
|
2594
|
+
"B137": {
|
|
2595
|
+
"title": "A human device check gate: acceptance clauses marked human, block human-pass with a required note and optional proof, close refuses until passed",
|
|
2596
|
+
"wave": 14,
|
|
2597
|
+
"level": "L2",
|
|
2598
|
+
"status": "landed",
|
|
2599
|
+
"owned": [
|
|
2600
|
+
"src/gates/acceptance.mjs",
|
|
2601
|
+
"src/state/block.mjs",
|
|
2602
|
+
"src/state/run.mjs",
|
|
2603
|
+
"src/cli/block.mjs",
|
|
2604
|
+
"src/cli/run.mjs",
|
|
2605
|
+
"src/cli/status.mjs",
|
|
2606
|
+
"src/cli/report.mjs",
|
|
2607
|
+
"src/ledger/report.mjs",
|
|
2608
|
+
"src/util/forbidden.mjs",
|
|
2609
|
+
"skill/references/code.md",
|
|
2610
|
+
"skill/SKILL.md",
|
|
2611
|
+
"docs/how-it-works.md",
|
|
2612
|
+
"CHANGELOG.md",
|
|
2613
|
+
"test/gates/acceptance.test.mjs",
|
|
2614
|
+
"test/cli/block-human-pass.test.mjs",
|
|
2615
|
+
"test/util/forbidden.test.mjs",
|
|
2616
|
+
"test/state/block.test.mjs"
|
|
2617
|
+
],
|
|
2618
|
+
"depends_on": [
|
|
2619
|
+
"B136"
|
|
2620
|
+
],
|
|
2621
|
+
"note": "Stopped after review: the acceptance saved at open said --proof was required, but issue #19 makes it optional. Its changes landed through B137b."
|
|
2622
|
+
},
|
|
2623
|
+
"B137b": {
|
|
2624
|
+
"title": "A human device check gate: acceptance clauses marked human, block human-pass with a required note and optional proof, close refuses until passed (corrected acceptance: proof optional)",
|
|
2625
|
+
"wave": 14,
|
|
2626
|
+
"level": "L2",
|
|
2627
|
+
"status": "landed",
|
|
2628
|
+
"owned": [
|
|
2629
|
+
"src/gates/acceptance.mjs",
|
|
2630
|
+
"src/state/block.mjs",
|
|
2631
|
+
"src/state/run.mjs",
|
|
2632
|
+
"src/cli/block.mjs",
|
|
2633
|
+
"src/cli/run.mjs",
|
|
2634
|
+
"src/cli/status.mjs",
|
|
2635
|
+
"src/cli/report.mjs",
|
|
2636
|
+
"src/ledger/report.mjs",
|
|
2637
|
+
"src/util/forbidden.mjs",
|
|
2638
|
+
"skill/references/code.md",
|
|
2639
|
+
"skill/SKILL.md",
|
|
2640
|
+
"docs/how-it-works.md",
|
|
2641
|
+
"CHANGELOG.md",
|
|
2642
|
+
"test/gates/acceptance.test.mjs",
|
|
2643
|
+
"test/cli/block-human-pass.test.mjs",
|
|
2644
|
+
"test/util/forbidden.test.mjs",
|
|
2645
|
+
"test/state/block.test.mjs",
|
|
2646
|
+
"test/engines/builders/argv-snapshots.test.mjs",
|
|
2647
|
+
"test/engines/builders/forbidden-rendering.test.mjs",
|
|
2648
|
+
"test/engines/codex-home.test.mjs"
|
|
2649
|
+
],
|
|
2650
|
+
"depends_on": [
|
|
2651
|
+
"B137",
|
|
2652
|
+
"B136"
|
|
2653
|
+
],
|
|
2654
|
+
"note": "Fixes issue #19. Fix round 1 appended the human-pass coder rule and updated the pinned coder-only counts. A false transcript hit (flag text inside an edit script) was accepted by the owner."
|
|
2655
|
+
},
|
|
2656
|
+
"B138": {
|
|
2657
|
+
"title": "One human step per block: block close --decide lists every human-clearable refusal and asks one confirm; close.require_human; autopilot close:routine scope for routine closes",
|
|
2658
|
+
"wave": 14,
|
|
2659
|
+
"level": "L2",
|
|
2660
|
+
"status": "landed",
|
|
2661
|
+
"owned": [
|
|
2662
|
+
"src/cli/block.mjs",
|
|
2663
|
+
"src/state/block.mjs",
|
|
2664
|
+
"src/review/gate-check.mjs",
|
|
2665
|
+
"src/review/accept-hit.mjs",
|
|
2666
|
+
"src/autopilot/scopes.mjs",
|
|
2667
|
+
"src/autopilot/grant.mjs",
|
|
2668
|
+
"src/config/validate.mjs",
|
|
2669
|
+
"src/state/run.mjs",
|
|
2670
|
+
"schema/code-forge.schema.json",
|
|
2671
|
+
"docs/reference/config.md",
|
|
2672
|
+
"skill/references/code.md",
|
|
2673
|
+
"skill/references/autopilot.md",
|
|
2674
|
+
"CHANGELOG.md",
|
|
2675
|
+
"test/cli/block-close-decide.test.mjs",
|
|
2676
|
+
"test/cli/block-close-routine.test.mjs",
|
|
2677
|
+
"test/autopilot/grant.test.mjs",
|
|
2678
|
+
"test/config/schema-coverage.test.mjs",
|
|
2679
|
+
"test/autopilot/delegate.test.mjs",
|
|
2680
|
+
"test/cli/autopilot.test.mjs"
|
|
2681
|
+
],
|
|
2682
|
+
"depends_on": [
|
|
2683
|
+
"B137b"
|
|
2684
|
+
],
|
|
2685
|
+
"note": "Issue #16 item 8 (owner F4: one confirm + grant). Fix round 1 pinned close:routine in two old scope-message tests and proved the no answer was asked."
|
|
2686
|
+
},
|
|
2687
|
+
"B139": {
|
|
2688
|
+
"title": "Light block kind: block open --kind light, one batched review per block (max 2), block-test-only gates, light-limits refusal at close",
|
|
2689
|
+
"wave": 14,
|
|
2690
|
+
"level": "L2",
|
|
2691
|
+
"status": "landed",
|
|
2692
|
+
"owned": [
|
|
2693
|
+
"src/cli/block.mjs",
|
|
2694
|
+
"src/state/block.mjs",
|
|
2695
|
+
"src/worker/engine.mjs",
|
|
2696
|
+
"src/worker/loop.mjs",
|
|
2697
|
+
"src/worker/queue.mjs",
|
|
2698
|
+
"src/review/engine.mjs",
|
|
2699
|
+
"src/review/packet.mjs",
|
|
2700
|
+
"src/cli/review-file.mjs",
|
|
2701
|
+
"src/cli/gates.mjs",
|
|
2702
|
+
"src/gates/run.mjs",
|
|
2703
|
+
"src/gates/expand.mjs",
|
|
2704
|
+
"src/config/validate.mjs",
|
|
2705
|
+
"schema/code-forge.schema.json",
|
|
2706
|
+
"docs/reference/config.md",
|
|
2707
|
+
"skill/references/code.md",
|
|
2708
|
+
"skill/references/review.md",
|
|
2709
|
+
"CHANGELOG.md",
|
|
2710
|
+
"test/cli/block-light.test.mjs",
|
|
2711
|
+
"test/worker/light-batch.test.mjs",
|
|
2712
|
+
"test/gates/run.test.mjs",
|
|
2713
|
+
"test/config/schema-coverage.test.mjs"
|
|
2714
|
+
],
|
|
2715
|
+
"depends_on": [
|
|
2716
|
+
"B138"
|
|
2717
|
+
],
|
|
2718
|
+
"note": "Issue #16 item 9 (owner F5: --kind light). Fix round 1: a cached light result was reused before the ticket hash check (critical). Fix round 2: test types."
|
|
2719
|
+
},
|
|
2720
|
+
"B107": {
|
|
2721
|
+
"title": "Several review workers in one run: review.workers 1..4, run start --add-worker, worker identity on signed results, pin checks per worker",
|
|
2722
|
+
"wave": 14,
|
|
2723
|
+
"level": "L2",
|
|
2724
|
+
"status": "landed",
|
|
2725
|
+
"owned": [
|
|
2726
|
+
"src/worker/loop.mjs",
|
|
2727
|
+
"src/worker/queue.mjs",
|
|
2728
|
+
"src/worker/engine.mjs",
|
|
2729
|
+
"src/cli/run.mjs",
|
|
2730
|
+
"src/util/forbidden.mjs",
|
|
2731
|
+
"src/state/block.mjs",
|
|
2732
|
+
"src/state/run.mjs",
|
|
2733
|
+
"src/config/validate.mjs",
|
|
2734
|
+
"schema/code-forge.schema.json",
|
|
2735
|
+
"docs/reference/config.md",
|
|
2736
|
+
"skill/references/review.md",
|
|
2737
|
+
"CHANGELOG.md",
|
|
2738
|
+
"test/worker/registry.test.mjs",
|
|
2739
|
+
"test/worker/multi.test.mjs",
|
|
2740
|
+
"test/state/block.test.mjs",
|
|
2741
|
+
"test/util/forbidden.test.mjs",
|
|
2742
|
+
"test/config/schema-coverage.test.mjs",
|
|
2743
|
+
"test/engines/codex-home.test.mjs",
|
|
2744
|
+
"test/engines/builders/forbidden-rendering.test.mjs",
|
|
2745
|
+
"test/engines/builders/argv-snapshots.test.mjs",
|
|
2746
|
+
"test/review/answers.test.mjs",
|
|
2747
|
+
"test/review/reopen.test.mjs",
|
|
2748
|
+
"test/review/route.test.mjs",
|
|
2749
|
+
"test/worker/deletion-review.test.mjs",
|
|
2750
|
+
"test/state/run.test.mjs"
|
|
2751
|
+
],
|
|
2752
|
+
"depends_on": [
|
|
2753
|
+
"B139",
|
|
2754
|
+
"B106"
|
|
2755
|
+
],
|
|
2756
|
+
"note": "Issue #16 item 7 (rest of Group E). Fix round 1: results without a worker field keep the old pin check (82 old tests). Fix round 2: a recycled live pid must match its own pin (critical); an added worker is stopped when its probe fails."
|
|
2392
2757
|
}
|
|
2393
2758
|
}
|
|
2394
2759
|
}
|
package/docs/reference/config.md
CHANGED
|
@@ -55,6 +55,11 @@ Every other key defaults as shown, or is entirely absent from a minimal file. `a
|
|
|
55
55
|
| `levels.L3.fallback[].effort` | string | | — | |
|
|
56
56
|
| `levels.coder_floor_docs` | enum: `L0`, `L1`, `L2` | | `"L1"` | |
|
|
57
57
|
| `orchestrator` | enum: `L0`, `L1`, `L2`, `L3` | | — | |
|
|
58
|
+
| `light` | object | | — | |
|
|
59
|
+
| `light.max_files` | integer | | `5` | min 1; Maximum owned changed files in a light block at close. |
|
|
60
|
+
| `light.max_lines` | integer | | `300` | min 1; Maximum added plus removed lines in a light block at close. |
|
|
61
|
+
| `close` | object | | — | |
|
|
62
|
+
| `close.require_human` | boolean | | `false` | B138: require a terminal-confirmed human close, unless an active close:routine grant covers a routine block. Read from the run snapshot; cannot change by run reload. |
|
|
58
63
|
| `system1` | object | | — | |
|
|
59
64
|
| `system1.provider` | enum: `anthropic`, `openai`, `xai` | | — | |
|
|
60
65
|
| `system1.model` | string | | — | |
|
|
@@ -127,6 +132,7 @@ Every other key defaults as shown, or is entirely absent from a minimal file. `a
|
|
|
127
132
|
| `review.routes[].second.fallback[].provider` | enum: `anthropic`, `openai`, `xai` | yes | — | |
|
|
128
133
|
| `review.routes[].second.fallback[].model` | string | yes | — | minLength 1 |
|
|
129
134
|
| `review.routes[].second.fallback[].effort` | string | | — | |
|
|
135
|
+
| `review.workers` | integer | | `1` | min 1; max 4; B107: Maximum live workers serving the queue. The orchestrator adds one with run start --add-worker --run <id>. |
|
|
130
136
|
| `review.max_rounds_per_file` | integer | | `4` | min 2; max 6 |
|
|
131
137
|
| `review.recheck_scope` | enum: `fix_hunks`, `file` | | `"fix_hunks"` | |
|
|
132
138
|
| `review.late_findings` | enum: `sweep`, `block` | | `"sweep"` | |
|
|
@@ -161,6 +167,7 @@ Every other key defaults as shown, or is entirely absent from a minimal file. `a
|
|
|
161
167
|
| `gates.extra.secret_scan` | boolean | | `true` | |
|
|
162
168
|
| `gates.extra.safe_edit` | boolean | | `true` | |
|
|
163
169
|
| `gates.extra.invariants` | string | | — | |
|
|
170
|
+
| `gates.repeat_new_tests` | integer | | — | min 2; max 10; After a passing test gate with --run and --block, run its command this many additional times for only tests added or changed against the block base; absent means off. Requires a whole {test_files} argv item; otherwise prints repeat_new_tests: skipped (gates.test has no {test_files}). A failed repeat makes the gate red with reason flaky-test; output and signed gate rows carry repeats {n, files, failed}, and report shows the count. |
|
|
164
171
|
| `gates.full_suite_threshold_files` | integer | | `10` | min 1; A block that owns more files than this runs the full suite for a {test_files} gate (reason threshold), not its related tests. Owned files are counted this way. A glob or a directory counts the tracked and new (not ignored) files it covers. A path not created yet counts as 1. Outside git each entry counts 1. A git failure runs the full suite. block open --tests names the test files precisely. With gates run --changed, the threshold counts changed files since the last green gates run --run --block instead. |
|
|
165
172
|
| `proof` | object | | — | |
|
|
166
173
|
| `proof.tiers` | object | | — | |
|
package/package.json
CHANGED
|
@@ -41,6 +41,21 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"orchestrator": { "$ref": "#/$defs/levelName" },
|
|
44
|
+
"light": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"properties": {
|
|
48
|
+
"max_files": { "type": "integer", "minimum": 1, "default": 5, "description": "Maximum owned changed files in a light block at close." },
|
|
49
|
+
"max_lines": { "type": "integer", "minimum": 1, "default": 300, "description": "Maximum added plus removed lines in a light block at close." }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"close": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"properties": {
|
|
56
|
+
"require_human": { "type": "boolean", "default": false, "description": "B138: require a terminal-confirmed human close, unless an active close:routine grant covers a routine block. Read from the run snapshot; cannot change by run reload." }
|
|
57
|
+
}
|
|
58
|
+
},
|
|
44
59
|
"system1": {
|
|
45
60
|
"type": "object",
|
|
46
61
|
"additionalProperties": false,
|
|
@@ -170,6 +185,7 @@
|
|
|
170
185
|
}
|
|
171
186
|
}
|
|
172
187
|
},
|
|
188
|
+
"workers": { "type": "integer", "minimum": 1, "maximum": 4, "default": 1, "description": "B107: Maximum live workers serving the queue. The orchestrator adds one with run start --add-worker --run <id>." },
|
|
173
189
|
"max_rounds_per_file": { "type": "integer", "minimum": 2, "maximum": 6, "default": 4 },
|
|
174
190
|
"recheck_scope": { "type": "string", "enum": ["fix_hunks", "file"], "default": "fix_hunks" },
|
|
175
191
|
"late_findings": { "type": "string", "enum": ["sweep", "block"], "default": "sweep" },
|
|
@@ -246,6 +262,12 @@
|
|
|
246
262
|
"invariants": { "type": "string" }
|
|
247
263
|
}
|
|
248
264
|
},
|
|
265
|
+
"repeat_new_tests": {
|
|
266
|
+
"type": "integer",
|
|
267
|
+
"minimum": 2,
|
|
268
|
+
"maximum": 10,
|
|
269
|
+
"description": "After a passing test gate with --run and --block, run its command this many additional times for only tests added or changed against the block base; absent means off. Requires a whole {test_files} argv item; otherwise prints repeat_new_tests: skipped (gates.test has no {test_files}). A failed repeat makes the gate red with reason flaky-test; output and signed gate rows carry repeats {n, files, failed}, and report shows the count."
|
|
270
|
+
},
|
|
249
271
|
"full_suite_threshold_files": {
|
|
250
272
|
"type": "integer",
|
|
251
273
|
"minimum": 1,
|
package/scripts/first-use.mjs
CHANGED
|
@@ -25,8 +25,9 @@
|
|
|
25
25
|
* 8 review `code-forge review-file <file>` + `review-file --wait` per owned file
|
|
26
26
|
* 9 proof `proof export` (lists the export-ignore paths it restored), the test gate inside the
|
|
27
27
|
* export, `proof red-green` per test the acceptance names, `proof export --remove`
|
|
28
|
-
* 10
|
|
29
|
-
* 11
|
|
28
|
+
* 10 gates `code-forge gates run --run <run> --block B1` — green before close
|
|
29
|
+
* 11 close `code-forge block close B1` — then the cost of the completed block is printed
|
|
30
|
+
* 12 report `code-forge report --slug <slug>`
|
|
30
31
|
* then `code-forge run end` (always, once the run started: it stops the worker).
|
|
31
32
|
*
|
|
32
33
|
* Engines: `harness` is the default (R2: the no-Solo default). `subprocess` is OPT-IN: it is
|
|
@@ -60,7 +61,7 @@ const DEGRADED_DOC = path.join(PKG, 'skill', 'references', 'degraded.md');
|
|
|
60
61
|
|
|
61
62
|
export const BLOCK = 'B1';
|
|
62
63
|
export const OWNED = Object.freeze(['src/math.mjs', 'test/clamp.test.mjs']);
|
|
63
|
-
export const STEPS = Object.freeze(['copy', 'init', 'facts', 'author', 'start', 'open', 'code', 'review', 'proof', 'close', 'report']);
|
|
64
|
+
export const STEPS = Object.freeze(['copy', 'init', 'facts', 'author', 'start', 'open', 'code', 'review', 'proof', 'gates', 'close', 'report']);
|
|
64
65
|
const ENGINES = ['harness', 'subprocess'];
|
|
65
66
|
const CODERS = ['scripted', 'harness', 'spawn'];
|
|
66
67
|
const CLI_TIMEOUT_MS = 30 * 60 * 1000;
|
|
@@ -385,7 +386,12 @@ export async function main(argv, io = {}) {
|
|
|
385
386
|
await cf(['proof', 'export', BLOCK, '--run', run, '--remove']);
|
|
386
387
|
if (done('proof')) return 0;
|
|
387
388
|
|
|
388
|
-
// 10 —
|
|
389
|
+
// 10 — record green gates for this run and block, after the proofs
|
|
390
|
+
step('gates');
|
|
391
|
+
say((await cf(['gates', 'run', '--run', run, '--block', BLOCK])).stdout.trimEnd());
|
|
392
|
+
if (done('gates')) return 0;
|
|
393
|
+
|
|
394
|
+
// 11 — the close check, then what the completed block cost
|
|
389
395
|
step('close');
|
|
390
396
|
say((await cf(['block', 'close', BLOCK, '--run', run])).stdout.trimEnd());
|
|
391
397
|
blockOpen = false;
|
|
@@ -398,7 +404,7 @@ export async function main(argv, io = {}) {
|
|
|
398
404
|
);
|
|
399
405
|
if (done('close')) return 0;
|
|
400
406
|
|
|
401
|
-
//
|
|
407
|
+
// 12 — the report
|
|
402
408
|
step('report');
|
|
403
409
|
const report = await cf(['report', '--slug', /** @type {string} */ (summary.slug)]);
|
|
404
410
|
stdout.write(report.stdout);
|
package/skill/SKILL.md
CHANGED
|
@@ -22,6 +22,8 @@ State lives in the plan file's header — `facts → planned → hardened → co
|
|
|
22
22
|
|
|
23
23
|
## §2 Roles by level (never by model name)
|
|
24
24
|
|
|
25
|
+
`block human-pass <id> --run <r> --note <text> [--proof <dir-or-file>]` is human-only: the owner checks the listed device checks and confirms in their own terminal, with no `--yes` and no active autopilot grant. The note is required; proof is optional, must name an existing path when given, and is recorded as `proof: null` when omitted. A successful code close with `kind: human_check` acceptance clauses leaves `awaiting_human_check`, which status and report list; it has no fresh done file until the human passes or stops it. Never run this verb for the human, and do not end the run or treat the block as ready to land while it is awaiting a check (`references/code.md` §5).
|
|
26
|
+
|
|
25
27
|
| role | level | session | who runs it |
|
|
26
28
|
|---|---|---|---|
|
|
27
29
|
| facts delegate | L0 | read-only tools, empty cwd | `forge facts` |
|
|
@@ -13,6 +13,8 @@ Autopilot lets the owner leave for a set time. A delegate (a fresh L2 or L3 sess
|
|
|
13
13
|
|
|
14
14
|
## §2 During the window
|
|
15
15
|
|
|
16
|
+
The allowable scope `close:routine` means “close a routine block.” It lets plain `block close` pass `close.require_human` without a terminal when every changed file has a signed approval, a signed green gate row exists, and the block has no waiver rows, transcript hits or accepted hits. Waived or answered-only reviews do not qualify. Refusal is `close-not-routine: <reason>` (exit 1); success signs `autopilot.close {block, grant}` alongside the normal close. It never permits `block close --decide` or critical waivers.
|
|
17
|
+
|
|
16
18
|
- **Every owner-level question goes to the delegate first**: `forge autopilot ask --run <r> --scope <scope> --question <text> --options <words> [--block <id>] [--file <path>] [--finding <id>]`. Use the fixed option words, or the action will refuse the answer: a waiver `waive,fix` · an extra round `allow,deny` · a coder level the candidate levels, e.g. `L1,L2`.
|
|
17
19
|
- **Act only when it acted** (exit 0): run the action with `--decision <id>` from the answer — `forge autopilot waive|round|level … --decision <id>`. Exit 3 means the question goes to the owner: leave it open, it shows under Open questions. Exit 1 means the grant refused it: also the owner's.
|
|
18
20
|
- **A paused category** (`autopilot paused: … waiting for the owner`): wait. Never raise the cap, never route around it.
|