@lemoncode/lemony 0.3.0 → 0.4.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/catalog/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -52,7 +52,7 @@ acceptance for `write-adr` / `playbook-iterate`. See the Orchestrator's §Closeo
52
52
  block is recorded, the decision arrives in the spawn prompt instead — don't
53
53
  stall looking for it in the entry); the changed code from the PR diff when a PR
54
54
  exists (closeout) or from the branch when none does (mid-task routes — under
55
- pre-commit review ON read the **worktree**: mid-task the branch holds only
55
+ auto-commit OFF read the **worktree**: mid-task the branch holds only
56
56
  OK'd groups, or nothing before the first OK); or the
57
57
  request. If the codebase is unfamiliar and the
58
58
  task needs it, run `code-explorer` first.
@@ -52,7 +52,7 @@ what you run, only how many calls carry it.
52
52
  already committed there.
53
53
  2. **Implement via TDD** — run the `tdd` skill: one red → green → refactor cycle per
54
54
  behavior (vertical slices, never all-tests-then-all-code). When your invocation
55
- says **pre-commit review is ON**, the whole run obeys §Staging protocol (below) —
55
+ says **auto-commit is OFF**, the whole run obeys §Staging protocol (below) —
56
56
  zero commits, staged save-points.
57
57
  **Scope: exactly what the invocation hands you.** By default that is the whole
58
58
  `tasks.md` list (all-at-once). In **step-by-step mode** the Orchestrator
@@ -60,8 +60,8 @@ what you run, only how many calls carry it.
60
60
  group's id + header line): read that group's tasks from the spec's `tasks.md`
61
61
  yourself. On a later iteration the reference comes with reviewer or
62
62
  human-checkpoint feedback. Work the group's tasks
63
- in order — one TDD cycle and small commits per task, as always (ON: staged
64
- save-points per task — §Staging protocol) — then stop: do
63
+ in order — one TDD cycle and small commits per task, as always (auto-commit
64
+ OFF: staged save-points per task — §Staging protocol) — then stop: do
65
65
  **not** run ahead into the next group (the human checkpoints each group before the
66
66
  next starts), and don't re-open tasks the human already OK'd unless the feedback
67
67
  you were handed says so.
@@ -98,7 +98,7 @@ what you run, only how many calls carry it.
98
98
  lint / tests + coverage / audit + a real run); otherwise run those gates inline.
99
99
  Commit your work to the branch and **push it, best-effort** — a failed push (offline,
100
100
  auth) is a warning in your summary, never a blocker; the commits stay safe locally,
