peaks-loop 4.0.5 → 4.0.7
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 +320 -0
- package/dist/cli/commands/code-job-shape-commands.js +11 -8
- package/dist/cli/commands/code-mode-gate-commands.js +43 -1
- package/dist/cli/commands/code-runtime-commands.js +11 -6
- package/dist/cli/commands/core/standards-command.js +50 -5
- package/dist/cli/commands/dispatch-commands.js +39 -3
- package/dist/cli/commands/hooks-commands.js +26 -9
- package/dist/cli/commands/sub-agent-commands.js +2 -0
- package/dist/cli/commands/sub-agent-exec-command.d.ts +25 -0
- package/dist/cli/commands/sub-agent-exec-command.js +132 -0
- package/dist/cli/commands/sub-agent-shared.d.ts +11 -0
- package/dist/services/audit/backing-detector.d.ts +19 -2
- package/dist/services/audit/backing-detector.js +66 -7
- package/dist/services/audit/enforcers/lint-audit-regression.js +10 -1
- package/dist/services/context/build-dispatch-system-prompt.js +18 -0
- package/dist/services/dispatch/test-tool-detection.d.ts +14 -0
- package/dist/services/dispatch/test-tool-detection.js +22 -0
- package/dist/services/scan/archetype-service.js +52 -2
- package/dist/services/session/index.d.ts +1 -1
- package/dist/services/session/index.js +1 -1
- package/dist/services/session/session-manager.d.ts +29 -0
- package/dist/services/session/session-manager.js +33 -0
- package/dist/services/skills/hooks-settings-service.d.ts +41 -0
- package/dist/services/skills/hooks-settings-service.js +61 -5
- package/dist/services/slice/slice-check-service.js +59 -0
- package/dist/services/standards/find-skills-integration.d.ts +59 -0
- package/dist/services/standards/find-skills-integration.js +225 -0
- package/dist/services/standards/project-standards-service.js +44 -0
- package/package.json +4 -4
- package/scripts/install-skills.mjs +171 -0
- package/skills/peaks-code/SKILL.md +43 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peaks-loop",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.7",
|
|
4
4
|
"description": "Loop Engineering CLI — workflow primitive / loop guards / evaluators / slice orchestration",
|
|
5
5
|
"author": "SquabbyZ",
|
|
6
6
|
"keywords": [
|
|
@@ -98,9 +98,9 @@
|
|
|
98
98
|
"headroom-ai": "0.22.4",
|
|
99
99
|
"yaml": "^2.9.0",
|
|
100
100
|
"zod": "^3.25.76",
|
|
101
|
-
"peaks-loop-
|
|
102
|
-
"peaks-loop-shared": "0.0.
|
|
103
|
-
"peaks-loop-
|
|
101
|
+
"peaks-loop-shared-channel": "0.0.16",
|
|
102
|
+
"peaks-loop-shared": "0.0.37",
|
|
103
|
+
"peaks-loop-mut": "0.1.12"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
106
|
"@alibaba-group/open-code-review": "1.3.1"
|
|
@@ -762,6 +762,143 @@ export function installBundledOutputStyles(options = {}) {
|
|
|
762
762
|
return { installed, skipped };
|
|
763
763
|
}
|
|
764
764
|
|
|
765
|
+
/**
|
|
766
|
+
* Slice 2026-08-02 — auto-register bundled output style.
|
|
767
|
+
*
|
|
768
|
+
* Real user feedback (2026-08-02): `npm i -g peaks-loop@latest` on a
|
|
769
|
+
* fresh 0-1 project copied `peaks-skill-swarm.md` into
|
|
770
|
+
* `~/.claude/output-styles/` but never wrote
|
|
771
|
+
* `outputStyle: 'peaks-skill-swarm'` into `~/.claude/settings.json`.
|
|
772
|
+
* Result: Claude Code loaded no Peaks output style in new sessions.
|
|
773
|
+
*
|
|
774
|
+
* The fix: when `peaks-skill-swarm.md` is present in the bundled output
|
|
775
|
+
* styles directory AND `~/.claude/settings.json` does NOT yet declare
|
|
776
|
+
* `outputStyle`, merge in `outputStyle: 'peaks-skill-swarm'` while
|
|
777
|
+
* preserving every other key. If the user already set `outputStyle`,
|
|
778
|
+
* leave it alone — the user is the source of truth.
|
|
779
|
+
*
|
|
780
|
+
* Resolution precedence:
|
|
781
|
+
* 1. options.settingsFile (explicit override / test hook)
|
|
782
|
+
* 2. PEAKS_CLAUDE_SETTINGS_FILE env var (CI override)
|
|
783
|
+
* 3. homedir-relative `<homedir>/.claude/settings.json` (default)
|
|
784
|
+
*
|
|
785
|
+
* Soft-fail contract: every error path (missing file, malformed JSON,
|
|
786
|
+
* missing bundled style file, permission denied) is logged to stderr
|
|
787
|
+
* and returns `{ skipped: true, ... }` instead of throwing. The
|
|
788
|
+
* postinstall must never fail on this step because the bundled file
|
|
789
|
+
* itself was already written successfully.
|
|
790
|
+
*/
|
|
791
|
+
function resolveSettingsFilePath(options = {}) {
|
|
792
|
+
if (typeof options.settingsFile === 'string' && options.settingsFile.length > 0) {
|
|
793
|
+
return resolve(options.settingsFile);
|
|
794
|
+
}
|
|
795
|
+
const envOverride = process.env.PEAKS_CLAUDE_SETTINGS_FILE;
|
|
796
|
+
if (typeof envOverride === 'string' && envOverride.length > 0) {
|
|
797
|
+
return resolve(envOverride);
|
|
798
|
+
}
|
|
799
|
+
return resolve(homedir(), '.claude', 'settings.json');
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
export function installBundledOutputStyleDefault(options = {}) {
|
|
803
|
+
if (process.env.PEAKS_SKIP_SKILL_INSTALL === '1' || process.env.PEAKS_SKIP_OUTPUT_STYLE_DEFAULT === '1') {
|
|
804
|
+
return { skipped: true, reason: 'PEAKS_SKIP_OUTPUT_STYLE_DEFAULT=1' };
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
const bundledStylesDir = resolve(
|
|
808
|
+
options.targetRoot
|
|
809
|
+
?? process.env.PEAKS_CLAUDE_OUTPUT_STYLES_DIR
|
|
810
|
+
?? join(homedir(), '.claude', 'output-styles')
|
|
811
|
+
);
|
|
812
|
+
const settingsPath = resolveSettingsFilePath(options);
|
|
813
|
+
const bundledStyleName = 'peaks-skill-swarm.md';
|
|
814
|
+
const bundledStylePath = join(bundledStylesDir, bundledStyleName);
|
|
815
|
+
|
|
816
|
+
// Read the existing settings.json (if any) FIRST so a malformed file
|
|
817
|
+
// surfaces as a parse error (more actionable to the user than the
|
|
818
|
+
// generic "bundled style not present" message). Malformed JSON is a
|
|
819
|
+
// user-authored file we MUST NOT clobber — log and skip.
|
|
820
|
+
let existing = null;
|
|
821
|
+
if (existsSync(settingsPath)) {
|
|
822
|
+
const stats = getPathStats(settingsPath);
|
|
823
|
+
if (!stats || !stats.isFile() || stats.isSymbolicLink() || stats.nlink !== 1) {
|
|
824
|
+
process.stderr.write(
|
|
825
|
+
`peaks install-skills: refusing to overwrite non-regular settings.json at ${settingsPath}\n`
|
|
826
|
+
);
|
|
827
|
+
return { skipped: true, reason: 'settings.json is not a regular file' };
|
|
828
|
+
}
|
|
829
|
+
try {
|
|
830
|
+
const raw = readFileSafely(settingsPath, 'Claude settings.json path changed during read');
|
|
831
|
+
const parsed = JSON.parse(raw);
|
|
832
|
+
if (!isPlainObject(parsed)) {
|
|
833
|
+
process.stderr.write(
|
|
834
|
+
`peaks install-skills: refusing to overwrite settings.json that is not a JSON object at ${settingsPath}\n`
|
|
835
|
+
);
|
|
836
|
+
return { skipped: true, reason: 'settings.json is not a JSON object' };
|
|
837
|
+
}
|
|
838
|
+
existing = parsed;
|
|
839
|
+
} catch (error) {
|
|
840
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
841
|
+
process.stderr.write(
|
|
842
|
+
`peaks install-skills: failed to parse settings.json at ${settingsPath}: ${message}; leaving untouched\n`
|
|
843
|
+
);
|
|
844
|
+
return { skipped: true, reason: 'settings.json parse error' };
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Pre-condition: the bundled style file must be present in the
|
|
849
|
+
// dispatched target. If it's not, we MUST NOT inject
|
|
850
|
+
// `outputStyle: 'peaks-skill-swarm'` — Claude Code would then fail
|
|
851
|
+
// to load the style and fall back to default anyway, leaving the
|
|
852
|
+
// user with broken state. Skipping is the safe default.
|
|
853
|
+
if (!existsSync(bundledStylePath)) {
|
|
854
|
+
return { skipped: true, reason: `bundled output style not present at ${bundledStylePath}` };
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// User-authored outputStyle wins — never overwrite.
|
|
858
|
+
if (existing !== null && typeof existing.outputStyle === 'string' && existing.outputStyle.length > 0) {
|
|
859
|
+
return { skipped: true, reason: `user-defined outputStyle already set: ${existing.outputStyle}` };
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const next = existing === null
|
|
863
|
+
? { outputStyle: 'peaks-skill-swarm' }
|
|
864
|
+
: { ...existing, outputStyle: 'peaks-skill-swarm' };
|
|
865
|
+
|
|
866
|
+
const existingJson = existing === null ? null : `${JSON.stringify(existing, null, 2)}\n`;
|
|
867
|
+
const nextJson = `${JSON.stringify(next, null, 2)}\n`;
|
|
868
|
+
if (existingJson === nextJson) {
|
|
869
|
+
return { skipped: true, reason: 'no change' };
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
try {
|
|
873
|
+
writeFileAtomically(
|
|
874
|
+
settingsPath,
|
|
875
|
+
nextJson,
|
|
876
|
+
'Claude settings.json path changed during write',
|
|
877
|
+
() => {
|
|
878
|
+
if (!existsSync(settingsPath)) return;
|
|
879
|
+
const stats = getPathStats(settingsPath);
|
|
880
|
+
if (!stats || !stats.isFile() || stats.isSymbolicLink() || stats.nlink !== 1) {
|
|
881
|
+
throw new Error('Claude settings.json path is not a regular file');
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
);
|
|
885
|
+
} catch (error) {
|
|
886
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
887
|
+
process.stderr.write(
|
|
888
|
+
`peaks install-skills: failed to write settings.json at ${settingsPath}: ${message}\n`
|
|
889
|
+
);
|
|
890
|
+
return { skipped: true, reason: 'write error', error: message };
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
return {
|
|
894
|
+
installed: true,
|
|
895
|
+
created: existing === null,
|
|
896
|
+
updated: existing !== null,
|
|
897
|
+
settingsPath,
|
|
898
|
+
outputStyle: 'peaks-skill-swarm',
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
|
|
765
902
|
/**
|
|
766
903
|
* Slice 7/7 — bundled agents (Claude Code sub-agent prompts).
|
|
767
904
|
*
|
|
@@ -1205,6 +1342,40 @@ if (process.argv[1] !== undefined && import.meta.url === pathToFileURL(resolve(p
|
|
|
1205
1342
|
if (outputStylesResult.skipped.length > 0) {
|
|
1206
1343
|
process.stderr.write(`Peaks output styles skipped because local files already exist: ${outputStylesResult.skipped.join(', ')}\n`);
|
|
1207
1344
|
}
|
|
1345
|
+
|
|
1346
|
+
// Slice 2026-08-02 — auto-register bundled output style.
|
|
1347
|
+
//
|
|
1348
|
+
// After the bundled style file lands in `~/.claude/output-styles/`,
|
|
1349
|
+
// we also need Claude Code to actually USE it — otherwise the user
|
|
1350
|
+
// (real feedback 2026-08-02: fresh 0-1 project like
|
|
1351
|
+
// `Desktop\ticket-cross`) sees the default style in new sessions.
|
|
1352
|
+
//
|
|
1353
|
+
// This step reads `~/.claude/settings.json`, and only if the user
|
|
1354
|
+
// hasn't set `outputStyle` yet, writes
|
|
1355
|
+
// `outputStyle: 'peaks-skill-swarm'` while preserving every other
|
|
1356
|
+
// key. Malformed settings.json / IO errors / non-regular files are
|
|
1357
|
+
// soft-failed to stderr (the bundled file is already on disk, so
|
|
1358
|
+
// postinstall never aborts here).
|
|
1359
|
+
//
|
|
1360
|
+
// The `targetRoot` here mirrors the dispatch target of
|
|
1361
|
+
// `installBundledOutputStyles()` above so the env-var override
|
|
1362
|
+
// path (test fixtures + CI) stays consistent: if the bundled
|
|
1363
|
+
// style file was dispatched to an env-overridden dir, the
|
|
1364
|
+
// auto-register step checks THAT dir, not the user's homedir.
|
|
1365
|
+
try {
|
|
1366
|
+
const dispatchTargetRoot = process.env.PEAKS_CLAUDE_OUTPUT_STYLES_DIR
|
|
1367
|
+
?? join(homedir(), '.claude', 'output-styles');
|
|
1368
|
+
const styleDefaultResult = installBundledOutputStyleDefault({ targetRoot: dispatchTargetRoot });
|
|
1369
|
+
if (styleDefaultResult.installed) {
|
|
1370
|
+
process.stdout.write(
|
|
1371
|
+
`Peaks output style auto-registered: ${styleDefaultResult.outputStyle}\n` +
|
|
1372
|
+
` → wrote ${styleDefaultResult.settingsPath}\n`
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
} catch (error) {
|
|
1376
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1377
|
+
process.stderr.write(`Peaks output style default was not installed: ${message}\n`);
|
|
1378
|
+
}
|
|
1208
1379
|
if (userConfigResult.created) {
|
|
1209
1380
|
process.stdout.write('Peaks user config created: ~/.peaks/config.json\n');
|
|
1210
1381
|
}
|
|
@@ -63,6 +63,41 @@ This skill is the **primary surface**. The `peaks <cmd>` CLI is **auxiliary**
|
|
|
63
63
|
|
|
64
64
|
When 24h mode is active and an in-flight sub-agent batch is detected, the LLM MAY persist its current turn context to disk through the `session spill-demo` helper. Creates a `SpillRecord` in `.peaks/_runtime/<sessionId>/spill/`. Round-trip is idempotent; existing in-flight deferral still works without spill/hydrate. **Opt-in experimental** — not required.
|
|
65
65
|
|
|
66
|
+
## 24h mode explicit scope (slice 4.0.7-PR-meta-2, locked 2026-08-02)
|
|
67
|
+
|
|
68
|
+
The 4.0.7 dogfood pass on `ice-cola` surfaced a flow-level bug: 24h mode's "no AskUserQuestion" intent was over-extended by the LLM to **all** user instructions, including the Code-Change Red Line (the prose-only rule "you MUST NOT edit application source directly without going through peaks-rd"). The LLM routed 22 files / 632 lines of `Edit` calls straight through without a single `peaks sub-agent dispatch rd`. The fix below makes the scope explicit so future LLM sessions cannot make the same over-extension.
|
|
69
|
+
|
|
70
|
+
### What 24h mode BYPASSES (the AskUserQuestion gates)
|
|
71
|
+
|
|
72
|
+
24h mode is `peaks session 24h-mode transition --state 24H_ACTIVE`. Once active, the LLM MAY auto-proceed (recommended = chosen) at the following `peaks-code` steps without an AskUserQuestion:
|
|
73
|
+
|
|
74
|
+
- `step-0.5-openspec-opt-in` — OpenSpec opt-in
|
|
75
|
+
- `step-0.6-audit-goal` — audit + goal confirmation
|
|
76
|
+
- `step-0.7-resume-detection` — resume vs new-work
|
|
77
|
+
- `step-0.55-1x-upgrade` — 1.x → 2.0 upgrade detection (still surfaces the gate at the moment-of-impact, but does not pause to ASK)
|
|
78
|
+
- `step-1-mode-select` — full-auto / assisted / strict / swarm mode pick
|
|
79
|
+
- `step-2.5-session-title` — human-readable session title
|
|
80
|
+
- `phase-2-prd-confirm` — PRD's `Goals / Non-goals / Acceptance criteria` confirm (24h mode picks a recommended set; user can still reject post-hoc via the verdict loop)
|
|
81
|
+
- `phase-3-swarm-gate-b` — swarm selection (full-auto recommended; 24h mode skips the AskUserQuestion but still records the choice)
|
|
82
|
+
- `phase-6-qa-gate-d` — QA verdict gate (24h mode auto-proceeds; the verdict log is the audit trail)
|
|
83
|
+
- `phase-10-txt-memory-extract` — Step 11 memory sediment (24h mode auto-runs the extract)
|
|
84
|
+
- `step-n+1-final-review` — final review (24h mode auto-fires the 4-dim review; user can still inspect the artifact post-hoc)
|
|
85
|
+
|
|
86
|
+
### What 24h mode DOES NOT BYPASS (the hard rules)
|
|
87
|
+
|
|
88
|
+
24h mode is **only** a "no AskUserQuestion" override. It is NOT a "skip the entire peaks-code flow" override. The following peaks-code rules are **always** enforced under 24h mode:
|
|
89
|
+
|
|
90
|
+
- **Code-Change Red Line** (prose rule + slice 4.0.7-PR-meta-1 Edit-enforcement hook). Every code change goes through `peaks-code → peaks-rd → peaks-qa → verdict`. The LLM MUST NOT edit `src/**` directly. Use `peaks sub-agent dispatch rd`.
|
|
91
|
+
- **Sub-agent dispatch** for non-trivial work. Even in 24h mode, the LLM is not exempt from dispatching `peaks-rd` / `peaks-qa`. The `--apply` flag in 24h mode picks the recommended option in the dispatch envelope, but the dispatch still happens (slice 4.0.7-PR-meta-4).
|
|
92
|
+
- **Worktree authorization** (slice 2026-07-29-worktree-layer3-deny). 24h mode does NOT widen Layer 3's deny list. The 3-layer governance (L1 prose + L2 hook + L3 IDE permissions.deny) remains in force.
|
|
93
|
+
- **Request state machine transitions** (`spec-locked → implemented → qa-handoff → handed-off`). 24h mode is not a state-machine bypass.
|
|
94
|
+
- **External side effects** (`git push`, `git tag`, `npm publish`, `npm install -g peaks-loop`, `peaks global install`). The 5 commit-boundary hard-floor actions always pause, even in 24h mode.
|
|
95
|
+
- **Reverse 2.x → 1.x migration**, **git reset --hard**, **force-push to protected branches**. Same hard-floor logic.
|
|
96
|
+
|
|
97
|
+
### The single-sentence rule (paste into any new peaks-code session that flips 24h mode)
|
|
98
|
+
|
|
99
|
+
> 24h mode lets the LLM auto-proceed at the AskUserQuestion gates (mode select, step confirm, swarm pick, etc.). It does **not** let the LLM skip the peaks-code 11-step flow, edit `src/**` directly, or bypass request-state transitions.
|
|
100
|
+
|
|
66
101
|
## Peaks-Loop Superpowers 协作边界 (BRIDGE — MANDATORY, effective 2026-07-24)
|
|
67
102
|
|
|
68
103
|
Pins the boundary between `peaks-code` and the **superpowers** skill family (`brainstorming`, `writing-plans`, `executing-plans`, `subagent-driven-development`, `dispatching-parallel-agents`, `verification-before-completion`, `test-driven-development`, `systematic-debugging`, `requesting-code-review`, `receiving-code-review`, `using-superpowers`, `using-git-worktrees`, `finishing-a-development-branch`). Closed under slice 2026-07-24-peaks-code-bridge-002-rootcause.
|
|
@@ -114,7 +149,7 @@ Full content extracted to **`references/startup-sequence.md`** (Steps 0 / 0.5-0.
|
|
|
114
149
|
| `0.85 ≤ ratio < 0.95` | **pre-compact zone** | `peaks compact auto --execute` fires **automatically** (deferred only when in-flight sub-agent batch is running; fires the moment the batch lands). The LLM does not prompt the user. |
|
|
115
150
|
| `ratio ≥ 0.95` | **red-line (Karpathy §4)** | synchronous gate — `peaks compact auto --execute` invoked immediately; `peaks code context-now` returns `action: 'red-line'` and refuses to advance until ratio drops below 0.85. **Karpathy §4 automatic exception** — LLM cannot opt out. |
|
|
116
151
|
|
|
117
|
-
**Probe primitive (single source of truth):** `peaks code context-now --json
|
|
152
|
+
**Probe primitive (single source of truth):** `peaks code context-now --json --project <path>`. Do NOT use `peaks context check --prompt-size` (deprecated, will silently under-report ratio). Returns `{ ratio, action: 'ok' | 'soft-warn' | 'auto-compact-now' | 'red-line' }` — Code reads `action` and dispatches `peaks compact auto --execute` on `auto-compact-now` or `red-line` without user confirmation. **Always pass `--project` explicitly** — the CLI does not auto-resolve cwd (see Drift Index D-013).
|
|
118
153
|
|
|
119
154
|
**Enforcement layers (defense in depth):**
|
|
120
155
|
1. `src/services/code/auto-compact-orchestrator.ts` — `evaluateAutoCompactDecision` default-returns `shouldCompact: true` for both `pre-compact` and `red-line`. Only deferral is `inFlightBatch.hasInFlightBatch` (D6.e); no LLM/human approval branch.
|
|
@@ -127,18 +162,21 @@ Full content extracted to **`references/startup-sequence.md`** (Steps 0 / 0.5-0.
|
|
|
127
162
|
|
|
128
163
|
If the prose audit (`peaks audit red-lines`) flags any of the above, the slice is **blocked** until the prose is rewritten.
|
|
129
164
|
|
|
130
|
-
## CLI Drift Index (sediment 2026-07-09)
|
|
165
|
+
## CLI Drift Index (sediment 2026-07-09, refreshed 2026-08-02)
|
|
131
166
|
|
|
132
|
-
> **Reading guide:** Verified against peaks-loop 4.0.
|
|
167
|
+
> **Reading guide:** Verified against peaks-loop 4.0.6. Each drift below is annotated inline at the relevant step with a `> CLI reality check`. On `error: unknown option ...`, **read the inline reality check first** before guessing. The 4.0.7 dogfood pass (ice-cola surface probe) re-validated all entries; D-001 was rewritten (the pre-4.0.7 entry was the inverse of 4.0.6's actual behavior).
|
|
133
168
|
|
|
134
169
|
| Drift ID | Step | Symptom | Fix | Inline location |
|
|
135
170
|
|---|---|---|---|---|
|
|
136
|
-
| **D-001** | 0.8 | `peaks code detect-job --is-job ...` rejected
|
|
171
|
+
| **D-001** | 0.8 | `peaks code detect-job --is-job ...` requires the flag (4.0.6+); pre-4.0.6 the flag was rejected. Either way, you must pass `--is-job <bool> --rationale <text> --suggested-job-id <slug>` | `peaks code detect-job --is-job <true\|false> --rationale "<1-3 sentences>" --suggested-job-id <slug>` | §Step 0.8 first paragraph |
|
|
137
172
|
| **D-002** | 2.5 | `peaks session title --session-id <sid> ...` rejected with `error: unknown option '--session-id'` (this is the bare `<sid>` anti-pattern) | sid is positional: `peaks session title <sessionId> "<title>" --json` | §Step 2.5 |
|
|
138
173
|
| **D-003** | 0.8 | `JOB_SHAPE_NOT_DECIDED` exception expected but never thrown | Current behavior is `peaks job status` reports `done: 0` passively — treat as recoverable miss, not hard error | §Step 0.8 third paragraph |
|
|
139
174
|
| **D-010** | 11c | `peaks memory extract` returns `extractedCount: 0` despite `<!-- peaks-memory:start -->` existing | Block requires YAML frontmatter (`title:` + `kind:` + `---`) + closing `<!-- peaks-memory:end -->`. Bare `peaks-memory:start` is parsed silently but produces no writes | §Step 11c + 11d |
|
|
175
|
+
| **D-013** | N+2 | `peaks code context-now --json` (no `--project`) rejected with `error: required option '--project <path>' not specified` | Always pass `--project <path>` (use `.` for the cwd). The CLI does not auto-resolve cwd because monorepos + CI have surprising cwd semantics. | §Step N+2 probe primitive |
|
|
176
|
+
| **D-014** | 0.8 | `peaks code detect-job` / `read-job-shape` / `peaks workflow plan read --type <type>` / `peaks route --goal <g>` all reported `NO_ACTIVE_SESSION` even when `.peaks/_runtime/session.json` was a valid binding. The 4 CLIs read `getSkillPresence` (the `.peaks/.active-skill.json` file, set only by `peaks skill presence:set <skill>`) instead of the canonical binding. Fixed in 4.0.7 PR-2 via `resolveActiveSessionId` shared resolver — no action required at the call site, but if you see a `NO_ACTIVE_SESSION` error, run `peaks workspace init --project <path>` first. | §Step 0.8 third paragraph + §Step 1 mode select |
|
|
177
|
+
| **D-015** | 0.8 | `peaks code should-pause --step step-1-mode-select` reports `stale-presence: no-presence` even when 24h-mode is active. 24h-mode never sets skill presence by design (no sub-skill flips). Fixed in 4.0.7 PR-3 — gate short-circuits the stale-presence check when `24h-state.json#state === '24H_ACTIVE'`. | §Step 1 mode select + §24h mode |
|
|
140
178
|
|
|
141
|
-
> **Sediment lesson (master record):** `.peaks/memory/peaks-code-runbook-4-0-0-beta-6-skill-md-cli-d-001-d-002-d-003-d-010.md`
|
|
179
|
+
> **Sediment lesson (master record):** `.peaks/memory/peaks-code-runbook-4-0-0-beta-6-skill-md-cli-d-001-d-002-d-003-d-010.md` (pre-4.0.7); `.peaks/memory/2026-08-02-ice-cola-dogfood-surface-probe.md` (4.0.7 fixes).
|
|
142
180
|
|
|
143
181
|
## Peaks-Loop GStack integration
|
|
144
182
|
|