peaks-loop 4.0.46 → 4.0.48
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 +54 -0
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/agents/karpathy-reviewer.md +11 -10
- package/dist/cli/cli-helpers.d.ts +34 -0
- package/dist/cli/cli-helpers.js +57 -0
- package/dist/cli/commands/code-job-shape-commands.js +8 -0
- package/dist/cli/commands/code-runtime-commands.d.ts +22 -0
- package/dist/cli/commands/code-runtime-commands.js +139 -16
- package/dist/cli/commands/compact-command.js +241 -1
- package/dist/cli/commands/config-commands.js +15 -9
- package/dist/cli/commands/container-commands.js +3 -3
- package/dist/cli/commands/core/skill-command.js +45 -10
- package/dist/cli/commands/cron-commands.js +2 -1
- package/dist/cli/commands/dashboard-long-run.js +6 -0
- package/dist/cli/commands/dispatch-commands.js +11 -1
- package/dist/cli/commands/doctor/invoke-from-code.js +6 -0
- package/dist/cli/commands/e2e-verify.js +3 -3
- package/dist/cli/commands/governance-classify-contract-commands.js +1 -0
- package/dist/cli/commands/hooks-commands.js +14 -5
- package/dist/cli/commands/job-commands.js +8 -0
- package/dist/cli/commands/loop-commands.js +1 -0
- package/dist/cli/commands/loop-eval-commands.js +15 -0
- package/dist/cli/commands/perf-audit-commands.js +2 -0
- package/dist/cli/commands/playwright-commands.js +14 -1
- package/dist/cli/commands/prd-commands.js +1 -1
- package/dist/cli/commands/qa-commands.js +22 -0
- package/dist/cli/commands/reinject-command.d.ts +72 -0
- package/dist/cli/commands/reinject-command.js +174 -0
- package/dist/cli/commands/request-commands.js +14 -3
- package/dist/cli/commands/scan-commands.js +1 -1
- package/dist/cli/commands/security-audit-commands.js +2 -0
- package/dist/cli/commands/shadcn-commands.js +1 -0
- package/dist/cli/commands/slice-integrate-commands.js +5 -0
- package/dist/cli/commands/statusline-commands.js +44 -4
- package/dist/cli/commands/sub-agent/detached.d.ts +14 -1
- package/dist/cli/commands/sub-agent/detached.js +47 -22
- package/dist/cli/commands/sub-agent-shutdown-commands.js +11 -0
- package/dist/cli/commands/test-commands.js +2 -1
- package/dist/cli/commands/verdict-aggregate-command.js +95 -13
- package/dist/cli/commands/vm-commands.js +7 -7
- package/dist/cli/commands/workflow-commands.js +1 -1
- package/dist/cli/commands/workspace/init-command.js +24 -2
- package/dist/cli/commands/worktree-lease-commands.js +4 -4
- package/dist/cli/index.js +10 -3
- package/dist/cli/program.js +5 -0
- package/dist/hooks/pre-tool-use-sub-agent.js +1 -1
- package/dist/services/adapter/adapter-registry.js +1 -1
- package/dist/services/artifacts/artifact-prerequisites.d.ts +38 -7
- package/dist/services/artifacts/artifact-prerequisites.js +130 -65
- package/dist/services/artifacts/artifact-service.js +1 -1
- package/dist/services/artifacts/request-artifact-service.d.ts +8 -0
- package/dist/services/artifacts/request-artifact-service.js +18 -8
- package/dist/services/artifacts/request-artifact-state-helpers.d.ts +57 -0
- package/dist/services/artifacts/request-artifact-state-helpers.js +91 -10
- package/dist/services/audit-independent/perf-audit-service.d.ts +9 -0
- package/dist/services/audit-independent/perf-audit-service.js +27 -5
- package/dist/services/audit-independent/security-audit-service.d.ts +12 -2
- package/dist/services/audit-independent/security-audit-service.js +28 -6
- package/dist/services/capability-guard-runner/contracts/J01.js +2 -1
- package/dist/services/capability-guard-runner/contracts/J02.js +3 -3
- package/dist/services/capability-guard-runner/contracts/J04.js +4 -2
- package/dist/services/capability-guard-runner/contracts/J07.js +2 -1
- package/dist/services/code/auto-compact-lifecycle.d.ts +130 -1
- package/dist/services/code/auto-compact-lifecycle.js +180 -4
- package/dist/services/code/auto-compact-orchestrator.d.ts +53 -9
- package/dist/services/code/auto-compact-orchestrator.js +166 -34
- package/dist/services/code/compact-event-settle.d.ts +122 -0
- package/dist/services/code/compact-event-settle.js +219 -0
- package/dist/services/code/orchestrator-can-do.d.ts +4 -2
- package/dist/services/code/orchestrator-can-do.js +37 -5
- package/dist/services/codegraph/codegraph-exclude-reconciler.js +2 -1
- package/dist/services/codegraph/codegraph-process-runner.js +3 -2
- package/dist/services/compact/request-transition-hook.js +5 -2
- package/dist/services/compact-history/compact-history-service.d.ts +75 -0
- package/dist/services/compact-history/compact-history-service.js +49 -0
- package/dist/services/config/config-restore.d.ts +12 -1
- package/dist/services/config/config-restore.js +35 -4
- package/dist/services/config/config-rollback.js +6 -1
- package/dist/services/config/config-safety.d.ts +52 -0
- package/dist/services/config/config-safety.js +75 -1
- package/dist/services/context/auto-compact-dispatcher.d.ts +7 -37
- package/dist/services/context/auto-compact-dispatcher.js +113 -40
- package/dist/services/context/auto-compact-reader.d.ts +68 -28
- package/dist/services/context/auto-compact-reader.js +155 -1
- package/dist/services/context/auto-compact-types.d.ts +89 -12
- package/dist/services/context/auto-compact-types.js +16 -32
- package/dist/services/context/harness-context-witness.d.ts +310 -0
- package/dist/services/context/harness-context-witness.js +606 -0
- package/dist/services/context/harness-window-config.d.ts +412 -0
- package/dist/services/context/harness-window-config.js +607 -0
- package/dist/services/context/main-session-monitor.d.ts +27 -0
- package/dist/services/context/main-session-monitor.js +32 -1
- package/dist/services/context/post-compact-reinjection.d.ts +221 -0
- package/dist/services/context/post-compact-reinjection.js +491 -0
- package/dist/services/dispatch/merge-back-runner.js +5 -5
- package/dist/services/dispatch/service-shutdown.js +3 -3
- package/dist/services/doc/doc-generator.js +2 -1
- package/dist/services/env/shell-probe.js +1 -1
- package/dist/services/evidence/evidence-generator.js +86 -49
- package/dist/services/final-review/final-review-service.d.ts +9 -0
- package/dist/services/final-review/final-review-service.js +36 -12
- package/dist/services/fuzzy-matching/fzf-pick-service.js +2 -0
- package/dist/services/hooks/auto-compact-hook-install.d.ts +10 -2
- package/dist/services/hooks/auto-compact-hook-install.js +8 -0
- package/dist/services/ide/adapters/claude-code-adapter.d.ts +107 -3
- package/dist/services/ide/adapters/claude-code-adapter.js +154 -7
- package/dist/services/ide/ide-registry.d.ts +31 -0
- package/dist/services/ide/ide-registry.js +35 -0
- package/dist/services/ide/ide-types.d.ts +59 -0
- package/dist/services/job/job-state-store.js +7 -0
- package/dist/services/lint/detect-eslint.js +2 -2
- package/dist/services/lint/eslint-runner.js +3 -1
- package/dist/services/loop/evaluator-dispatcher.js +2 -1
- package/dist/services/memory/project-memory-service/index/kind-dispatch.js +1 -1
- package/dist/services/memory/project-memory-service/store/paths.d.ts +9 -1
- package/dist/services/memory/project-memory-service/store/paths.js +15 -6
- package/dist/services/polyrepo/polyrepo-dispatcher.js +11 -0
- package/dist/services/prd/best-practice-auto-trigger.js +1 -0
- package/dist/services/prd/handoff-auto-regen.js +31 -27
- package/dist/services/prd/handoff-frontmatter.d.ts +44 -0
- package/dist/services/prd/handoff-frontmatter.js +75 -0
- package/dist/services/prd/handoff-service.d.ts +41 -2
- package/dist/services/prd/handoff-service.js +81 -8
- package/dist/services/prd/handoff-types.d.ts +3 -2
- package/dist/services/prd/handoff-types.js +3 -2
- package/dist/services/qa/qa-business-review-state.js +9 -0
- package/dist/services/release/version-precheck-service.d.ts +2 -1
- package/dist/services/release/version-precheck-service.js +82 -12
- package/dist/services/runtime/vendor-adapter.d.ts +29 -4
- package/dist/services/runtime/vendors/claude-code.js +1 -1
- package/dist/services/runtime/vendors/codex.js +1 -1
- package/dist/services/runtime/vendors/copilot.js +1 -1
- package/dist/services/sc/sc-service.js +1 -1
- package/dist/services/scan/diff-scope-service.js +2 -2
- package/dist/services/scan/file-size-scan.js +2 -2
- package/dist/services/scan/karpathy-service.js +2 -2
- package/dist/services/scan/orphan-service.js +2 -1
- package/dist/services/scan/type-sanity-service.js +2 -2
- package/dist/services/session/session-checkpoint-service.js +8 -0
- package/dist/services/skill/resume-detector.js +29 -11
- package/dist/services/skillhub/tar-runtime.js +1 -0
- package/dist/services/skills/hooks-codegate-superpowers.d.ts +14 -0
- package/dist/services/skills/hooks-codegate-superpowers.js +99 -3
- package/dist/services/skills/hooks-settings-service.d.ts +12 -0
- package/dist/services/skills/hooks-settings-service.js +91 -14
- package/dist/services/skills/session-start-hook-constants.d.ts +86 -0
- package/dist/services/skills/session-start-hook-constants.js +86 -0
- package/dist/services/skills/skill-presence-service.js +9 -0
- package/dist/services/skills/skill-statusline-service.d.ts +14 -0
- package/dist/services/slice/slice-check-service.js +31 -12
- package/dist/services/slice/slice-decompose-runners.js +2 -1
- package/dist/services/slice/slice-review-state.js +8 -0
- package/dist/services/upgrade/upgrade-service.js +1 -0
- package/dist/services/workflow/pipeline-verify-gate-support.d.ts +47 -10
- package/dist/services/workflow/pipeline-verify-gate-support.js +212 -93
- package/dist/services/workflow/pipeline-verify-service.js +24 -23
- package/dist/services/workflow/pipeline-verify-types.d.ts +10 -3
- package/dist/services/workflow/workflow-skip-service.js +2 -1
- package/dist/services/workspace/claude-settings-template.d.ts +56 -8
- package/dist/services/workspace/claude-settings-template.js +98 -20
- package/dist/services/workspace/migrate-service.js +1 -1
- package/dist/services/workspace/workspace-claude-settings-materializer.js +124 -9
- package/dist/services/workspace/workspace-service.js +8 -0
- package/dist/services/worktree/host-worktree-reconciler.js +1 -0
- package/dist/services/worktree/long-path-cleanup.js +3 -2
- package/dist/shared/process.js +1 -1
- package/package.json +6 -6
- package/scripts/install-skills.mjs +1 -0
- package/scripts/watch.mjs +3 -1
- package/skills/bee/peaks-perf-audit/SKILL.md +1 -1
- package/skills/bee/peaks-prd/SKILL.md +8 -6
- package/skills/bee/peaks-qa/SKILL.md +7 -7
- package/skills/bee/peaks-qa/references/qa-runbook.md +2 -2
- package/skills/bee/peaks-qa/references/qa-transition-gates.md +7 -7
- package/skills/bee/peaks-rd/SKILL.md +10 -8
- package/skills/bee/peaks-rd/references/artifact-per-request.md +2 -2
- package/skills/bee/peaks-rd/references/parallel-review-fanout.md +7 -5
- package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +13 -13
- package/skills/bee/peaks-rd/references/rd-runbook.md +9 -5
- package/skills/bee/peaks-rd/references/rd-transition-gates.md +9 -7
- package/skills/bee/peaks-rd/references/writing-handoff-frontmatter.md +6 -6
- package/skills/bee/peaks-reviewer/SKILL.md +1 -1
- package/skills/bee/peaks-sc/SKILL.md +1 -1
- package/skills/bee/peaks-security-audit/SKILL.md +1 -1
- package/skills/bee/peaks-txt/SKILL.md +1 -1
- package/skills/bee/peaks-ui/SKILL.md +1 -1
- package/skills/peaks-audit/SKILL.md +1 -1
- package/skills/peaks-code/SKILL.md +3 -3
- package/skills/peaks-code/references/a2a-artifact-mapping.md +3 -3
- package/skills/peaks-code/references/local-artifact-workspace.md +1 -1
- package/skills/peaks-code/references/resume-detection.md +13 -7
- package/skills/peaks-code/references/runbook.md +3 -2
- package/skills/peaks-code/references/session-overload-signal-index.md +2 -1
- package/skills/peaks-code/references/sub-agent-dispatch.md +1 -1
- package/skills/peaks-code/references/workflow-gates-and-types.md +8 -6
- package/skills/peaks-content/SKILL.md +1 -1
- package/skills/peaks-doctor/SKILL.md +1 -1
- package/skills/peaks-final-review/SKILL.md +1 -1
- package/skills/peaks-ide/SKILL.md +1 -1
- package/skills/peaks-issue-fix-orchestrator/SKILL.md +1 -1
- package/skills/peaks-resume/SKILL.md +1 -1
- package/skills/peaks-slice-decompose/SKILL.md +1 -1
- package/skills/peaks-solo/SKILL.md +1 -1
- package/skills/peaks-sop/SKILL.md +1 -1
- package/skills/peaks-status/SKILL.md +1 -1
- package/skills/peaks-test/SKILL.md +1 -1
|
@@ -25,6 +25,47 @@
|
|
|
25
25
|
*/
|
|
26
26
|
/** Sentinel substring identifying a SessionStart outer-cache hook entry. */
|
|
27
27
|
export declare const HOOK_OUTER_CACHE_SENTINEL = "peaks outer-cache write";
|
|
28
|
+
/**
|
|
29
|
+
* rid `2026-09-13-a2-post-compact-reinject` — SessionStart entry scoped to
|
|
30
|
+
* `matcher: 'compact'` that puts the engineering state back into the context
|
|
31
|
+
* a compaction just emptied.
|
|
32
|
+
*
|
|
33
|
+
* This is the official mechanism, and the `matcher` is the load-bearing part
|
|
34
|
+
* of it: Claude Code adds a `SessionStart` hook's plain-text stdout to the
|
|
35
|
+
* context, and scoping to `compact` means the card is re-injected AFTER a
|
|
36
|
+
* compaction rather than on every fresh session. Compaction itself cannot be
|
|
37
|
+
* initiated from here — the harness performs it, and a hook can only observe
|
|
38
|
+
* or veto. Re-injection is the half that IS available to us.
|
|
39
|
+
*
|
|
40
|
+
* Why a separate entry instead of folding this into the `peaks session
|
|
41
|
+
* primer` entry that already runs on every SessionStart: the primer's own
|
|
42
|
+
* contract is "rotation + presence cleanup", it fires on `startup` too (where
|
|
43
|
+
* the dispatch context is still in the history and the card would be noise),
|
|
44
|
+
* and its output is a rotation envelope rather than an engineering-state
|
|
45
|
+
* card. Two entries, two intents — each one's output means exactly one thing.
|
|
46
|
+
*/
|
|
47
|
+
export declare const HOOK_POST_COMPACT_REINJECT_SENTINEL = "peaks session reinject";
|
|
48
|
+
/**
|
|
49
|
+
* The reinject hook command. `--project "${CLAUDE_PROJECT_DIR}"` matches the
|
|
50
|
+
* other two SessionStart entries: `${CLAUDE_PROJECT_DIR}` is Claude Code's
|
|
51
|
+
* standard project-root convention, and the CLI resolves it strictly (a
|
|
52
|
+
* SessionStart payload is env-driven and must not be trusted as a path).
|
|
53
|
+
*
|
|
54
|
+
* `--quiet-failure` is NOT a flag and deliberately so: printing nothing on
|
|
55
|
+
* failure is this command's unconditional behaviour, not something a caller
|
|
56
|
+
* opts into. See `reinject-command.ts` — stdout IS context here, so an error
|
|
57
|
+
* message on stdout would be injected into the model's context as though
|
|
58
|
+
* peaks-loop meant it.
|
|
59
|
+
*/
|
|
60
|
+
export declare const HOOK_POST_COMPACT_REINJECT_COMMAND = "peaks session reinject --project \"${CLAUDE_PROJECT_DIR}\"";
|
|
61
|
+
/** SessionStart hook event key (same as outer-cache + primer). */
|
|
62
|
+
export declare const HOOK_POST_COMPACT_REINJECT_EVENT = "SessionStart";
|
|
63
|
+
/**
|
|
64
|
+
* The SessionStart `source` value the re-injection is scoped to. Claude Code
|
|
65
|
+
* reports `compact` as the SessionStart source when the session is resuming
|
|
66
|
+
* from a compaction; the hook entry's `matcher` is matched against it.
|
|
67
|
+
*/
|
|
68
|
+
export declare const HOOK_POST_COMPACT_REINJECT_MATCHER = "compact";
|
|
28
69
|
/** Default (claude-code) SessionStart hook command. */
|
|
29
70
|
export declare const HOOK_OUTER_CACHE_COMMAND = "peaks outer-cache write --project \"${CLAUDE_PROJECT_DIR}\"";
|
|
30
71
|
/** SessionStart hook event key for Claude Code. */
|
|
@@ -42,3 +83,48 @@ export declare const HOOK_WORKSPACE_INIT_SENTINEL = "peaks session primer";
|
|
|
42
83
|
export declare const HOOK_WORKSPACE_INIT_COMMAND = "peaks session primer --project \"${CLAUDE_PROJECT_DIR}\"";
|
|
43
84
|
/** SessionStart hook event key (same as outer-cache). */
|
|
44
85
|
export declare const HOOK_WORKSPACE_INIT_EVENT = "SessionStart";
|
|
86
|
+
/**
|
|
87
|
+
* rid `2026-09-13-compact-event-settle` — the `PostCompact` entry that lets the
|
|
88
|
+
* harness's own event settle a compact, instead of the next `context-now` probe
|
|
89
|
+
* inferring one from a ratio that fell.
|
|
90
|
+
*
|
|
91
|
+
* WHY THIS ENTRY IS NOT A `SessionStart` ONE, despite living in this file: the
|
|
92
|
+
* three entries above all ride `SessionStart` and differ only by matcher. A
|
|
93
|
+
* `PostCompact` hook is a different EVENT that carries the one fact no
|
|
94
|
+
* `SessionStart` payload has — whether the compaction the harness just
|
|
95
|
+
* completed was `auto` or `manual`. That distinction is the whole question
|
|
96
|
+
* ("has this machine ever auto-compacted?"), and without it peaks-loop can only
|
|
97
|
+
* ever see that SOMETHING compacted. See `compact-event-settle.ts` for what the
|
|
98
|
+
* command does with it.
|
|
99
|
+
*
|
|
100
|
+
* WHY THE MATCHER IS THE EMPTY STRING and not the documented `auto|manual`:
|
|
101
|
+
* both trigger values are wanted, so the matcher must filter nothing. An empty
|
|
102
|
+
* matcher is the convention the three `SessionStart` entries already rely on to
|
|
103
|
+
* match every source, and it is the only form that cannot fail SILENTLY — an
|
|
104
|
+
* alternation string is a match-everything pattern under regex semantics but
|
|
105
|
+
* matches NEITHER value under exact-equality semantics, and a hook that never
|
|
106
|
+
* fires looks exactly like a hook with nothing to report.
|
|
107
|
+
*/
|
|
108
|
+
export declare const HOOK_COMPACT_SETTLE_SENTINEL = "peaks compact settle";
|
|
109
|
+
/**
|
|
110
|
+
* The settle hook command. `--project "${CLAUDE_PROJECT_DIR}"` is byte-for-byte
|
|
111
|
+
* the shape of the three `SessionStart` entries above — Claude Code's standard
|
|
112
|
+
* project-root convention, resolved strictly on the CLI side (a hook payload is
|
|
113
|
+
* env-driven and must not be trusted as a path).
|
|
114
|
+
*
|
|
115
|
+
* The command prints NOTHING on the hook path and exits 0 for every outcome.
|
|
116
|
+
* `PostCompact`'s stdin/stdout contract is truncated in the retrievable docs,
|
|
117
|
+
* so the safe assumption is the `SessionStart` one — stdout may be added to the
|
|
118
|
+
* model's context. An error message there would be read as a fact. See
|
|
119
|
+
* `compact-event-settle.ts`.
|
|
120
|
+
*
|
|
121
|
+
* No `shell` pin, deliberately: this entry lands in the shared, committed
|
|
122
|
+
* `.claude/settings.json`, and a `powershell` pin there would break every
|
|
123
|
+
* macOS / Linux reader of the file. See `resolveHookEntries`' comment block for
|
|
124
|
+
* the full reason the three `SessionStart` entries are unpinned too.
|
|
125
|
+
*/
|
|
126
|
+
export declare const HOOK_COMPACT_SETTLE_COMMAND = "peaks compact settle --project \"${CLAUDE_PROJECT_DIR}\"";
|
|
127
|
+
/** The event this entry rides. Claude Code fires it after a compaction completes. */
|
|
128
|
+
export declare const HOOK_COMPACT_SETTLE_EVENT = "PostCompact";
|
|
129
|
+
/** Matcher: empty = every `trigger` (`auto` and `manual`). See the sentinel doc. */
|
|
130
|
+
export declare const HOOK_COMPACT_SETTLE_MATCHER = "";
|
|
@@ -25,6 +25,47 @@
|
|
|
25
25
|
*/
|
|
26
26
|
/** Sentinel substring identifying a SessionStart outer-cache hook entry. */
|
|
27
27
|
export const HOOK_OUTER_CACHE_SENTINEL = 'peaks outer-cache write';
|
|
28
|
+
/**
|
|
29
|
+
* rid `2026-09-13-a2-post-compact-reinject` — SessionStart entry scoped to
|
|
30
|
+
* `matcher: 'compact'` that puts the engineering state back into the context
|
|
31
|
+
* a compaction just emptied.
|
|
32
|
+
*
|
|
33
|
+
* This is the official mechanism, and the `matcher` is the load-bearing part
|
|
34
|
+
* of it: Claude Code adds a `SessionStart` hook's plain-text stdout to the
|
|
35
|
+
* context, and scoping to `compact` means the card is re-injected AFTER a
|
|
36
|
+
* compaction rather than on every fresh session. Compaction itself cannot be
|
|
37
|
+
* initiated from here — the harness performs it, and a hook can only observe
|
|
38
|
+
* or veto. Re-injection is the half that IS available to us.
|
|
39
|
+
*
|
|
40
|
+
* Why a separate entry instead of folding this into the `peaks session
|
|
41
|
+
* primer` entry that already runs on every SessionStart: the primer's own
|
|
42
|
+
* contract is "rotation + presence cleanup", it fires on `startup` too (where
|
|
43
|
+
* the dispatch context is still in the history and the card would be noise),
|
|
44
|
+
* and its output is a rotation envelope rather than an engineering-state
|
|
45
|
+
* card. Two entries, two intents — each one's output means exactly one thing.
|
|
46
|
+
*/
|
|
47
|
+
export const HOOK_POST_COMPACT_REINJECT_SENTINEL = 'peaks session reinject';
|
|
48
|
+
/**
|
|
49
|
+
* The reinject hook command. `--project "${CLAUDE_PROJECT_DIR}"` matches the
|
|
50
|
+
* other two SessionStart entries: `${CLAUDE_PROJECT_DIR}` is Claude Code's
|
|
51
|
+
* standard project-root convention, and the CLI resolves it strictly (a
|
|
52
|
+
* SessionStart payload is env-driven and must not be trusted as a path).
|
|
53
|
+
*
|
|
54
|
+
* `--quiet-failure` is NOT a flag and deliberately so: printing nothing on
|
|
55
|
+
* failure is this command's unconditional behaviour, not something a caller
|
|
56
|
+
* opts into. See `reinject-command.ts` — stdout IS context here, so an error
|
|
57
|
+
* message on stdout would be injected into the model's context as though
|
|
58
|
+
* peaks-loop meant it.
|
|
59
|
+
*/
|
|
60
|
+
export const HOOK_POST_COMPACT_REINJECT_COMMAND = `peaks session reinject --project "\${CLAUDE_PROJECT_DIR}"`;
|
|
61
|
+
/** SessionStart hook event key (same as outer-cache + primer). */
|
|
62
|
+
export const HOOK_POST_COMPACT_REINJECT_EVENT = 'SessionStart';
|
|
63
|
+
/**
|
|
64
|
+
* The SessionStart `source` value the re-injection is scoped to. Claude Code
|
|
65
|
+
* reports `compact` as the SessionStart source when the session is resuming
|
|
66
|
+
* from a compaction; the hook entry's `matcher` is matched against it.
|
|
67
|
+
*/
|
|
68
|
+
export const HOOK_POST_COMPACT_REINJECT_MATCHER = 'compact';
|
|
28
69
|
/** Default (claude-code) SessionStart hook command. */
|
|
29
70
|
export const HOOK_OUTER_CACHE_COMMAND = `peaks outer-cache write --project "\${CLAUDE_PROJECT_DIR}"`;
|
|
30
71
|
/** SessionStart hook event key for Claude Code. */
|
|
@@ -42,3 +83,48 @@ export const HOOK_WORKSPACE_INIT_SENTINEL = 'peaks session primer';
|
|
|
42
83
|
export const HOOK_WORKSPACE_INIT_COMMAND = `peaks session primer --project "\${CLAUDE_PROJECT_DIR}"`;
|
|
43
84
|
/** SessionStart hook event key (same as outer-cache). */
|
|
44
85
|
export const HOOK_WORKSPACE_INIT_EVENT = 'SessionStart';
|
|
86
|
+
/**
|
|
87
|
+
* rid `2026-09-13-compact-event-settle` — the `PostCompact` entry that lets the
|
|
88
|
+
* harness's own event settle a compact, instead of the next `context-now` probe
|
|
89
|
+
* inferring one from a ratio that fell.
|
|
90
|
+
*
|
|
91
|
+
* WHY THIS ENTRY IS NOT A `SessionStart` ONE, despite living in this file: the
|
|
92
|
+
* three entries above all ride `SessionStart` and differ only by matcher. A
|
|
93
|
+
* `PostCompact` hook is a different EVENT that carries the one fact no
|
|
94
|
+
* `SessionStart` payload has — whether the compaction the harness just
|
|
95
|
+
* completed was `auto` or `manual`. That distinction is the whole question
|
|
96
|
+
* ("has this machine ever auto-compacted?"), and without it peaks-loop can only
|
|
97
|
+
* ever see that SOMETHING compacted. See `compact-event-settle.ts` for what the
|
|
98
|
+
* command does with it.
|
|
99
|
+
*
|
|
100
|
+
* WHY THE MATCHER IS THE EMPTY STRING and not the documented `auto|manual`:
|
|
101
|
+
* both trigger values are wanted, so the matcher must filter nothing. An empty
|
|
102
|
+
* matcher is the convention the three `SessionStart` entries already rely on to
|
|
103
|
+
* match every source, and it is the only form that cannot fail SILENTLY — an
|
|
104
|
+
* alternation string is a match-everything pattern under regex semantics but
|
|
105
|
+
* matches NEITHER value under exact-equality semantics, and a hook that never
|
|
106
|
+
* fires looks exactly like a hook with nothing to report.
|
|
107
|
+
*/
|
|
108
|
+
export const HOOK_COMPACT_SETTLE_SENTINEL = 'peaks compact settle';
|
|
109
|
+
/**
|
|
110
|
+
* The settle hook command. `--project "${CLAUDE_PROJECT_DIR}"` is byte-for-byte
|
|
111
|
+
* the shape of the three `SessionStart` entries above — Claude Code's standard
|
|
112
|
+
* project-root convention, resolved strictly on the CLI side (a hook payload is
|
|
113
|
+
* env-driven and must not be trusted as a path).
|
|
114
|
+
*
|
|
115
|
+
* The command prints NOTHING on the hook path and exits 0 for every outcome.
|
|
116
|
+
* `PostCompact`'s stdin/stdout contract is truncated in the retrievable docs,
|
|
117
|
+
* so the safe assumption is the `SessionStart` one — stdout may be added to the
|
|
118
|
+
* model's context. An error message there would be read as a fact. See
|
|
119
|
+
* `compact-event-settle.ts`.
|
|
120
|
+
*
|
|
121
|
+
* No `shell` pin, deliberately: this entry lands in the shared, committed
|
|
122
|
+
* `.claude/settings.json`, and a `powershell` pin there would break every
|
|
123
|
+
* macOS / Linux reader of the file. See `resolveHookEntries`' comment block for
|
|
124
|
+
* the full reason the three `SessionStart` entries are unpinned too.
|
|
125
|
+
*/
|
|
126
|
+
export const HOOK_COMPACT_SETTLE_COMMAND = `peaks compact settle --project "\${CLAUDE_PROJECT_DIR}"`;
|
|
127
|
+
/** The event this entry rides. Claude Code fires it after a compaction completes. */
|
|
128
|
+
export const HOOK_COMPACT_SETTLE_EVENT = 'PostCompact';
|
|
129
|
+
/** Matcher: empty = every `trigger` (`auto` and `manual`). See the sentinel doc. */
|
|
130
|
+
export const HOOK_COMPACT_SETTLE_MATCHER = '';
|
|
@@ -604,6 +604,15 @@ export function clearSkillPresence(projectRootOverride) {
|
|
|
604
604
|
// shim; the LLM runner calls `peaks workflow terminalize` or
|
|
605
605
|
// `terminalizePresenceLease` directly).
|
|
606
606
|
//
|
|
607
|
+
// That rule is the surrounding DESIGN, not a description of this
|
|
608
|
+
// function: nothing below routes anywhere. This shim has no session
|
|
609
|
+
// lock, no lease argument and no workflow id, so it cannot route —
|
|
610
|
+
// it cleans up deprecated files and returns whether it removed any.
|
|
611
|
+
// The truthful report of what remains is the caller's job
|
|
612
|
+
// (`skill-command.ts` re-reads the live projection and emits
|
|
613
|
+
// `cleared` / `reason`). Do not read the paragraph above as a
|
|
614
|
+
// promise about this function.
|
|
615
|
+
//
|
|
607
616
|
// The shim still removes the legacy `active-skill.json` /
|
|
608
617
|
// `.peaks/.active-skill.json` so a stale marker from a prior CLI
|
|
609
618
|
// version cannot resurrect after a fresh `clear`. The canonical
|
|
@@ -7,6 +7,20 @@ export type StatusLineStdin = {
|
|
|
7
7
|
cwd?: string;
|
|
8
8
|
session_id?: string;
|
|
9
9
|
caller_id?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The harness's own context numbers. Declared here because this type IS the
|
|
12
|
+
* documented shape of the payload the harness pipes in; omitting a documented
|
|
13
|
+
* field would make the type lie by omission, and a consumer that reached for
|
|
14
|
+
* it would have to cast. Read (never written) by
|
|
15
|
+
* `harness-context-witness.ts` — see that module for why
|
|
16
|
+
* `context_window_size` is NOT a denominator.
|
|
17
|
+
*/
|
|
18
|
+
context_window?: {
|
|
19
|
+
context_window_size?: unknown;
|
|
20
|
+
used_percentage?: unknown;
|
|
21
|
+
remaining_percentage?: unknown;
|
|
22
|
+
current_usage?: Record<string, unknown> | undefined;
|
|
23
|
+
} | undefined;
|
|
10
24
|
};
|
|
11
25
|
export type StatusLineState = 'active' | 'idle' | 'stale' | 'invalid-presence';
|
|
12
26
|
export type StatusLinePresence = {
|
|
@@ -8,6 +8,7 @@ import { isDirectory } from 'peaks-loop-shared/fs';
|
|
|
8
8
|
// is no longer read. Path-safety helpers now live at
|
|
9
9
|
// `shared/path-safety.ts` if this module ever needs them.
|
|
10
10
|
import { verifyPipeline } from '../workflow/pipeline-verify-service.js';
|
|
11
|
+
import { REQUEST_ID_PATTERN } from '../artifacts/request-artifact-service.js';
|
|
11
12
|
import { findMockViolations } from '../audit/enforcers/mock-placement.js';
|
|
12
13
|
import { runRedLinesAudit } from '../audit/red-lines-service.js';
|
|
13
14
|
/**
|
|
@@ -96,7 +97,8 @@ function runCommand(command, args, cwd, timeoutMs) {
|
|
|
96
97
|
cwd,
|
|
97
98
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
98
99
|
timeout: timeoutMs,
|
|
99
|
-
maxBuffer: EXEC_MAX_BUFFER_BYTES
|
|
100
|
+
maxBuffer: EXEC_MAX_BUFFER_BYTES,
|
|
101
|
+
windowsHide: true
|
|
100
102
|
}).toString('utf8');
|
|
101
103
|
return {
|
|
102
104
|
status: 'pass',
|
|
@@ -238,20 +240,29 @@ async function runUnitTests(projectRoot, runTests) {
|
|
|
238
240
|
}
|
|
239
241
|
};
|
|
240
242
|
}
|
|
243
|
+
// Slice `2026-09-14-audit-artifact-rid-scoping`: the evidence filenames
|
|
244
|
+
// carry the rid now. Candidate order is canonical-first, then the
|
|
245
|
+
// back-compat tiers — the same order `artifact-prerequisites.ts` resolves
|
|
246
|
+
// in, so this boundary gate and the transition gate agree on which file is
|
|
247
|
+
// a slice's evidence. `<rid>` is substituted at probe time.
|
|
241
248
|
const REVIEW_FILES = [
|
|
242
|
-
{
|
|
249
|
+
{
|
|
250
|
+
name: 'code-review',
|
|
251
|
+
paths: ['rd/code-review-<rid>.md', 'rd/code-review.md'],
|
|
252
|
+
label: 'code-review'
|
|
253
|
+
},
|
|
243
254
|
// v2.12.0 collapse: security + perf moved to standalone audit skills.
|
|
244
|
-
// `slice check` accepts
|
|
245
|
-
//
|
|
246
|
-
// (v2.13.0 hard-deletes the legacy paths — see CHANGELOG [2.12.0]).
|
|
255
|
+
// `slice check` accepts the rid-scoped audit path, the bare v2.12.0 path
|
|
256
|
+
// OR the v2.11.x legacy path during the 1-minor-release back-compat
|
|
257
|
+
// window (v2.13.0 hard-deletes the legacy paths — see CHANGELOG [2.12.0]).
|
|
247
258
|
{
|
|
248
259
|
name: 'security-review',
|
|
249
|
-
paths: ['audit/security.md', 'rd/security-review.md'],
|
|
260
|
+
paths: ['audit/security-<rid>.md', 'audit/security.md', 'rd/security-review.md'],
|
|
250
261
|
label: 'security-review'
|
|
251
262
|
},
|
|
252
263
|
{
|
|
253
264
|
name: 'perf-baseline',
|
|
254
|
-
paths: ['audit/perf.md', 'rd/perf-baseline.md'],
|
|
265
|
+
paths: ['audit/perf-<rid>.md', 'audit/perf.md', 'rd/perf-baseline.md'],
|
|
255
266
|
label: 'perf-baseline'
|
|
256
267
|
}
|
|
257
268
|
];
|
|
@@ -283,11 +294,11 @@ async function runReviewFanout(projectRoot, rid, refresh) {
|
|
|
283
294
|
const found = [];
|
|
284
295
|
for (const review of REVIEW_FILES) {
|
|
285
296
|
let hit = null;
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
const candidates =
|
|
297
|
+
// Back-compat: each entry lists multiple candidate paths. First hit (in
|
|
298
|
+
// declared order) wins; canonical paths come first so a current slice
|
|
299
|
+
// preferentially reports its own rid-scoped evidence even when a legacy
|
|
300
|
+
// file is also present during migration.
|
|
301
|
+
const candidates = review.paths.map((candidate) => candidate.replace('<rid>', rid));
|
|
291
302
|
for (const candidate of candidates) {
|
|
292
303
|
for (const scope of scopes) {
|
|
293
304
|
const abs = join(projectRoot, '.peaks', scope, candidate);
|
|
@@ -366,6 +377,14 @@ export async function sliceCheck(options) {
|
|
|
366
377
|
throw new Error('No --rid supplied. Pass --rid <id> on the CLI to identify which slice to check.');
|
|
367
378
|
}
|
|
368
379
|
const rid = options.rid;
|
|
380
|
+
// The rid becomes a filename in `runReviewFanout`'s candidate list and a
|
|
381
|
+
// directory segment in its `scopes` — both joined onto the project root. The
|
|
382
|
+
// rid is the repo's own request-id shape, and `request-artifact-service.ts`
|
|
383
|
+
// already refuses anything else; apply the same guard here rather than
|
|
384
|
+
// probing paths a hostile `--rid` steers.
|
|
385
|
+
if (!REQUEST_ID_PATTERN.test(rid)) {
|
|
386
|
+
throw new Error(`Invalid request id: ${rid} (expected letters, digits, dots, underscores, or dashes)`);
|
|
387
|
+
}
|
|
369
388
|
const totalStart = Date.now();
|
|
370
389
|
const stages = [];
|
|
371
390
|
let unitTestsRunMode = 'skipped';
|
|
@@ -98,7 +98,8 @@ function runCodegraph(args, projectRoot) {
|
|
|
98
98
|
cwd: projectRoot,
|
|
99
99
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
100
100
|
timeout: 60_000,
|
|
101
|
-
maxBuffer: 32 * 1024 * 1024
|
|
101
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
102
|
+
windowsHide: true
|
|
102
103
|
};
|
|
103
104
|
// Use `peaks codegraph` (the peaks wrapper), which adds --project support.
|
|
104
105
|
// 2026-09-10: no shell. `peaks` on Windows is a `.cmd` shim, which Node >= 20
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
16
16
|
import { dirname, join, resolve } from 'node:path';
|
|
17
|
+
import { isUnsafePathInput } from '../../shared/path-safety.js';
|
|
17
18
|
/** The 5 default review items per slice (the 12 Gaps memory checklist). */
|
|
18
19
|
export const DEFAULT_REVIEW_ITEMS = [
|
|
19
20
|
{ id: 'business-match', question: '这个 slice 做完,业务流程对吗?(跟产品最初给的需求匹配)' },
|
|
@@ -32,6 +33,13 @@ export function buildEmptySliceReview(sliceId, sessionId, now = new Date()) {
|
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
export function getReviewDir(projectRoot, sessionId) {
|
|
36
|
+
// Sid axis. Every `peaks slice-review|score|accept|reject` subcommand reaches
|
|
37
|
+
// the runtime tree through this one constructor. Measured: `--session-id
|
|
38
|
+
// ../../../../…/PWNED` wrote `slice-reviews/<slice-id>.json` outside every
|
|
39
|
+
// project root under an `ok: true` envelope (RD sweep case A26).
|
|
40
|
+
if (isUnsafePathInput(sessionId)) {
|
|
41
|
+
throw new Error(`Invalid session id: ${sessionId} (must be a single path segment)`);
|
|
42
|
+
}
|
|
35
43
|
return resolve(projectRoot, '.peaks', '_runtime', sessionId, 'slice-reviews');
|
|
36
44
|
}
|
|
37
45
|
export function getReviewPath(projectRoot, sessionId, sliceId) {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*
|
|
9
9
|
* File budget: ≤ 400 lines (rid-006 split).
|
|
10
10
|
*/
|
|
11
|
-
import type
|
|
11
|
+
import { type ArtifactPrerequisite, type RequestType } from '../artifacts/artifact-prerequisites.js';
|
|
12
|
+
import type { RequestArtifactRole, RequestArtifactState } from '../artifacts/request-artifact-service.js';
|
|
12
13
|
import type { PipelineGate } from './pipeline-verify-types.js';
|
|
13
14
|
export declare function extractState(markdown: string): string;
|
|
14
15
|
/**
|
|
@@ -24,6 +25,38 @@ export declare function findRequestFile(projectRoot: string, role: string, rid:
|
|
|
24
25
|
content: string;
|
|
25
26
|
sessionId: string;
|
|
26
27
|
} | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Where the CURRENT contract puts one gate's evidence.
|
|
30
|
+
*
|
|
31
|
+
* The contract is the `artifact-prerequisites.ts` table — the table
|
|
32
|
+
* `peaks request transition` enforces and the one the peaks-qa prose
|
|
33
|
+
* contract mirrors (`skills/bee/peaks-qa/references/qa-transition-gates.md`).
|
|
34
|
+
* `probeName` is the location this checker probes today. The contract's
|
|
35
|
+
* `relativePath` is returned first, then its accepted historical locations in
|
|
36
|
+
* the table's own declared order — `legacyRelativePath`, then
|
|
37
|
+
* `legacyRelativePaths` (the same composition `artifact-prerequisites.ts`' own
|
|
38
|
+
* resolver performs, so a hit here and a hit there land on the same file).
|
|
39
|
+
*
|
|
40
|
+
* Returns `null` when the contract carries no prerequisite for that name at
|
|
41
|
+
* all — the artifact was retired and no gate may fail on it.
|
|
42
|
+
*
|
|
43
|
+
* This lookup exists because hard-coding the paths here is what let
|
|
44
|
+
* `verify-pipeline` fall a minor release behind the gate: it kept demanding
|
|
45
|
+
* `rd/security-review.md` as mandatory after the table had demoted that file
|
|
46
|
+
* to a `legacyRelativePath` fallback of `audit/security.md`, and it kept
|
|
47
|
+
* demanding `qa/security-findings-<rid>.md` / `qa/performance-findings-<rid>.md`
|
|
48
|
+
* after the v2.11.0 D1/D4 trim dropped them from `qa:verdict-issued`
|
|
49
|
+
* altogether (rid 2026-09-14-verify-pipeline-contract-drift).
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* The prerequisite the contract carries for `probeName`, or null when it
|
|
53
|
+
* carries none. `contractEvidencePaths` is this object's path projection; the
|
|
54
|
+
* BODY contract (`mustContain` / `mustContainAny` / `headingMustContain`) rides
|
|
55
|
+
* on the same object, which is why `contractBodyViolations` below consults it
|
|
56
|
+
* instead of probing for the file's existence alone.
|
|
57
|
+
*/
|
|
58
|
+
export declare function contractPrerequisite(role: RequestArtifactRole, state: RequestArtifactState, requestType: RequestType, probeName: string): ArtifactPrerequisite | null;
|
|
59
|
+
export declare function contractEvidencePaths(role: RequestArtifactRole, state: RequestArtifactState, requestType: RequestType, probeName: string): string[] | null;
|
|
27
60
|
export declare function rdGatesForType(requestType: RequestType): PipelineGate[];
|
|
28
61
|
export declare function qaGatesForType(requestType: RequestType): PipelineGate[];
|
|
29
62
|
export declare const RD_QA_HANDOFF_STATES: Set<string>;
|
|
@@ -33,15 +66,19 @@ export interface CanonicalPathTracker {
|
|
|
33
66
|
anyEvidenceResolved: boolean;
|
|
34
67
|
allResolvedPathsCanonical: boolean;
|
|
35
68
|
}
|
|
36
|
-
/** Resolve RD evidence files (
|
|
69
|
+
/** Resolve RD evidence files (prd-handoff / bug-analysis / code-review / security-review / perf-baseline)
|
|
37
70
|
* by probing canonical + legacy paths for each gate. Mutates the gate.passed /
|
|
38
71
|
* gate.detail fields in place and pushes violations / nextActions. Returns the
|
|
39
72
|
* updated tracker. Verbatim-move from `pipeline-verify-service.ts`. */
|
|
40
|
-
export declare function resolveRdEvidencePaths(gates: PipelineGate[], rdEvidenceDir: string, projectRoot: string, violations: string[], nextActions: string[], tracker: CanonicalPathTracker): CanonicalPathTracker;
|
|
41
|
-
/** Resolve QA evidence files (test-cases / test-report
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
73
|
+
export declare function resolveRdEvidencePaths(gates: PipelineGate[], rdEvidenceDir: string, projectRoot: string, rid: string, requestType: RequestType, violations: string[], nextActions: string[], tracker: CanonicalPathTracker): CanonicalPathTracker;
|
|
74
|
+
/** Resolve QA evidence files (test-cases / test-report) by probing canonical
|
|
75
|
+
* + legacy paths for each gate. Mutates the gate.passed / gate.detail fields
|
|
76
|
+
* in place and pushes violations / nextActions. Returns the updated tracker.
|
|
77
|
+
* Verbatim-move from `pipeline-verify-service.ts`.
|
|
78
|
+
*
|
|
79
|
+
* The `security-findings` / `performance-findings` branches that used to live
|
|
80
|
+
* here are gone: those artifacts are not in any `qa:verdict-issued` table
|
|
81
|
+
* (v2.11.0 D1/D4), and the evidence they stood for is resolved on the RD side
|
|
82
|
+
* at the contract's own paths (`audit/security-<rid>.md`,
|
|
83
|
+
* `audit/perf-<rid>.md`). */
|
|
84
|
+
export declare function resolveQaEvidencePaths(gates: PipelineGate[], projectRoot: string, rdEvidenceDir: string, requestType: RequestType, rid: string, violations: string[], nextActions: string[], tracker: CanonicalPathTracker): CanonicalPathTracker;
|