101
- then return a summary to the Orchestrator. (Pre-commit review ON: no commit and
101
+ then return a summary to the Orchestrator. (Auto-commit OFF: no commit and
102
102
  no push — leave **everything staged** and say so in the summary; the Orchestrator
103
103
  commits at the human's OK.) The Orchestrator opens
104
104
  the PR when you signal done — you don't open it.
@@ -108,14 +108,14 @@ what you run, only how many calls carry it.
108
108
  checkpoint's "how to run it" is presented from it), and any `## Side-findings`
109
109
  block. Long-form material — reasoning, alternatives weighed, per-task notes —
110
110
  belongs in `progress.md` and the commit messages, never in the summary
111
- (pre-commit review ON: in `progress.md` alone — there are no commit messages
111
+ (auto-commit OFF: in `progress.md` alone — there are no commit messages
112
112
  until the human OK, so it carries everything a fresh iteration will need): the
113
113
  Orchestrator carries your summary in context for the rest of the task, so every
114
114
  extra line taxes the whole run. The cap trims narrative, not signal — a blocker,
115
115
  a deviation from the spec, or a side-finding is always stated, however long the
116
116
  list.
117
117
 
118
- ## Staging protocol (pre-commit review ON)
118
+ ## Staging protocol (auto-commit OFF)
119
119
 
120
120
  Active **only when your invocation says so** — the human chose to review the work
121
121
  **uncommitted**, so the branch must receive nothing until their OK. This inverts
@@ -205,9 +205,9 @@ define's close (`.claude/agents/partition.md`); a parent issue carrying
205
205
  context) once with the `tdd` skill and the branch — it keeps `progress.md` live and
206
206
  signals done; **step-by-step** runs the per-group loop (§Step-by-step
207
207
  implementation) instead, and rejoins this flow at step 8 after the last group. With
208
- **pre-commit review ON** (the gate's second knob), either mode runs the zero-commit
209
- protocol — no commit touches the branch before a checkpoint OK (§Pre-commit review
210
- ON); in all-at-once its single gate runs when the Implementer signals done,
208
+ **auto-commit OFF** (the gate's second knob), either mode runs the zero-commit
209
+ protocol — no commit touches the branch before a checkpoint OK (§Auto-commit
210
+ OFF); in all-at-once its single gate runs when the Implementer signals done,
211
211
  **before** step 8 — the PR never opens on uncommitted work.
212
212
  8. **Review** — flip to `harness:status:in-review` and **open the PR**
213
213
  (`gh pr create`, `harness/<id>-<slug> → <default>`, with `Closes #<id>` in the PR
@@ -319,28 +319,32 @@ applies. The mode is switchable **downward only** (step-by-step → all-at-once,
319
319
  at every checkpoint); there is no upgrade path — all-at-once has no stop where the
320
320
  switch could be offered.
321
321
 
322
- **The second knob, same interaction — pre-commit review.** Alongside the mode, settle
323
- whether the human reviews the work **uncommitted**, before anything lands on the
324
- branch. Read `implementation.pre_commit_review` from `harness.config.yml` first (an
325
- absent key means `human`): `on` / `off` **pin the answer record it without asking**;
326
- `human` (the default) asks here, in the same interaction, suggesting OFF:
327
-
328
- > **Pre-commit review OFF** (default) the Implementer commits and best-effort
329
- > pushes as it works, exactly as today; checkpoints present committed work per
330
- > the checkpoint contract.
322
+ **The second knob, same interaction — auto-commit.** Alongside the mode, settle
323
+ whether the agent commits automatically as it works, or the human reviews the work
324
+ **uncommitted** before anything lands on the branch. Read
325
+ `implementation.auto_commit` from `harness.config.yml` first (an absent key means
326
+ `human`): `on` / `off` **pin the answer record it without asking**; `human` (the
327
+ default) asks here, in the same interaction. Ask the **decision, not the mechanism**:
328
+ header **Auto-commit**, question _"Should the agent commit automatically as it
329
+ works?"_, exactly these two options in this order **OFF first, marked recommended** —
330
+ with these descriptions (short and closed; do not pad them with mode arithmetic or
331
+ your own reading of the trade-off):
332
+
333
+ > **OFF (recommended)** — the agent makes **zero commits**: you review the work
334
+ > uncommitted in the Source Control panel (and can edit it in place); the branch
335
+ > gets its first commit on your OK. Choose this for more control.
331
336
  >
332
- > **Pre-commit review ON** — the Implementer makes **zero commits**: the work
333
- > accumulates in the worktree under a staging protocol, you review it
334
- > **uncommitted** (the Source Control panel shows it natively, and you can edit
335
- > it in place), and the branch receives its first commit only on your OK.
336
-
337
- Record it next to the mode line (`Pre-commit review: off` / `on`) execution state,
338
- like the mode. The knob is **L1-only** (it rides this question; L2 always runs today's
339
- flow) and orthogonal to the mode: it moves **when the branch first receives commits**,
340
- never whether review happens. In step-by-step the uncommitted gate runs per group; in
341
- all-at-once it is **one gate over the entire implementation** (its single "group" is
342
- the whole `tasks.md`). ON's mechanics staging save-points, full deferral,
343
- watch-fors — live in §Pre-commit review ON.
337
+ > **ON** — the agent commits and pushes as it works; checkpoints present
338
+ > committed work. Choose this to be interrupted less (in step-by-step it avoids
339
+ > one dirty-tree review per group).
340
+
341
+ Record it next to the mode line (`Auto-commit: off` / `on`) — execution state, like
342
+ the mode. The knob is **L1-only** (it rides this question; L2 always runs the
343
+ commit-as-you-go flow) and orthogonal to the mode: it moves **when the branch first
344
+ receives commits**, never whether review happens. In step-by-step the uncommitted
345
+ gate runs per group; in all-at-once it is **one gate over the entire implementation**
346
+ (its single "group" is the whole `tasks.md`). Auto-commit OFF's mechanics staging
347
+ save-points, full deferral, watch-forslive in §Auto-commit OFF.
344
348
 
345
349
  ## Step-by-step implementation (the per-group loop)
346
350
 
@@ -362,7 +366,7 @@ numbers still never shift. For each group, in order:
362
366
  task-state paths, and the group's id + header line in `tasks.md` — by reference
363
367
  (§Sub-agent invocation), it reads the group's tasks from the file itself (`tdd`
364
368
  skill — checkbox by checkbox with small commits, as always). It commits to the
365
- branch (pre-commit review ON: it **stages** instead of committing — point the
369
+ branch (auto-commit OFF: it **stages** instead of committing — point the
366
370
  invocation at the staging protocol in `implementer.md`), logs to `progress.md`,
367
371
  and signals done. **No PR yet** — the PR opens after the last group,
368
372
  as in all-at-once; the human inspects and runs the **local checkout** (a checkpoint
@@ -372,7 +376,8 @@ numbers still never shift. For each group, in order:
372
376
  group's tasks and requirements itself — scoped to the **group's diff against its
373
377
  slice of the spec**. **Hand the group's anchor OID (step 1's step-log line) in the
374
378
  spawn prompt in both knob states** — the Reviewer self-validates its ledger
375
- against it (`--anchor`); pre-commit review ON additionally hands the ON flag
379
+ against it (`--anchor`); under auto-commit OFF the prompt additionally says
380
+ `auto-commit is OFF` —
376
381
  the diff is then the group's **uncommitted work against the anchor**,
377
382
  `git diff <anchor> -- ':(exclude).claude/state'`; worktree == index
378
383
  within that scope at review time. The
@@ -401,9 +406,10 @@ numbers still never shift. For each group, in order:
401
406
  invocation handed it, and your authoritative run catches a green built on the
402
407
  wrong anchor — that red routes like any sidecar-side red below.
403
408
 
404
- **In pre-commit review OFF, run the verb on a clean tree.** The floor's owed set
405
- reads the diff against the anchor _including uncommitted work_ — correct in ON,
406
- where the group's work is uncommitted by design, but in OFF an uncommitted tracked
409
+ **In auto-commit ON, run the verb on a clean tree.** The floor's owed set
410
+ reads the diff against the anchor _including uncommitted work_ — correct in
411
+ auto-commit OFF, where the group's work is uncommitted by design, but in
412
+ auto-commit ON an uncommitted tracked
407
413
  edit outside `.claude/state` at validation time is a **human delta the Reviewer
408
414
  never saw**, and it would red the floor as `unaccounted-file` on a ledger that is
409
415
  not wrong. Check `git status --porcelain -- . ':(exclude).claude/state'` first; a
@@ -457,9 +463,9 @@ numbers still never shift. For each group, in order:
457
463
  the unresolved disagreement (both positions, the spec slice) instead of a clean
458
464
  step.
459
465
 
460
- In pre-commit review ON, `OK` is also the moment the group's single code commit
466
+ In auto-commit OFF, `OK` is also the moment the group's single code commit
461
467
  lands, and `changes` sends the fresh Implementer to iterate **over the worktree**
462
- — both per §Pre-commit review ON.
468
+ — both per §Auto-commit OFF.
463
469
 
464
470
  3. **Human checkpoint** — first run §Checkpoint contract's **spec check** (item
465
471
  4): the state commit below sweeps `spec/`, so an unconfirmed human spec edit
@@ -486,8 +492,8 @@ numbers still never shift. For each group, in order:
486
492
  A failed push — offline, auth — warns and never blocks; the next push carries
487
493
  it. This long wait is where a session likeliest dies — the push is what lets
488
494
  another machine's `/resume` see the pending checkpoint.
489
- **Pre-commit review ON skips this state commit and push entirely** — until the
490
- OK the branch receives _nothing_, state included (§Pre-commit review ON): update
495
+ **Auto-commit OFF skips this state commit and push entirely** — until the
496
+ OK the branch receives _nothing_, state included (§Auto-commit OFF): update
491
497
  the `progress.md` line on disk only, accepting the documented price that the
492
498
  pending checkpoint is invisible to a cold `/resume` from another machine.
493
499
  Then present the step **per §Checkpoint contract**: what was built and how to
@@ -508,7 +514,7 @@ numbers still never shift. For each group, in order:
508
514
  (`Mode: step-by-step (downgraded to all-at-once at step N)` — the gate choice
509
515
  stays first; the downgrade is a suffix, because `task_done.mode` records the gate
510
516
  choice), and run the **remaining** tasks as a single Implementer invocation
511
- (all-at-once; the pre-commit review knob keeps its recorded setting).
517
+ (all-at-once; the auto-commit knob keeps its recorded setting).
512
518
  Checkpoint OKs already given stand.
513
519
 
514
520
  Aborting needs no protocol: the human interrupts the session; `/resume` picks the
@@ -521,11 +527,11 @@ numbers still never shift. For each group, in order:
521
527
  `-- .claude/state/tasks/<id>/` pathspec as step 3's twin so other staged
522
528
  content never rides mislabeled) + best-effort push ride as
523
529
  **one composite turn** (§Turn economy) — without that commit a cold `/resume`
524
- still reads `awaiting` after the last group. Pre-commit review ON: on OK the
530
+ still reads `awaiting` after the last group. Auto-commit OFF: on OK the
525
531
  same composite additionally carries the group's **code commit** — the deferral
526
532
  ends here, so code commit + state commit + push + emit land together (exact
527
533
  commands, the pathspec split of the mixed index, and the all-at-once no-emit
528
- rule in §Pre-commit review ON); on
534
+ rule in §Auto-commit OFF); on
529
535
  `changes` nothing is committed and the deferral continues. `<review-iterations>` is the number
530
536
  of Reviewer invocations that preceded this checkpoint (≥ 1; resets after a
531
537
  "changes"):
@@ -557,7 +563,7 @@ numbers still never shift. For each group, in order:
557
563
 
558
564
  Per-step Reviewer REJECTs also emit `review_rejected` as usual, with the extra
559
565
  `--step=<N>` flag (the `iteration` count stays task-global, as today; an
560
- all-at-once single-group pass — pre-commit review ON's pre-gate review —
566
+ all-at-once single-group pass — auto-commit OFF's pre-gate review —
561
567
  omits `--step`, per the events schema).
562
568
 
563
569
  5. **`progress.md` step log** — keep the sub-state explicit so `/resume` can re-enter
@@ -593,24 +599,24 @@ checkpoint OK means "right direction and it runs", not a review waiver; the full
593
599
  wins, and the human still holds the merge gate to disagree.
594
600
 
595
601
  **Every full-pass APPROVE is ledger-validated too** — the step-8 review in either mode,
596
- pre-commit review ON's single-group pre-gate pass, and a re-APPROVE after the merge gate
602
+ auto-commit OFF's single-group pre-gate pass, and a re-APPROVE after the merge gate
597
603
  or PR comments sent the PR back to review. The Reviewer writes `full-pass.json` (no step
598
604
  number → the union of every group); you run
599
605
  `lemony review-ledger validate --task-id=<id> --anchor=<merge-base> --full-pass` —
600
606
  the merge-base of the freshly fetched base and the PR head, the Diff-fingerprint's
601
- own OID (L1 step 8; pre-commit review ON's pre-gate pass instead anchors at the OID
607
+ own OID (L1 step 8; auto-commit OFF's pre-gate pass instead anchors at the OID
602
608
  you recorded when its single group started) — and route a red exactly as
603
609
  in step 2 above: one fresh Reviewer retry with the lines verbatim, a second red or any
604
610
  spec-side problem to the human, and never an APPROVE relayed on a red ledger. Outside
605
611
  the step loop the transient line is `awaiting ledger retry (full pass, retry 1/1)` in
606
612
  `progress.md` (no step counter), and "the human" is the gate the pass feeds: the
607
- pre-commit-ON checkpoint when there is one, otherwise the merge-gate presentation,
613
+ auto-commit-OFF checkpoint when there is one, otherwise the merge-gate presentation,
608
614
  with the verb's lines as the content.
609
615
 
610
616
  ## Checkpoint contract (how a human gate presents work)
611
617
 
612
618
  Every human checkpoint — per-group in step-by-step, and the single all-at-once gate
613
- when pre-commit review is ON — presents the same way. "Present the step" is a
619
+ when auto-commit is OFF — presents the same way. "Present the step" is a
614
620
  contract, not a vibe:
615
621
 
616
622
  1. **Anchored scope.** The group's **anchor** — the branch head OID recorded when
@@ -620,10 +626,10 @@ contract, not a vibe:
620
626
  at the head after the last OK'd group) — bounds exactly what is
621
627
  under review. Present the commit list + touched-files table, then the **exact
622
628
  group diff**, always excluding task state:
623
- - OFF: `git log --oneline <anchor>..HEAD` +
629
+ - auto-commit ON: `git log --oneline <anchor>..HEAD` +
624
630
  `git diff --stat <anchor>..HEAD -- ':(exclude).claude/state'`,
625
631
  then `git diff <anchor>..HEAD -- ':(exclude).claude/state'`;
626
- - ON (nothing committed):
632
+ - auto-commit OFF (nothing committed):
627
633
  `git diff --stat <anchor> -- ':(exclude).claude/state'`, then
628
634
  `git diff <anchor> -- ':(exclude).claude/state'` — staged new files are in
629
635
  the index, so they appear.
@@ -631,13 +637,13 @@ contract, not a vibe:
631
637
  a difftool is configured (or an extension like GitLens is present), **offer**
632
638
  the richer side-by-side view — an ephemeral config works without touching the
633
639
  repo's (`git -c diff.tool=<tool> difftool <range>`). Never assume an extension
634
- exists. In ON the Source Control panel already shows the work natively — it IS
635
- uncommitted.
640
+ exists. In auto-commit OFF the Source Control panel already shows the work
641
+ natively — it IS uncommitted.
636
642
  3. **What was built and how to run it** — from the Implementer's verification line,
637
643
  as today. Checkpoint narration is the product, never overhead (§Turn economy).
638
644
  4. **The human delta — always detected, always revalidated.** Whatever the answer
639
- (`ok` or `changes: …`), first detect the human's own edits — in ON, **two
640
- checks with distinct routes** (every agent save-point is staged at
645
+ (`ok` or `changes: …`), first detect the human's own edits — in auto-commit
646
+ OFF, **two checks with distinct routes** (every agent save-point is staged at
641
647
  presentation time, so the staged/unstaged seam is the auto-detect):
642
648
  - **Work delta**: the unstaged section outside task state —
643
649
  `git diff -- ':(exclude).claude/state'` **plus untracked files outside
@@ -664,10 +670,10 @@ contract, not a vibe:
664
670
  recorded `**Resolution**` in `discoveries.md` is confirmed content — stage
665
671
  it, don't re-raise.
666
672
 
667
- The **spec check runs in both knob states** — in OFF, run it **before** step
668
- 3's `awaiting` state commit, which would otherwise silently commit a
669
- pre-existing spec edit before detection. OFF's work-delta detection is
670
- simply any uncommitted working-tree change.
673
+ The **spec check runs in both knob states** — in auto-commit ON, run it
674
+ **before** step 3's `awaiting` state commit, which would otherwise silently
675
+ commit a pre-existing spec edit before detection. Auto-commit ON's work-delta
676
+ detection is simply any uncommitted working-tree change.
671
677
  The **work delta** then runs the pipeline: present it, confirm it is
672
678
  intended, and **re-run the suite with the delta applied** — the delta never
673
679
  inherits the group's green. **A red revalidation blocks the OK**: never run
@@ -675,15 +681,16 @@ contract, not a vibe:
675
681
  `changes` (the human decides: fix it themselves, drop the delta, or hand it
676
682
  to the Implementer). On a green revalidation the delta rides with the group:
677
683
  on OK it lands with
678
- the group's work (ON: staged into the group's commit; OFF: committed as its
684
+ the group's work (auto-commit OFF: staged into the group's commit; auto-commit ON:
685
+ committed as its
679
686
  own commit — `step(<id>): step <N> human delta` — before the next group); on
680
687
  `changes` it stays in the worktree for
681
- the fresh Implementer (ON: staged first as the safe starting point —
682
- §Pre-commit review ON).
688
+ the fresh Implementer (auto-commit OFF: staged first as the safe starting point —
689
+ §Auto-commit OFF).
683
690
 
684
- ## Pre-commit review ON (zero commits + staging save-points)
691
+ ## Auto-commit OFF (zero commits + staging save-points)
685
692
 
686
- The knob's ON state (chosen at the approval gate — §Implementation mode) moves
693
+ The auto-commit OFF state (chosen at the approval gate — §Implementation mode) moves
687
694
  **when the branch first receives commits**; review, fix-loop routing, and the merge
688
695
  gate are unchanged. v1 is deliberately an experiment — the watch-fors below are its
689
696
  pre-registered exit signals.
@@ -716,8 +723,8 @@ pre-registered exit signals.
716
723
  line drops the step counter). Its APPROVE is ledger-validated with `--full-pass`
717
724
  and `--anchor=<oid>` — the anchor you recorded when its single group started
718
725
  (§Step-by-step implementation, after the last group), never relayed on a red.
719
- Hand that pre-gate Reviewer the anchor, the ON
720
- flag, and "the whole `tasks.md` as the single group" in place of a group id.
726
+ Hand that pre-gate Reviewer the anchor, the words `auto-commit is OFF`, and "the
727
+ whole `tasks.md` as the single group" in place of a group id.
721
728
  All agent work is
722
729
  staged at presentation time; present per §Checkpoint contract. The human
723
730
  inspects the work natively in the Source Control panel and edits/discards
@@ -749,7 +756,8 @@ pre-registered exit signals.
749
756
  `step(<id>): step <N> checkpoint OK`, and the `step_completed` emit rides the
750
757
  same turn (step 4). All-at-once (a downgraded remainder resolves as
751
758
  all-at-once here too): `<code-msg>` = `task(<id>): implementation`,
752
- `<state-msg>` = `task(<id>): pre-commit gate OK`, and **nothing is emitted** —
759
+ `<state-msg>` = `task(<id>): implementation checkpoint OK`, and **nothing is
760
+ emitted** —
753
761
  `step_completed` is step-by-step-only (its `--step` has no meaning here, and
754
762
  closeout's mode recovery reads any `step_completed` as proof of step-by-step);
755
763
  the gate resolution reaches telemetry through `task_done` as usual. One commit
@@ -193,7 +193,7 @@ offer to resume it (`/resume #<k-id>`) in this session. A k already merged
193
193
  a task branch (human-gated by house rules); merge is uglier history but safe. While k
194
194
  is unmerged the source is `origin/harness/<k-id>-<k-slug>`. The merge-in is **your**
195
195
  move at a checkpoint boundary (or the Implementer's on re-invoke, named in the spawn
196
- prompt), never inside a staging save-point; under pre-commit review ON it goes right
196
+ prompt), never inside a staging save-point; under auto-commit OFF it goes right
197
197
  after a checkpoint OK commit;
198
198
  - record it in the child's trace line (`stacked — assumes it lands as-is`) and the
199
199
  parent row (`→ #<id> spec-in-progress (stacked on #<k-id>)` — the status at opening,
@@ -243,7 +243,7 @@ mediation). On **"keep together"**: record the resolution and resume. On
243
243
  this order:
244
244
 
245
245
  1. **Ask the second half in the same mediation** — later-unit work already on the branch
246
- (commits; under pre-commit review ON, staged save-points): keep it or drop it? Name
246
+ (commits; under auto-commit OFF, staged save-points): keep it or drop it? Name
247
247
  the commits. (A second fork that only exists because of the first answer: record it in
248
248
  the same `**Resolution**` block, no second entry.)
249
249
  2. **Create the parent** partition-plan issue with the current task as Part 1 (row
@@ -258,7 +258,7 @@ this order:
258
258
  the narrowed `tasks.md` is re-presented at the next checkpoint — no new gate.
259
259
  5. **Record and resume**: the Implementer re-invoke carries the keep/drop answer — it
260
260
  performs the `git revert`s by commit (never a force-push), or discards the staged
261
- later-unit changes under pre-commit review ON — and resumes on the narrowed slice.
261
+ later-unit changes under auto-commit OFF — and resumes on the narrowed slice.
262
262
 
263
263
  On an **L2 (triage) task** — no PRD — "partition" means the task was mis-levelled: keep
264
264
  the triage on its first unit (you narrow its fix plan in the issue body, read-modify-write)
@@ -69,7 +69,7 @@ verbatim — the spinoff offer depends on it surviving.
69
69
  Every review of a spec-backed change that ends in an **APPROVE** writes a **ledger**: a
70
70
  JSON sidecar at `.claude/state/tasks/<id>/review-ledger/step-<N>.json` — or
71
71
  `full-pass.json` when the review has no step number (the all-at-once full pass, and
72
- pre-commit review ON's single-group pre-gate pass). You write the file yourself, beside
72
+ auto-commit OFF's single-group pre-gate pass). You write the file yourself, beside
73
73
  your verdict; it is the one artifact you write besides your `progress.md` evidence
74
74
  section, and the source under review stays untouched. A REJECT owes no ledger: nothing
75
75
  is being approved, and its failing points already ride your return in full. A task with
@@ -241,7 +241,7 @@ lemony review-ledger validate --task-id=<id> --anchor=<anchor> --step=<N>
241
241
  ```
242
242
 
243
243
  (`--full-pass` in place of `--step` on a full pass.) `<anchor>` is the anchor your
244
- invocation handed you (per-step, and pre-commit review ON's pre-gate pass); on the PR
244
+ invocation handed you (per-step, and auto-commit OFF's pre-gate pass); on the PR
245
245
  full pass it is the merge-base you already compute for the stale-approve record —
246
246
  `git merge-base FETCH_HEAD HEAD` after the fetch, the same OID the Diff-fingerprint
247
247
  digests from. The Orchestrator re-validates with the anchor **it** recorded, so a
@@ -257,7 +257,7 @@ The change is a PR (`harness/<id>-<slug> → default`) the Orchestrator opened;
257
257
  that PR's diff. Run your review skills in order — which ones you have depends on the
258
258
  repo's capabilities (see Skills below); run whichever landed.
259
259
 
260
- **Per-step review (step-by-step mode — and pre-commit review ON's all-at-once
260
+ **Per-step review (step-by-step mode — and auto-commit OFF's all-at-once
261
261
  pre-gate pass, where the whole implementation is the single group).** The
262
262
  Orchestrator may instead invoke you
263
263
  mid-implementation, scoped to **one `tasks.md` group of tasks** — handed **by
@@ -265,7 +265,7 @@ reference** (the group's id + header line): read the group's tasks and the
265
265
  requirements they reference from the spec files yourself. There is no PR yet —
266
266
  review the **group's diff on the branch against its slice of the spec** (the whole
267
267
  repo is your context; the verdict stays bounded to that slice). When the invocation
268
- says **pre-commit review is ON**, the group's work is **uncommitted by design**:
268
+ says **auto-commit is OFF**, the group's work is **uncommitted by design**:
269
269
  the diff is the group's uncommitted work against its anchor
270
270
  (`git diff <anchor> -- ':(exclude).claude/state'`, the anchor handed in your
271
271
  invocation; worktree == index within that scope at review time) — review it as
@@ -276,8 +276,8 @@ below, both in step 4: the verdict is **local** — return it in your summary fo
276
276
  your ledger is `step-<N>.json` (the pre-gate single group, which has no step number,
277
277
  writes `full-pass.json`) — and a
278
278
  REJECT's `review_rejected` emit carries the extra `--step=<N>` flag **only when the
279
- group is a step-by-step step** — an all-at-once single group (pre-commit review
280
- ON's pre-gate pass) omits `--step`, which the events schema defines as absent on
279
+ group is a step-by-step step** — an all-at-once single group (auto-commit
280
+ OFF's pre-gate pass) omits `--step`, which the events schema defines as absent on
281
281
  all-at-once rejections (`iteration` stays
282
282
  task-global). Cross-group interactions are the final full-pass's job, not this one's;
283
283
  that full-pass reviews everything as usual and may reject anything, including
@@ -50,8 +50,8 @@ A two-step pause:
50
50
 
51
51
  The hook prints `git status --porcelain` after emitting — it never
52
52
  auto-commits. Decide what (if anything) to stage and commit before leaving.
53
- Exception — a task running **pre-commit review ON** (orchestrator §Pre-commit
54
- review ON): do **not** commit; the zero-commit deferral binds `/pause` too.
53
+ Exception — a task running **auto-commit OFF** (orchestrator §Auto-commit
54
+ OFF): do **not** commit; the zero-commit deferral binds `/pause` too.
55
55
  Leave the staged save-point untouched (it survives the session; staging
56
56
  anything now is the mid-experiment `add` the protocol forbids), note the pause
57
57
  in `progress.md` — disk-only, per the mode's contract.
@@ -36,15 +36,16 @@ drop `harness:needs-design` and continue toward spec-ready. When `progress.md` r
36
36
  `Mode: step-by-step`, the `## Step log` carries the step sub-state — resume
37
37
  exactly there: `awaiting human checkpoint (step N/M)` re-presents that pending
38
38
  checkpoint (inspect / run / OK / changes / OK+downgrade; in all-at-once under
39
- pre-commit review ON the line carries no `(step N/M)` counter — same
39
+ auto-commit OFF the line carries no `(step N/M)` counter — same
40
40
  re-entry); a `fix-loop iteration K`
41
41
  line re-enters the per-step implement→review loop at that iteration; an
42
42
  `awaiting ledger retry (step N/M, retry 1/1)` line — or its full-pass twin
43
43
  `awaiting ledger retry (full pass, retry 1/1)` — re-runs
44
44
  `lemony review-ledger validate` on the sidecar on disk (`--anchor` per the
45
45
  orchestrator: per-step, the `(anchor <oid>)` on the step-log line; full pass, the
46
- fingerprint merge-base — except pre-commit review ON's pre-gate twin, which anchors
47
- at the recorded single-group anchor, = the branch head: ON defers every commit) —
46
+ fingerprint merge-base — except auto-commit OFF's pre-gate twin, which anchors
47
+ at the recorded single-group anchor, = the branch head: auto-commit OFF defers every
48
+ commit) —
48
49
  green re-presents the gate
49
50
  the pass feeds, red goes to that gate with the verb's lines, the single retry being spent
50
51
  (authority: the orchestrator §Step-by-step implementation). If the Mode line carries a
@@ -55,13 +56,13 @@ history, not sub-state).
55
56
  **Cross-machine pickup of an `in-progress` task**: the branch on origin
56
57
  carries the last **successful** best-effort WIP push — the Implementer pushes on
57
58
  signaling done, and step-by-step pushes at each checkpoint-wait. Exception: a task
58
- running **pre-commit review ON** defers every commit and push until a checkpoint OK
59
+ running **auto-commit OFF** defers every commit and push until a checkpoint OK
59
60
  — in-flight work and its `progress.md` updates exist only in the implementing
60
61
  machine's worktree, so from another machine the branch reads as of the last OK'd
61
62
  group; before the first OK it is **indistinguishable from idle** (the knob record
62
- itself is deferred — the documented price of the mode, orchestrator §Pre-commit
63
- review ON). When config pins `implementation.pre_commit_review: on`, or the
64
- branch's `progress.md` already carries the `Pre-commit review: on` line (some OK
63
+ itself is deferred — the documented price of the mode, orchestrator §Auto-commit
64
+ OFF). When config pins `implementation.auto_commit: off`, or the
65
+ branch's `progress.md` already carries the `Auto-commit: off` line (some OK
65
66
  landed), surface the mode instead of concluding the task is idle. A discovery
