peaks-loop 3.1.0 → 3.1.2

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.
@@ -0,0 +1,60 @@
1
+ # Peaks-Loop Solo — Step 0.8 (v3.1.1 + v3.1.2) Gate Deep-Dive
2
+
3
+ > Read alongside `SKILL.md` Step 0.8. The SKILL.md header is the LOCKED CONTRACT; this file is the mechanics.
4
+
5
+ ## Recorder contract (`peaks solo detect-job`)
6
+
7
+ The CLI does NOT judge whether the request is Job-shaped — that is the LLM's job. Keyword regexes are wrong here (too brittle, miss natural-language variants, shift the LLM's semantic understanding into code). The CLI is a **recorder and gate**: the LLM makes the judgement, writes it via `peaks solo detect-job`, and downstream steps refuse to proceed until the decision file exists.
8
+
9
+ ### LLM judgement criteria (read once, then call the recorder)
10
+
11
+ - N parallel targets (`app/components/*`, `app/modules/*`, `for each subdir`, "以目录为维度", "把剩下的也跑了").
12
+ - Completion phrase implying batch continuation (`until all done`, "继续执行下个 slice", "全部添加完", "all of them").
13
+ - Cost / length disavowal (`不用考虑费用`, "don't worry about cost", "一直跑").
14
+ - Explicit slice count (`25 slices`, "切分成 N 段", "拆成 N 块").
15
+
16
+ ### Action sequence
17
+
18
+ 1. LLM reads the user prompt and applies judgement → `isJob: boolean + rationale + suggestedJobId + suggestedStrategy + confidence`.
19
+ 2. LLM calls `peaks solo detect-job --is-job <bool> --rationale <text> --suggested-job-id <jid> --suggested-strategy <single|rotating> --confidence <high|medium|low> [--force]`.
20
+ 3. CLI records to `.peaks/_runtime/<sessionId>/job-shape.json`.
21
+ 4. If `isJob: true` → `peaks job init --job-id <jid> --slice-list <...> --main-loop-strategy <strategy> --rotate-every 3` (BEFORE Step 1).
22
+ 5. Downstream steps (Step 1, Step 0.81, etc.) call `read-job-shape` to refuse if missing.
23
+
24
+ ### Hard rule (v3.1.1 red-line #10)
25
+
26
+ LLM MUST NOT skip `peaks solo detect-job` even when the trigger is obvious from context. If the next step's `read-job-shape` throws `JOB_SHAPE_NOT_DECIDED`, Solo MUST record a decision before proceeding. Keyword-based "I already know it's a Job" is not a substitute.
27
+
28
+ ## v3.1.2 mechanical gates
29
+
30
+ The recorder-only design was bypassed twice under load; the gate must be un-bypassable.
31
+
32
+ ### 1. PreToolUse hook — `peaks solo gate-step-08`
33
+
34
+ `peaks workspace init` installs the `Bash` matcher `peaks solo gate-step-08 --project .` in `.claude/settings.local.json` (alongside the existing Write|Edit|MultiEdit matcher). The hook runs before every Bash call:
35
+
36
+ | Condition | Exit | Behaviour |
37
+ |---|---|---|
38
+ | `job-shape.json` exists | 0 (allow) | allow + emit decision; if `progress.json` exists, add `Next: slice #N+1 of M (<currentSlice>)` |
39
+ | `job-shape.json` missing AND prompt matches the fail-closed backup regex | 2 (BLOCKED) | LLM must call `peaks solo detect-job` before retrying |
40
+ | `job-shape.json` missing AND no regex match | 0 (allow) | allow, no Job trigger |
41
+
42
+ ### 2. Size-fear ban — `peaks solo emit-handoff`
43
+
44
+ Refuses to emit a final handoff while `remaining > 0` under Job mode. Pass `--force-under-job` only with explicit user approval.
45
+
46
+ ### 3. Forced auto-compact — `--enforce-job-mode`
47
+
48
+ `peaks solo context-now --enforce-job-mode` (auto-enabled when `job-shape.json` says `isJob=true`) returns `action: 'auto-compact-now'` at ≥ 0.85; Solo MUST call `peaks session auto-compact --execute` without confirmation.
49
+
50
+ ### 4. On-disk slice progress — `progress.json`
51
+
52
+ `peaks job checkpoint --state done` writes `progress.json`. `peaks job progress --job-id <jid> [--allow-missing]` is the canonical reader; `peaks solo gate-step-08` also surfaces it on every Bash call so the LLM cannot "wake up cold".
53
+
54
+ ## Backup regex rationale
55
+
56
+ The fail-closed backup regex (mentioned above) exists so the gate has defense in depth: even if the recorder's downstream enforcement is bypassed, the hook catches obvious Job-shaped prompts. The regex is intentionally narrow — it MUST miss benign prompts and MUST hit obvious batches — so the LLM-side judgement remains primary.
57
+
58
+ ## Hook wiring
59
+
60
+ `peaks workspace init` writes both matchers (Bash + Write|Edit|MultiEdit) atomically; if either fails the whole init fails. `peaks workspace init --remove-hooks` reverses both. The Bash matcher is required for Step 0.8; the Write|Edit|MultiEdit matcher pre-existed (Step 0 [Fact-Forcing Gate]).