66
67
  pause still surfaces cross-machine via its labels and issue comment, though the
67
68
  full `discoveries.md` entry stays machine-local. If a **local** copy
@@ -114,7 +114,7 @@
114
114
  "default": {},
115
115
  "type": "object",
116
116
  "properties": {
117
- "pre_commit_review": {
117
+ "auto_commit": {
118
118
  "default": "human",
119
119
  "type": "string",
120
120
  "enum": [
@@ -130,9 +130,17 @@ if [ ! -x "$PEER_HOOK" ]; then
130
130
  WARNINGS+=("$PEER_HOOK is missing or not executable — \`/pause\` and SessionEnd telemetry will fail. Re-run \`lemony install\` (or chmod +x).")
131
131
  fi
132
132
 
133
- # ── Warning 3 ─ local branch behind origin (no fetch — uses existing refs) ─
133
+ # ── Warning 3 ─ default branch behind origin (no fetch — uses existing refs) ─
134
+ # Scoped to a session sitting ON the default branch: "pull before starting" is
135
+ # advice for main, and a task branch is behind origin/main by construction.
136
+ # The nudge used to fire branch-agnostic: mid-task under auto-commit OFF
137
+ # the worktree is dirty by design with the staged index as the save-point
138
+ # ladder, and following `git pull --rebase` with `rebase.autostash` set flattens
139
+ # that index — the documented rollback then reverts to the last commit and the
140
+ # group's whole uncommitted work is gone. So on any other branch: silence.
141
+ CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)"
134
142
  DEFAULT_BRANCH="$(git symbolic-ref --quiet refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')"
135
- if [ -n "$DEFAULT_BRANCH" ]; then
143
+ if [ -n "$DEFAULT_BRANCH" ] && [ "$CURRENT_BRANCH" = "$DEFAULT_BRANCH" ]; then
136
144
  BEHIND="$(git rev-list --count "HEAD..origin/$DEFAULT_BRANCH" 2>/dev/null || echo 0)"
137
145
  if [ "${BEHIND:-0}" -gt 0 ]; then
138
146
  WARNINGS+=("local branch is $BEHIND commit(s) behind origin/$DEFAULT_BRANCH. Consider \`git pull --rebase\` before starting.")
@@ -142,7 +150,6 @@ fi
142
150
  # ── Warning 4 ─ residual harness branches (parked tasks) ───────────────────
143
151
  STALE_BRANCHES="$(git for-each-ref --format='%(refname:short)' refs/heads/harness/ 2>/dev/null | wc -l | tr -d ' ')"
144
152
  if [ "${STALE_BRANCHES:-0}" -gt 0 ]; then
145
- CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)"
146
153
  case "$CURRENT_BRANCH" in
147
154
  harness/*) : ;;
148
155
  *) WARNINGS+=("$STALE_BRANCHES parked harness branch(es) present. Resume with \`continue <id>\` or close them with task-closeout.") ;;
@@ -87,10 +87,11 @@ A task deserves the harness if it is **specifiable**, **verifiable**, or
87
87
  7. **Implement** — Implementer sub-agent, `tdd` skill, on the branch, keeping
88
88
  `.claude/state/tasks/<id>/progress.md` live. The gate interaction settles two
89
89
  knobs, both recorded in `progress.md`: the **implementation mode** (all-at-once,
90
- or step-by-step with per-group human checkpoints) and **pre-commit review**
91
- (config `implementation.pre_commit_review`; ON = the human reviews the work
92
- **uncommitted** — zero commits until each checkpoint OK). Authority:
93
- orchestrator §Implementation mode / §Pre-commit review ON.
90
+ or step-by-step with per-group human checkpoints) and **auto-commit**
91
+ (config `implementation.auto_commit`; auto-commit OFF = zero commits the human
92
+ reviews the work **uncommitted** until each checkpoint OK; auto-commit ON =
93
+ commit-as-you-go).
94
+ Authority: orchestrator §Implementation mode / §Auto-commit OFF.
94
95
  8. **Review** — flip to `harness:status:in-review`, open the PR (`gh pr create`,
95
96
  branch → default), Reviewer sub-agent reviews it (`senior-review`, fresh context). If
96
97
  the task touched UI, the **UI Designer** reviews as a distinct design + a11y lens too
@@ -59,13 +59,17 @@ rollback:
59
59
  # allow_no_checks: false
60
60
 
61
61
  # Implementation-phase knobs the Orchestrator reads at the L1 approval gate.
62
- # pre_commit_reviewhuman review of the UNCOMMITTED work before anything is
63
- # committed (zero-commit mode): `human` (default) asks at the gate, in the same
64
- # interaction as the all-at-once / step-by-step choice, suggesting OFF (today's
65
- # commit-as-you-go flow); `on` / `off` pin the answer and skip the question
66
- # (bench/headless runs pin `off`). Bare on/off are strings here (YAML 1.2).
62
+ # auto_commitdoes the agent commit automatically as it works? `on`: the
63
+ # Implementer commits and pushes as it goes; `off`: zero commits the work
64
+ # accumulates in the worktree, you review it UNCOMMITTED (Source Control) and
65
+ # the branch gets its first commit on your OK (more control). `human` (default)
66
+ # asks at the gate, in the same interaction as the all-at-once / step-by-step
67
+ # choice, recommending OFF; `on` / `off` pin the answer and skip the question
68
+ # (a headless/bench run must pin `on`). Bare on/off are strings here (YAML 1.2).
69
+ # Replaces `pre_commit_review` (0.3.0, inverse polarity): the old key is
70
+ # tolerated and removed on the next config write; its value is not migrated.
67
71
  # implementation:
68
- # pre_commit_review: human
72
+ # auto_commit: human
69
73
 
70
74
  # Review gates. The mechanical gates a Reviewer must attest in its evidence
71
75
  # ledger, one entry per name, beyond the always-required real run — a flat list of
package/dist/cli.mjs CHANGED
@@ -23,18 +23,22 @@ const DEPRECATED_PATHS_KEYS = [
23
23
  "skills",
24
24
  "agents"
25
25
  ];
26
+ const DEPRECATED_IMPLEMENTATION_KEYS = ["pre_commit_review"];
26
27
  const HARNESS_CONFIG_SCHEMA_FILENAME = "harness.config.schema.json";
27
- const CONFIG_KEY_SINCE = { gates: "0.3.0" };
28
+ const CONFIG_KEY_SINCE = {
29
+ gates: "0.3.0",
30
+ "implementation.auto_commit": "0.4.0"
31
+ };
28
32
  const TASK_STORAGE_REPO_PLACEHOLDER = "OWNER/REPO";
29
33
  const TARGETS = ["claude-code"];
30
34
  const TASK_STORAGE_TYPES = ["github"];
31
35
  const TASK_STORAGE_REPO_PATTERN = /^[^\s/]+\/[^\s/]+$/;
32
- const PRE_COMMIT_REVIEW_MODES = [
36
+ const AUTO_COMMIT_MODES = [
33
37
  "human",
34
38
  "on",
35
39
  "off"
36
40
  ];
37
- const PRE_COMMIT_REVIEW_DEFAULT = "human";
41
+ const AUTO_COMMIT_DEFAULT = "human";
38
42
  const VENDOR_VERSION_REGEX = /^\d+\.\d+\.\d+(-(alpha|beta|rc)\.\d+)?$/;
39
43
  const VENDOR_VERSION_EXAMPLE = "0.1.0-alpha.0";
40
44
  const PATHS_DEFAULTS = {
@@ -121,7 +125,7 @@ const mergeSchema = z.object({
121
125
  checks_timeout_secs: z.int().positive().default(600),
122
126
  allow_no_checks: z.boolean().default(false)
123
127
  }).strict().prefault({});
124
- const implementationSchema = z.object({ pre_commit_review: z.enum(PRE_COMMIT_REVIEW_MODES).default(PRE_COMMIT_REVIEW_DEFAULT) }).strict().prefault({});
128
+ const implementationSchema = z.object({ auto_commit: z.enum(AUTO_COMMIT_MODES).default(AUTO_COMMIT_DEFAULT) }).strict().prefault({});
125
129
  const gatesSchema = z.array(z.string().trim().min(1)).optional();
126
130
  const harnessConfigSchema = z.object({
127
131
  vendor_version: z.string().regex(VENDOR_VERSION_REGEX),
@@ -161,6 +165,12 @@ const readHarnessConfig = async (repoRoot) => {
161
165
  for (const key of DEPRECATED_PATHS_KEYS) delete pathsCandidate[key];
162
166
  candidate.paths = pathsCandidate;
163
167
  }
168
+ const implementation = candidate.implementation;
169
+ if (implementation && typeof implementation === "object" && !Array.isArray(implementation)) {
170
+ const implementationCandidate = { ...implementation };
171
+ for (const key of DEPRECATED_IMPLEMENTATION_KEYS) delete implementationCandidate[key];
172
+ candidate.implementation = implementationCandidate;
173
+ }
164
174
  const result = harnessConfigSchema.safeParse(candidate);
165
175
  if (!result.success) throw new Error(`${HARNESS_CONFIG_FILENAME} is invalid:\n${formatConfigError(harnessConfigSchema, result.error)}`);
166
176
  return result.data;
@@ -222,6 +232,7 @@ const setConfigValues = (rawYaml, updates) => {
222
232
  for (const key of DEPRECATED_PATHS_KEYS) if (doc.hasIn(["paths", key])) doc.deleteIn(["paths", key]);
223
233
  const pathsNode = doc.get("paths", true);
224
234
  if (isMap(pathsNode) && pathsNode.items.length === 0) doc.delete("paths");
235
+ for (const key of DEPRECATED_IMPLEMENTATION_KEYS) if (doc.hasIn(["implementation", key])) doc.deleteIn(["implementation", key]);
225
236
  return doc.toString();
226
237
  };
227
238
  const writeConfigValues = async (repoRoot, updates) => {
@@ -5840,7 +5851,7 @@ const reviewLedgerValidate = async (args) => {
5840
5851
  if (taskId === void 0) throw new Error(`${REVIEW_LEDGER_USAGE} --task-id is required.`);
5841
5852
  if (taskId !== basename(taskId) || taskId === "." || taskId === "..") throw new Error(`Invalid --task-id="${taskId}": a task id names one directory under the task state, never a path.`);
5842
5853
  const anchor = parseFlag(args, "anchor");
5843
- if (anchor === void 0) throw new Error(`${REVIEW_LEDGER_USAGE} --anchor is required — the group's recorded head OID on a step, the fingerprint merge-base on a full pass (pre-commit review ON's pre-gate pass anchors at the recorded group anchor instead); the owed set of the mutant floor is the diff from it.`);
5854
+ if (anchor === void 0) throw new Error(`${REVIEW_LEDGER_USAGE} --anchor is required — the group's recorded head OID on a step, the fingerprint merge-base on a full pass (auto-commit OFF's pre-gate pass anchors at the recorded group anchor instead); the owed set of the mutant floor is the diff from it.`);
5844
5855
  const address = parseLedgerAddress(args);
5845
5856
  const result = await runLedgerValidate({
5846
5857
  repoRoot: cwd(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lemoncode/lemony",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Lemony — a Harness for AI Coding. Vendor package: installer, agent role catalog, generic skill catalog, hooks, and templates for a Spec-Driven Development workflow.",
5
5
  "type": "module",
6
6
  "private": false,