peaks-loop 4.0.0-beta → 4.0.0-beta.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.
- package/CHANGELOG.md +105 -87
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/dist/src/cli/commands/{solo-commands.d.ts → code-commands.d.ts} +24 -24
- package/dist/src/cli/commands/{solo-commands.js → code-commands.js} +78 -78
- package/dist/src/cli/commands/core/skill-command.js +1 -1
- package/dist/src/cli/commands/dispatch-from-dag.js +1 -1
- package/dist/src/cli/commands/hook-handle.js +7 -7
- package/dist/src/cli/commands/job-commands.js +2 -2
- package/dist/src/cli/commands/session-auto-compact-hook-command.js +2 -2
- package/dist/src/cli/commands/sub-agent-shared.d.ts +1 -1
- package/dist/src/cli/commands/user-touchpoint-commands.d.ts +4 -4
- package/dist/src/cli/commands/user-touchpoint-commands.js +14 -14
- package/dist/src/cli/commands/workflow-commands.js +22 -22
- package/dist/src/cli/program.js +6 -6
- package/dist/src/services/artifacts/repair-cycle-service.js +1 -1
- package/dist/src/services/audit/enforcers/active-skill-resolver.d.ts +1 -1
- package/dist/src/services/audit/enforcers/active-skill-resolver.js +1 -1
- package/dist/src/services/audit/enforcers/{solo-code-ban.d.ts → code-ban.d.ts} +6 -6
- package/dist/src/services/audit/enforcers/{solo-code-ban.js → code-ban.js} +6 -6
- package/dist/src/services/audit/red-line-catalog.d.ts +2 -2
- package/dist/src/services/audit/red-line-catalog.js +5 -5
- package/dist/src/services/audit/types.d.ts +2 -2
- package/dist/src/services/{solo → code}/auto-compact-orchestrator.d.ts +1 -1
- package/dist/src/services/{solo → code}/auto-compact-orchestrator.js +3 -3
- package/dist/src/services/{solo → code}/dag-orchestrator.d.ts +1 -1
- package/dist/src/services/{solo → code}/dag-orchestrator.js +1 -1
- package/dist/src/services/{solo → code}/emit-handoff.d.ts +1 -1
- package/dist/src/services/{solo → code}/emit-handoff.js +1 -1
- package/dist/src/services/{solo → code}/job-shape-decision.d.ts +1 -1
- package/dist/src/services/{solo → code}/job-shape-decision.js +5 -5
- package/dist/src/services/{solo → code}/mode-gate.d.ts +9 -9
- package/dist/src/services/{solo → code}/mode-gate.js +5 -5
- package/dist/src/services/{solo → code}/post-compact-detector.d.ts +3 -3
- package/dist/src/services/{solo → code}/post-compact-detector.js +4 -4
- package/dist/src/services/{solo → code}/step-08-gate.d.ts +4 -4
- package/dist/src/services/{solo → code}/step-08-gate.js +4 -4
- package/dist/src/services/{solo → code}/user-touchpoint-classifier.d.ts +1 -1
- package/dist/src/services/{solo → code}/user-touchpoint-classifier.js +1 -1
- package/dist/src/services/context/auto-compact-dispatcher.d.ts +2 -2
- package/dist/src/services/context/auto-compact-dispatcher.js +2 -2
- package/dist/src/services/context/auto-compact-types.d.ts +1 -1
- package/dist/src/services/dispatch/slice-dag.d.ts +2 -2
- package/dist/src/services/dispatch/test-tool-detection.d.ts +1 -1
- package/dist/src/services/dispatch/test-tool-detection.js +1 -1
- package/dist/src/services/feedback/feedback-promotion-service.js +2 -2
- package/dist/src/services/job/job-progress-store.d.ts +1 -1
- package/dist/src/services/job/job-progress-store.js +1 -1
- package/dist/src/services/preferences/preferences-service.d.ts +1 -1
- package/dist/src/services/preferences/preferences-types.d.ts +1 -1
- package/dist/src/services/rd/standards-diagnostic.d.ts +1 -1
- package/dist/src/services/rd/standards-diagnostic.js +2 -2
- package/dist/src/services/recommendations/capability-seed-items.js +1 -1
- package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
- package/dist/src/services/recommendations/recommendation-service.js +1 -1
- package/dist/src/services/refactor/refactor-service.d.ts +1 -1
- package/dist/src/services/signal/cancel-handler.js +3 -3
- package/dist/src/services/skill/resume-detector.js +1 -1
- package/dist/src/services/skills/skill-presence-service.d.ts +1 -1
- package/dist/src/services/upgrade/1x-detector-service.js +1 -1
- package/dist/src/services/workflow/pipeline-verify-service.d.ts +1 -1
- package/dist/src/services/workflow/pipeline-verify-service.js +3 -3
- package/dist/src/services/workflow/workflow-autonomous-service.d.ts +3 -3
- package/dist/src/services/workflow/workflow-autonomous-service.js +2 -2
- package/dist/src/services/workflow/workflow-router-service.d.ts +6 -6
- package/dist/src/services/workflow/workflow-router-service.js +33 -33
- package/dist/src/services/workspace/claude-settings-template.d.ts +1 -1
- package/dist/src/services/workspace/claude-settings-template.js +5 -5
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/output-styles/peaks-skill-swarm.md +3 -3
- package/package.json +1 -1
- package/skills/bee/peaks-qa/SKILL.md +1 -1
- package/skills/bee/peaks-qa/references/artifact-per-request.md +3 -3
- package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +6 -6
- package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +1 -1
- package/skills/bee/peaks-rd/references/rd-runbook.md +1 -1
- package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +11 -11
- package/skills/bee/peaks-rd/references/rd-transition-gates.md +1 -1
- package/skills/bee/peaks-sc/SKILL.md +1 -1
- package/skills/bee/peaks-txt/SKILL.md +3 -3
- package/skills/bee/peaks-ui/SKILL.md +8 -8
- package/skills/peaks-code/SKILL.md +21 -21
- package/skills/peaks-code/references/anchoring-and-session-info.md +2 -2
- package/skills/peaks-code/references/artifact-contracts.md +1 -1
- package/skills/peaks-code/references/boundaries.md +3 -3
- package/skills/peaks-code/references/codegraph-orchestration.md +1 -1
- package/skills/peaks-code/references/dag-orchestrator.md +7 -7
- package/skills/peaks-code/references/external-references.md +2 -2
- package/skills/peaks-code/references/fanout-mandatory.md +3 -3
- package/skills/peaks-code/references/fast-mode.md +2 -2
- package/skills/peaks-code/references/frontend-only-mode.md +9 -9
- package/skills/peaks-code/references/job-loop.md +1 -1
- package/skills/peaks-code/references/local-artifact-workspace.md +2 -2
- package/skills/peaks-code/references/micro-cycle.md +14 -14
- package/skills/peaks-code/references/mode-selection-with-stale-presence.md +5 -5
- package/skills/peaks-code/references/mode-selection.md +3 -3
- package/skills/peaks-code/references/openspec-workflow.md +16 -16
- package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
- package/skills/peaks-code/references/quality-gate-cheatsheet.md +1 -1
- package/skills/peaks-code/references/refactor-mode.md +1 -1
- package/skills/peaks-code/references/runbook.md +15 -15
- package/skills/peaks-code/references/step-0-55-1x-detection.md +1 -1
- package/skills/peaks-code/references/step-0-8-gate.md +11 -11
- package/skills/peaks-code/references/sub-agent-dispatch.md +8 -8
- package/skills/peaks-code/references/swarm-dispatch-contract.md +17 -17
- package/skills/peaks-code/references/workflow-gates-and-types.md +2 -2
- package/skills/peaks-code/references/workflow.md +5 -5
- package/skills/peaks-resume/SKILL.md +2 -2
- package/skills/peaks-status/SKILL.md +2 -2
- package/skills/peaks-test/SKILL.md +2 -2
- /package/dist/src/services/{solo → code}/batch-heartbeat-poller.d.ts +0 -0
- /package/dist/src/services/{solo → code}/batch-heartbeat-poller.js +0 -0
- /package/dist/src/services/{solo → code}/status-line-renderer.d.ts +0 -0
- /package/dist/src/services/{solo → code}/status-line-renderer.js +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The CLI is a *recorder and gate*, not a judge. The LLM makes the
|
|
5
5
|
* semantic call ("is this a Job?") and writes the verdict via
|
|
6
|
-
* `peaks
|
|
6
|
+
* `peaks code detect-job`; this service persists the verdict to
|
|
7
7
|
* `.peaks/_runtime/<sessionId>/job-shape.json` and refuses downstream
|
|
8
8
|
* steps that need a decision when the file is missing.
|
|
9
9
|
*
|
|
@@ -73,7 +73,7 @@ export function readJobShapeDecision(projectRoot, sessionId) {
|
|
|
73
73
|
if (!existsSync(path)) {
|
|
74
74
|
throw new JobShapeDecisionError({
|
|
75
75
|
code: JOB_SHAPE_NOT_DECIDED,
|
|
76
|
-
message: `No Job-shape decision recorded for session ${sessionId}. Run \`peaks
|
|
76
|
+
message: `No Job-shape decision recorded for session ${sessionId}. Run \`peaks code detect-job\` to record a decision.`,
|
|
77
77
|
details: { path }
|
|
78
78
|
});
|
|
79
79
|
}
|
|
@@ -84,7 +84,7 @@ export function readJobShapeDecision(projectRoot, sessionId) {
|
|
|
84
84
|
catch (err) {
|
|
85
85
|
throw new JobShapeDecisionError({
|
|
86
86
|
code: JOB_SHAPE_NOT_DECIDED,
|
|
87
|
-
message: `Job-shape decision file is unreadable for session ${sessionId}. Run \`peaks
|
|
87
|
+
message: `Job-shape decision file is unreadable for session ${sessionId}. Run \`peaks code detect-job\` to re-record.`,
|
|
88
88
|
details: { path, cause: err instanceof Error ? err.message : String(err) }
|
|
89
89
|
});
|
|
90
90
|
}
|
|
@@ -95,7 +95,7 @@ export function readJobShapeDecision(projectRoot, sessionId) {
|
|
|
95
95
|
catch (err) {
|
|
96
96
|
throw new JobShapeDecisionError({
|
|
97
97
|
code: JOB_SHAPE_NOT_DECIDED,
|
|
98
|
-
message: `Job-shape decision file is malformed JSON for session ${sessionId}. Run \`peaks
|
|
98
|
+
message: `Job-shape decision file is malformed JSON for session ${sessionId}. Run \`peaks code detect-job --force\` to overwrite.`,
|
|
99
99
|
details: { path, cause: err instanceof Error ? err.message : String(err) }
|
|
100
100
|
});
|
|
101
101
|
}
|
|
@@ -105,7 +105,7 @@ export function readJobShapeDecision(projectRoot, sessionId) {
|
|
|
105
105
|
catch (err) {
|
|
106
106
|
throw new JobShapeDecisionError({
|
|
107
107
|
code: JOB_SHAPE_NOT_DECIDED,
|
|
108
|
-
message: `Job-shape decision file is schema-invalid for session ${sessionId}. Run \`peaks
|
|
108
|
+
message: `Job-shape decision file is schema-invalid for session ${sessionId}. Run \`peaks code detect-job --force\` to overwrite.`,
|
|
109
109
|
details: { path, cause: err instanceof Error ? err.message : String(err) }
|
|
110
110
|
});
|
|
111
111
|
}
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* 4 mode values stay in lockstep with the rest of the runtime.
|
|
21
21
|
*/
|
|
22
22
|
import type { SkillPresenceMode } from '../skills/skill-presence-service.js';
|
|
23
|
-
export type
|
|
24
|
-
export declare const
|
|
23
|
+
export type CodeMode = SkillPresenceMode;
|
|
24
|
+
export declare const CODE_MODES: readonly CodeMode[];
|
|
25
25
|
export type HardFloorCategory = 'irreversible-external-side-effect' | 'authentication-credential' | 'multi-day-investment'
|
|
26
26
|
/**
|
|
27
27
|
* v2.15.0 slice 002 AC-4: actions that are past the user's
|
|
@@ -42,7 +42,7 @@ export declare const HARD_FLOOR_CATEGORIES: readonly HardFloorCategory[];
|
|
|
42
42
|
export type GatedStepId = 'step-0.5-openspec-opt-in' | 'step-0.6-audit-goal' | 'step-0.7-resume-detection' | 'step-0.55-1x-upgrade' | 'step-1-mode-select' | 'step-2.5-session-title' | 'phase-2-prd-confirm' | 'phase-3-swarm-gate-b' | 'phase-6-qa-gate-d' | 'phase-10-txt-memory-extract' | 'step-n+1-final-review' | 'frontend-only-mismatch' | 'step-0.75-checkpoint-resume' | 'standards-preflight';
|
|
43
43
|
export declare const GATED_STEPS: readonly GatedStepId[];
|
|
44
44
|
/**
|
|
45
|
-
* Slice 2026-06-28-
|
|
45
|
+
* Slice 2026-06-28-code-mode-bypass-fix: the kind of gate that
|
|
46
46
|
* produced this decision. The LLM-side caller (peaks-code body) reads
|
|
47
47
|
* this to distinguish "you paused because the user must choose the
|
|
48
48
|
* mode" (`mode-selection-itself`) from "you paused because the mode
|
|
@@ -63,23 +63,23 @@ export declare const GATED_STEPS: readonly GatedStepId[];
|
|
|
63
63
|
export type GateKind = 'mode-selection-itself' | 'mode-driven' | 'hard-floor';
|
|
64
64
|
export interface GateDecision {
|
|
65
65
|
readonly shouldPause: boolean;
|
|
66
|
-
/** Human-readable rationale; surfaces in `peaks
|
|
66
|
+
/** Human-readable rationale; surfaces in `peaks code should-pause --json` */
|
|
67
67
|
readonly reason: string;
|
|
68
68
|
/** Hard-floor override applied? Surfaces in audit log when true */
|
|
69
69
|
readonly hardFloorCategory?: HardFloorCategory;
|
|
70
|
-
/** Slice 2026-06-28-
|
|
70
|
+
/** Slice 2026-06-28-code-mode-bypass-fix: kind of gate that produced
|
|
71
71
|
* this decision. Always present; defaults to `'mode-driven'` for the
|
|
72
72
|
* assisted/strict pause branch. */
|
|
73
73
|
readonly gateKind: GateKind;
|
|
74
74
|
}
|
|
75
|
-
export declare function
|
|
75
|
+
export declare function isCodeMode(value: string): value is CodeMode;
|
|
76
76
|
export declare function isHardFloorCategory(value: string): value is HardFloorCategory;
|
|
77
77
|
/**
|
|
78
78
|
* `true` when the current mode should auto-proceed (skip the
|
|
79
79
|
* AskUserQuestion round-trip). Mirrors D5.a: "recommended = chosen
|
|
80
80
|
* in full-auto / swarm; always log, never silently skip".
|
|
81
81
|
*/
|
|
82
|
-
export declare function shouldAutoProceed(mode:
|
|
82
|
+
export declare function shouldAutoProceed(mode: CodeMode): boolean;
|
|
83
83
|
/**
|
|
84
84
|
* Should the LLM emit an AskUserQuestion at `step` given `mode`?
|
|
85
85
|
* Pure function: no IO, no LLM call. The LLM-side caller passes the
|
|
@@ -107,7 +107,7 @@ export type CommitBoundaryActionId = 'git-push' | 'git-tag' | 'npm-publish' | 'n
|
|
|
107
107
|
export declare const COMMIT_BOUNDARY_ACTIONS: readonly CommitBoundaryActionId[];
|
|
108
108
|
export declare function isCommitBoundaryAction(value: string): value is CommitBoundaryActionId;
|
|
109
109
|
export declare function shouldPauseAtGate(opts: {
|
|
110
|
-
mode:
|
|
110
|
+
mode: CodeMode;
|
|
111
111
|
step: GatedStepId;
|
|
112
112
|
hardFloorCategory?: HardFloorCategory | undefined;
|
|
113
113
|
/**
|
|
@@ -125,7 +125,7 @@ export declare function shouldPauseAtGate(opts: {
|
|
|
125
125
|
* system. The CLI / LLM is responsible for appending.
|
|
126
126
|
*/
|
|
127
127
|
export declare function formatAutoProceedLogLine(opts: {
|
|
128
|
-
mode:
|
|
128
|
+
mode: CodeMode;
|
|
129
129
|
step: GatedStepId;
|
|
130
130
|
recommendedOption: string;
|
|
131
131
|
hardFloorCategory?: HardFloorCategory | undefined;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* Re-uses `SkillPresenceMode` from `skill-presence-service.ts` so the
|
|
20
20
|
* 4 mode values stay in lockstep with the rest of the runtime.
|
|
21
21
|
*/
|
|
22
|
-
export const
|
|
22
|
+
export const CODE_MODES = [
|
|
23
23
|
'full-auto',
|
|
24
24
|
'assisted',
|
|
25
25
|
'swarm',
|
|
@@ -47,8 +47,8 @@ export const GATED_STEPS = [
|
|
|
47
47
|
'step-0.75-checkpoint-resume',
|
|
48
48
|
'standards-preflight'
|
|
49
49
|
];
|
|
50
|
-
export function
|
|
51
|
-
return
|
|
50
|
+
export function isCodeMode(value) {
|
|
51
|
+
return CODE_MODES.includes(value);
|
|
52
52
|
}
|
|
53
53
|
export function isHardFloorCategory(value) {
|
|
54
54
|
return HARD_FLOOR_CATEGORIES.includes(value);
|
|
@@ -75,7 +75,7 @@ export function isCommitBoundaryAction(value) {
|
|
|
75
75
|
* Hard-pause steps: these pause regardless of mode. They are the gates
|
|
76
76
|
* whose decision *creates* or *recreates* the mode/state under which
|
|
77
77
|
* later gates run. Auto-proceeding on them would silently fix the mode
|
|
78
|
-
* without user consent (defect #1: new
|
|
78
|
+
* without user consent (defect #1: new Code session skipped Step 1
|
|
79
79
|
* AskUserQuestion because `full-auto` mode triggered `shouldAutoProceed`
|
|
80
80
|
* on `step-1-mode-select` itself).
|
|
81
81
|
*
|
|
@@ -115,7 +115,7 @@ export function shouldPauseAtGate(opts) {
|
|
|
115
115
|
gateKind: 'hard-floor'
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
-
// Slice 2026-06-28-
|
|
118
|
+
// Slice 2026-06-28-code-mode-bypass-fix: hard-pause steps that
|
|
119
119
|
// determine the active mode or session context MUST prompt the
|
|
120
120
|
// user. Otherwise full-auto silently locks in `mode=full-auto` on
|
|
121
121
|
// the first tool call, skipping the AskUserQuestion Step 1 mandates.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* 1. `.peaks/_runtime/<sessionId>/` is bound
|
|
8
8
|
* 2. Latest checkpoint mtime is from today (UTC date)
|
|
9
9
|
* 3. Latest checkpoint has a parseable `mode` field
|
|
10
|
-
* 4. The peak-
|
|
10
|
+
* 4. The peak-code skill is the active skill
|
|
11
11
|
* 5. Exactly one session has a today's checkpoint (no ambiguity)
|
|
12
12
|
*
|
|
13
13
|
* On a hit, the LLM MUST auto-resume (D7.b override of "never silently
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
* No writes (caller logs the decision via the auto-decisions channel).
|
|
23
23
|
*/
|
|
24
24
|
import type { SkillPresenceMode } from '../skills/skill-presence-service.js';
|
|
25
|
-
import { type
|
|
25
|
+
import { type CodeMode } from './mode-gate.js';
|
|
26
26
|
export type PostCompactResumeReason = 'post-compact-match' | 'sid-unbound' | 'runtime-dir-missing' | 'no-checkpoint-today' | 'no-mode-field' | 'stale-checkpoint' | 'multiple-checkpoints-ambiguous' | 'active-skill-mismatch' | 'checkpoint-read-failed';
|
|
27
27
|
export declare const POST_COMPACT_RESUME_REASONS: readonly PostCompactResumeReason[];
|
|
28
28
|
export interface PostCompactResumeProbe {
|
|
29
29
|
readonly shouldAutoResume: boolean;
|
|
30
30
|
readonly reason: PostCompactResumeReason;
|
|
31
|
-
readonly mode?:
|
|
31
|
+
readonly mode?: CodeMode;
|
|
32
32
|
readonly checkpointPath?: string;
|
|
33
33
|
readonly checkpointMtime?: string;
|
|
34
34
|
readonly task?: string;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* 1. `.peaks/_runtime/<sessionId>/` is bound
|
|
8
8
|
* 2. Latest checkpoint mtime is from today (UTC date)
|
|
9
9
|
* 3. Latest checkpoint has a parseable `mode` field
|
|
10
|
-
* 4. The peak-
|
|
10
|
+
* 4. The peak-code skill is the active skill
|
|
11
11
|
* 5. Exactly one session has a today's checkpoint (no ambiguity)
|
|
12
12
|
*
|
|
13
13
|
* On a hit, the LLM MUST auto-resume (D7.b override of "never silently
|
|
@@ -25,7 +25,7 @@ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
|
25
25
|
import { join } from 'node:path';
|
|
26
26
|
import { getSkillPresence } from '../skills/skill-presence-service.js';
|
|
27
27
|
import { emitObservabilityEvent } from '../observability/observability-service.js';
|
|
28
|
-
import {
|
|
28
|
+
import { isCodeMode } from './mode-gate.js';
|
|
29
29
|
export const POST_COMPACT_RESUME_REASONS = [
|
|
30
30
|
'post-compact-match',
|
|
31
31
|
'sid-unbound',
|
|
@@ -160,7 +160,7 @@ export async function detectPostCompactResume(opts) {
|
|
|
160
160
|
// Mode: prefer the checkpoint's mode; fall back to the presence override
|
|
161
161
|
// (test seam) or to a fresh skill-presence read.
|
|
162
162
|
let mode;
|
|
163
|
-
if (
|
|
163
|
+
if (isCodeMode(checkpointMode)) {
|
|
164
164
|
mode = checkpointMode;
|
|
165
165
|
}
|
|
166
166
|
else if (opts.presenceModeOverride !== undefined) {
|
|
@@ -170,7 +170,7 @@ export async function detectPostCompactResume(opts) {
|
|
|
170
170
|
try {
|
|
171
171
|
const presence = getSkillPresence(opts.projectRoot);
|
|
172
172
|
const presenceMode = presence?.mode;
|
|
173
|
-
if (presenceMode !== undefined &&
|
|
173
|
+
if (presenceMode !== undefined && isCodeMode(presenceMode)) {
|
|
174
174
|
mode = presenceMode;
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Wire-installed by `peaks workspace init` (extends the existing hook
|
|
5
5
|
* installer; does NOT replace the Write|Edit|MultiEdit fact-forcing
|
|
6
|
-
* bypass). The hook runs `peaks
|
|
6
|
+
* bypass). The hook runs `peaks code gate-step-08 --project .` before
|
|
7
7
|
* every Bash tool call. Exit code is the load-bearing contract:
|
|
8
8
|
*
|
|
9
9
|
* exit 0 → allow (with structured stdout describing the decision)
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* regex is the FIRST time peaks-loop accepts hardcoded keywords —
|
|
30
30
|
* explicitly scoped as a *fail-closed backup* (case 3), NOT a primary
|
|
31
31
|
* judgement. The LLM still owns the semantic call via
|
|
32
|
-
* `peaks
|
|
32
|
+
* `peaks code detect-job`. The regex is a safety net for the v3.1.1
|
|
33
33
|
* incident class (LLM under load never records the decision at all).
|
|
34
34
|
*/
|
|
35
35
|
export declare const STEP_08_GATE_FILE_NAME: "job-shape.json";
|
|
@@ -38,7 +38,7 @@ export declare const STEP_08_PROGRESS_FILE_NAME: "progress.json";
|
|
|
38
38
|
* Fail-closed backup regex — see module docstring case 3 for why this
|
|
39
39
|
* exists. Kept short and explicit; if the prompt mentions any of these
|
|
40
40
|
* triggers and `job-shape.json` is missing, the LLM is treated as
|
|
41
|
-
* having skipped `peaks
|
|
41
|
+
* having skipped `peaks code detect-job` and the gate blocks.
|
|
42
42
|
*
|
|
43
43
|
* The list mirrors the v3.1.0 / v3.1.1 incident triggers verbatim:
|
|
44
44
|
* 继续执行下个 slice (until next slice) → until / 直到
|
|
@@ -84,7 +84,7 @@ export interface EvaluateStep08Result {
|
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
86
|
* Pure evaluator — does NOT write, does NOT exit. CLI wrapper in
|
|
87
|
-
* `src/cli/commands/
|
|
87
|
+
* `src/cli/commands/code-commands.ts` reads `allow` to set the process
|
|
88
88
|
* exit code (0 allow / 2 block) and prints the structured envelope.
|
|
89
89
|
*/
|
|
90
90
|
export declare function evaluateStep08(input: EvaluateStep08Input): EvaluateStep08Result;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Wire-installed by `peaks workspace init` (extends the existing hook
|
|
5
5
|
* installer; does NOT replace the Write|Edit|MultiEdit fact-forcing
|
|
6
|
-
* bypass). The hook runs `peaks
|
|
6
|
+
* bypass). The hook runs `peaks code gate-step-08 --project .` before
|
|
7
7
|
* every Bash tool call. Exit code is the load-bearing contract:
|
|
8
8
|
*
|
|
9
9
|
* exit 0 → allow (with structured stdout describing the decision)
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* regex is the FIRST time peaks-loop accepts hardcoded keywords —
|
|
30
30
|
* explicitly scoped as a *fail-closed backup* (case 3), NOT a primary
|
|
31
31
|
* judgement. The LLM still owns the semantic call via
|
|
32
|
-
* `peaks
|
|
32
|
+
* `peaks code detect-job`. The regex is a safety net for the v3.1.1
|
|
33
33
|
* incident class (LLM under load never records the decision at all).
|
|
34
34
|
*/
|
|
35
35
|
import { existsSync, readFileSync } from 'node:fs';
|
|
@@ -41,7 +41,7 @@ export const STEP_08_PROGRESS_FILE_NAME = 'progress.json';
|
|
|
41
41
|
* Fail-closed backup regex — see module docstring case 3 for why this
|
|
42
42
|
* exists. Kept short and explicit; if the prompt mentions any of these
|
|
43
43
|
* triggers and `job-shape.json` is missing, the LLM is treated as
|
|
44
|
-
* having skipped `peaks
|
|
44
|
+
* having skipped `peaks code detect-job` and the gate blocks.
|
|
45
45
|
*
|
|
46
46
|
* The list mirrors the v3.1.0 / v3.1.1 incident triggers verbatim:
|
|
47
47
|
* 继续执行下个 slice (until next slice) → until / 直到
|
|
@@ -102,7 +102,7 @@ function readPromptFromLastPromptFile(projectRoot, sessionId) {
|
|
|
102
102
|
}
|
|
103
103
|
/**
|
|
104
104
|
* Pure evaluator — does NOT write, does NOT exit. CLI wrapper in
|
|
105
|
-
* `src/cli/commands/
|
|
105
|
+
* `src/cli/commands/code-commands.ts` reads `allow` to set the process
|
|
106
106
|
* exit code (0 allow / 2 block) and prints the structured envelope.
|
|
107
107
|
*/
|
|
108
108
|
export function evaluateStep08(input) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* v2.15.0 follow-up — G4: user touchpoint classifier.
|
|
3
3
|
*
|
|
4
4
|
* 12 Gaps positioning memory: "user 介入 = 业务/产品审阅,不是技术决策".
|
|
5
|
-
* This service classifies every
|
|
5
|
+
* This service classifies every Code gate by the kind of decision it
|
|
6
6
|
* represents, so the CLI / status line can show user which gates
|
|
7
7
|
* actually need their attention vs which are technical defaults
|
|
8
8
|
* (AI auto-decides in full-auto).
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* v2.15.0 follow-up — G4: user touchpoint classifier.
|
|
3
3
|
*
|
|
4
4
|
* 12 Gaps positioning memory: "user 介入 = 业务/产品审阅,不是技术决策".
|
|
5
|
-
* This service classifies every
|
|
5
|
+
* This service classifies every Code gate by the kind of decision it
|
|
6
6
|
* represents, so the CLI / status line can show user which gates
|
|
7
7
|
* actually need their attention vs which are technical defaults
|
|
8
8
|
* (AI auto-decides in full-auto).
|
|
@@ -7,11 +7,11 @@ export interface DispatchIdeCompactInput {
|
|
|
7
7
|
/** Spawn timeout (ms). Default 30s — Claude Code `/compact` is sync. */
|
|
8
8
|
readonly timeoutMs?: number | undefined;
|
|
9
9
|
/**
|
|
10
|
-
* Slice 2026-06-28-
|
|
10
|
+
* Slice 2026-06-28-code-mode-bypass-fix (defect #4): which session
|
|
11
11
|
* the compact should target. Default `'main'` — the orchestrator
|
|
12
12
|
* (peaks-code body) runs in the main-session Claude Code window and
|
|
13
13
|
* wants to compress *its* context, not a sub-agent's. Sub-agent
|
|
14
|
-
* shells that spawn their own `peaks
|
|
14
|
+
* shells that spawn their own `peaks code auto-compact` flow pass
|
|
15
15
|
* `'sub-agent'` to preserve the legacy shell-spawn behaviour.
|
|
16
16
|
*
|
|
17
17
|
* Behaviour matrix (claude-code MVP):
|
|
@@ -47,7 +47,7 @@ export async function dispatchIdeCompact(input) {
|
|
|
47
47
|
// See auto-compact-reader.ts for the IdeKind→IdeId cast rationale.
|
|
48
48
|
const ideId = (detected === 'unknown' ? 'claude-code' : detected);
|
|
49
49
|
const adapter = getAdapter(ideId);
|
|
50
|
-
// Slice 2026-06-28-
|
|
50
|
+
// Slice 2026-06-28-code-mode-bypass-fix (defect #4): default to
|
|
51
51
|
// `'main'` so the orchestrator's auto-compact actually compresses
|
|
52
52
|
// the main-session context. The orchestrator passes `'sub-agent'`
|
|
53
53
|
// explicitly when a sub-agent shell dispatches the call.
|
|
@@ -123,7 +123,7 @@ export async function dispatchIdeCompact(input) {
|
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
// Lazy install: we only get here when the caller explicitly
|
|
126
|
-
// invokes `peaks
|
|
126
|
+
// invokes `peaks code auto-compact --execute`, so the user has
|
|
127
127
|
// already opted in. No zero-touch surprise on workspace init.
|
|
128
128
|
return await dispatchIdeNativeHook({
|
|
129
129
|
projectRoot: input.projectRoot,
|
|
@@ -107,7 +107,7 @@ export type AutoCompactResult = {
|
|
|
107
107
|
readonly convergencePlan?: ConvergencePlan;
|
|
108
108
|
readonly dispatch?: CompactDispatchResult;
|
|
109
109
|
/**
|
|
110
|
-
* Slice 2026-06-28-
|
|
110
|
+
* Slice 2026-06-28-code-mode-bypass-fix (defect #4): which
|
|
111
111
|
* session the compact targeted. `'main'` (default) means the
|
|
112
112
|
* main-session Claude Code window will fire `/compact` on its
|
|
113
113
|
* next turn; `'sub-agent'` means the dispatcher shell-spawned
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Slice complexity tier (v2.15.0 follow-up, G2 in 12 Gaps).
|
|
3
|
-
* Used by
|
|
3
|
+
* Used by Code to schedule complex slices during user-attended hours
|
|
4
4
|
* and trivial / simple slices overnight.
|
|
5
5
|
*/
|
|
6
6
|
export type SliceComplexity = 'trivial' | 'simple' | 'complex';
|
|
@@ -27,7 +27,7 @@ export interface SliceNode {
|
|
|
27
27
|
*/
|
|
28
28
|
readonly upstreamSync?: boolean;
|
|
29
29
|
/**
|
|
30
|
-
* v2.15.0 follow-up — G2: complexity tier. Drives
|
|
30
|
+
* v2.15.0 follow-up — G2: complexity tier. Drives Code's scheduling
|
|
31
31
|
* (complex = user-attended, simple/trivial = overnight). Optional.
|
|
32
32
|
*/
|
|
33
33
|
readonly complexity?: SliceComplexity;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The Test Tool Detection block is prepended to every sub-agent prompt
|
|
5
5
|
* dispatched by peaks-loop (both the single-dispatch chokepoint in
|
|
6
6
|
* `src/cli/commands/dispatch-commands.ts` and the DAG-dispatch chokepoint
|
|
7
|
-
* in `src/services/
|
|
7
|
+
* in `src/services/code/dag-orchestrator.ts`). It tells the sub-agent
|
|
8
8
|
* to read `package.json#scripts.test` first and use the project-local
|
|
9
9
|
* runner — never `npx <runner>` — so it cannot bypass the lockfile or
|
|
10
10
|
* spawn a network-bound tool call.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The Test Tool Detection block is prepended to every sub-agent prompt
|
|
5
5
|
* dispatched by peaks-loop (both the single-dispatch chokepoint in
|
|
6
6
|
* `src/cli/commands/dispatch-commands.ts` and the DAG-dispatch chokepoint
|
|
7
|
-
* in `src/services/
|
|
7
|
+
* in `src/services/code/dag-orchestrator.ts`). It tells the sub-agent
|
|
8
8
|
* to read `package.json#scripts.test` first and use the project-local
|
|
9
9
|
* runner — never `npx <runner>` — so it cannot bypass the lockfile or
|
|
10
10
|
* spawn a network-bound tool call.
|
|
@@ -223,8 +223,8 @@ export function generatePromotionStub(opts) {
|
|
|
223
223
|
}
|
|
224
224
|
// layer === 'C'
|
|
225
225
|
return {
|
|
226
|
-
snippet: `// src/services/
|
|
227
|
-
targetFiles: ['src/services/
|
|
226
|
+
snippet: `// src/services/code/mode-gate.ts\n// 1. Add to HardFloorCategory union: '${feedbackName}-rule'\n// 2. Add to HARD_FLOOR_CATEGORIES\n// 3. Wire shouldPauseAtGate to recognise the new category\n// Tests: tests/unit/services/code/<name>-hard-floor.test.ts (≥6 cases per AC-4)`,
|
|
227
|
+
targetFiles: ['src/services/code/mode-gate.ts', `tests/unit/services/code/${feedbackName}-hard-floor.test.ts`]
|
|
228
228
|
};
|
|
229
229
|
}
|
|
230
230
|
/**
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* jobId, done, total, currentSlice, lastCommitSha, updatedAt
|
|
11
11
|
* }
|
|
12
12
|
*
|
|
13
|
-
* The `peaks
|
|
13
|
+
* The `peaks code gate-step-08` hook reads this file in its case-1 path
|
|
14
14
|
* (job-shape.json says isJob=true) and surfaces `Next: slice #N+1 of M
|
|
15
15
|
* (<currentSlice>)` to stdout. The LLM cannot "wake up cold" — the
|
|
16
16
|
* next-slice context is mechanically injected on every Bash call.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* jobId, done, total, currentSlice, lastCommitSha, updatedAt
|
|
11
11
|
* }
|
|
12
12
|
*
|
|
13
|
-
* The `peaks
|
|
13
|
+
* The `peaks code gate-step-08` hook reads this file in its case-1 path
|
|
14
14
|
* (job-shape.json says isJob=true) and surfaces `Next: slice #N+1 of M
|
|
15
15
|
* (<currentSlice>)` to stdout. The LLM cannot "wake up cold" — the
|
|
16
16
|
* next-slice context is mechanically injected on every Bash call.
|
|
@@ -22,7 +22,7 @@ export declare function writeAtomic(filePath: string, prefs: ProjectPreferences)
|
|
|
22
22
|
* verbatim. v1's `agentShieldPrompt` and `loopAutonomousEnabled` were
|
|
23
23
|
* already present, so they carry through unchanged. The `fanout` field
|
|
24
24
|
* is new in v2 — it defaults to `{ defaultMode: 'fan-out' }` so the
|
|
25
|
-
* pre-v2 behavior (peak-
|
|
25
|
+
* pre-v2 behavior (peak-code SKILL instructed fan-out when ≥ 2 leaves)
|
|
26
26
|
* is preserved.
|
|
27
27
|
*/
|
|
28
28
|
export type MigrateResult = {
|
|
@@ -68,7 +68,7 @@ export interface ProjectPreferences {
|
|
|
68
68
|
*/
|
|
69
69
|
readonly schema_version: typeof PREFERENCES_SCHEMA_VERSION;
|
|
70
70
|
/**
|
|
71
|
-
* Slice 2026-06-28-
|
|
71
|
+
* Slice 2026-06-28-code-mode-bypass-fix: economyMode is a
|
|
72
72
|
* **MODEL-SELECTION** knob only — it chooses between the cheap
|
|
73
73
|
* configured provider (`getConfiguredExecutionModelId`) and the
|
|
74
74
|
* strongest planner/reviewer model (`STRONGEST_MODEL_ID`). It does
|
|
@@ -60,7 +60,7 @@ export declare function buildRdStandardsGateList(input: {
|
|
|
60
60
|
readonly missing: boolean;
|
|
61
61
|
}): ReadonlyArray<RdStandardGate>;
|
|
62
62
|
/**
|
|
63
|
-
* Single entry point for the RD / QA /
|
|
63
|
+
* Single entry point for the RD / QA / Code bootstrap. Returns the
|
|
64
64
|
* exit code + error code + diagnostic + gate list. The CLI wrapper is
|
|
65
65
|
* responsible for `process.stderr.write(diagnostic ?? '')` and
|
|
66
66
|
* `process.exit(result.exitCode)`.
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* G4 The remediation string is the exact copy-pasteable CLI invocation.
|
|
21
21
|
*
|
|
22
22
|
* This module is a pure-function helper. The `peaks rd` / `peaks qa` /
|
|
23
|
-
* `peaks
|
|
23
|
+
* `peaks code` runtime hooks call `resolveRdStartupStandardsCheck` at
|
|
24
24
|
* bootstrap and decide whether to write `process.stderr` + JSON envelope
|
|
25
25
|
* + exit. The bootstrap is intentionally side-effect-free here so unit
|
|
26
26
|
* tests can run it without spawning child processes.
|
|
@@ -112,7 +112,7 @@ export function buildRdStandardsGateList(input) {
|
|
|
112
112
|
];
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
-
* Single entry point for the RD / QA /
|
|
115
|
+
* Single entry point for the RD / QA / Code bootstrap. Returns the
|
|
116
116
|
* exit code + error code + diagnostic + gate list. The CLI wrapper is
|
|
117
117
|
* responsible for `process.stderr.write(diagnostic ?? '')` and
|
|
118
118
|
* `process.exit(result.exitCode)`.
|
|
@@ -86,7 +86,7 @@ export const seedCapabilityItems = [
|
|
|
86
86
|
capability('codegraph.project-indexing', 'codegraph', 'Codegraph Project Indexing', 'cli', 'project-analysis', ['engineer'], 'medium', 'peaks-rd-local-scan', 'Use Peaks RD local project scanning when codegraph is unavailable.', 'Codegraph Project Indexing', 'Codegraph 项目索引', 'Indexes a local project through the peaks codegraph execution boundary for role-skill analysis.', '通过 peaks codegraph 执行边界索引本地项目,辅助角色 skill 分析。'),
|
|
87
87
|
capability('codegraph.semantic-query', 'codegraph', 'Codegraph Semantic Query', 'cli', 'project-analysis', ['engineer'], 'medium', 'peaks-rd-local-scan', 'Use local Grep/Glob and RD scanning when codegraph semantic query is unavailable.', 'Codegraph Semantic Query', 'Codegraph 语义查询', 'Queries local symbols and project relationships for RD planning evidence.', '查询本地符号和项目关系,为 RD 规划提供证据。'),
|
|
88
88
|
capability('codegraph.impact-analysis', 'codegraph', 'Codegraph Impact Analysis', 'cli', 'impact-analysis', ['engineer', 'qa'], 'medium', 'peaks-rd-qa-impact-review', 'Use RD changed-file analysis and QA regression planning when codegraph affected output is unavailable.', 'Codegraph Impact Analysis', 'Codegraph 影响面分析', 'Analyzes likely impact for changed files so RD and QA can focus planning and regression scope.', '分析变更文件的可能影响面,帮助 RD 与 QA 聚焦规划和回归范围。'),
|
|
89
|
-
capability('codegraph.context-pack', 'codegraph', 'Codegraph Context Pack', 'cli', 'context-pack', ['engineer', 'qa', 'product'], 'medium', 'peaks-txt-context-capsule', 'Use Peaks TXT context capsules and role-skill handoffs when codegraph context output is unavailable.', 'Codegraph Context Pack', 'Codegraph 上下文包', 'Builds task-specific local context that
|
|
89
|
+
capability('codegraph.context-pack', 'codegraph', 'Codegraph Context Pack', 'cli', 'context-pack', ['engineer', 'qa', 'product'], 'medium', 'peaks-txt-context-capsule', 'Use Peaks TXT context capsules and role-skill handoffs when codegraph context output is unavailable.', 'Codegraph Context Pack', 'Codegraph 上下文包', 'Builds task-specific local context that Code, RD, and TXT can use as supporting evidence.', '生成任务相关的本地上下文,作为 Code、RD 与 TXT 的辅助证据。'),
|
|
90
90
|
capability('playwright-mcp.browser-validation', 'playwright-mcp', 'Playwright MCP Browser Validation', 'mcp', 'browser-validation', ['engineer', 'qa'], 'medium', 'manual-browser-test', 'Use local Playwright or manual browser verification.', 'Playwright Browser Validation', 'Playwright 浏览器验证', 'Validates UI flows through controlled browser automation.', '通过受控浏览器自动化验证 UI 流程。'),
|
|
91
91
|
capability('chrome-devtools-mcp.browser-debug', 'chrome-devtools-mcp', 'Chrome DevTools Browser Debug', 'mcp', 'browser-debug', ['engineer', 'qa'], 'medium', 'manual-devtools-inspection', 'Use browser screenshots, console logs, and network traces supplied by the user.', 'Chrome DevTools Debug', 'Chrome DevTools 调试', 'Inspects runtime UI, console, network, and performance behavior.', '检查运行时 UI、控制台、网络和性能行为。'),
|
|
92
92
|
capability('figma-context-mcp.design-context', 'figma-context-mcp', 'Figma Design Context', 'mcp', 'design-context', ['designer', 'engineer'], 'medium', 'manual-design-input', 'Ask the user for screenshots, tokens, or exported design notes.', 'Figma Design Context', 'Figma 设计上下文', 'Reads design context for UI implementation planning.', '读取设计上下文以辅助 UI 实现规划。'),
|
|
@@ -6,7 +6,7 @@ export const seedCapabilityLandingMappings = [
|
|
|
6
6
|
mapping({ capabilityId: 'codegraph.impact-analysis', sourceId: 'codegraph', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-rd', skillName: 'peaks-rd', guidance: 'Dry-run reference only: peaks-rd may use peaks codegraph affected --project <path> <files...> --json to inspect likely impact before slice planning and red-line checks when execution is approved.' }),
|
|
7
7
|
mapping({ capabilityId: 'codegraph.impact-analysis', sourceId: 'codegraph', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-qa', skillName: 'peaks-qa', guidance: 'Use affected output as regression-surface evidence only; QA validation and test evidence remain authoritative.' }),
|
|
8
8
|
mapping({ capabilityId: 'codegraph.context-pack', sourceId: 'codegraph', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-rd', skillName: 'peaks-rd', guidance: 'Dry-run reference only: peaks-rd may use peaks codegraph context --project <path> <task> to gather local evidence for RD analysis when execution is approved, without replacing standards dry-runs.' }),
|
|
9
|
-
mapping({ capabilityId: 'codegraph.context-pack', sourceId: 'codegraph', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-code', skillName: 'peaks-code', guidance: '
|
|
9
|
+
mapping({ capabilityId: 'codegraph.context-pack', sourceId: 'codegraph', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-code', skillName: 'peaks-code', guidance: 'Code may attach local context packs or affected summaries before role handoff so RD, QA, and TXT share the same project evidence.' }),
|
|
10
10
|
mapping({ capabilityId: 'codegraph.context-pack', sourceId: 'codegraph', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-txt', skillName: 'peaks-txt', guidance: 'TXT may summarize recorded codegraph context packs into handoffs while treating them as supporting evidence only.' }),
|
|
11
11
|
mapping({ capabilityId: 'playwright-mcp.browser-validation', sourceId: 'playwright-mcp', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-qa', skillName: 'peaks-qa', guidance: 'Use for browser and E2E validation after user-approved app targets are available.' }),
|
|
12
12
|
mapping({ capabilityId: 'chrome-devtools-mcp.browser-debug', sourceId: 'chrome-devtools-mcp', sourceGroup: 'access-repo', landingKind: 'skill', target: 'peaks-ui', skillName: 'peaks-ui', guidance: 'Use for runtime UI, console, network, and performance inspection.' }),
|
|
@@ -75,7 +75,7 @@ export function createRecommendationPlan(options) {
|
|
|
75
75
|
return {
|
|
76
76
|
intent: options.workflow,
|
|
77
77
|
workflow: options.workflow,
|
|
78
|
-
profile: '
|
|
78
|
+
profile: 'code-guided-auto',
|
|
79
79
|
audience: ['engineer'],
|
|
80
80
|
options: [recommendedOption],
|
|
81
81
|
requiredCapabilities,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Slice #009 / G5 RL-9 — user cancel must dispose in-flight dispatch records.
|
|
3
3
|
*
|
|
4
|
-
* When
|
|
4
|
+
* When Code's main loop receives SIGINT (Ctrl-C) or the user runs
|
|
5
5
|
* `peaks workflow cancel --rid <rid>`, the loop MUST mark in-flight
|
|
6
6
|
* dispatch records as `outcome: "cancelled"` + `disposed: true` +
|
|
7
7
|
* `disposedAt: now()` BEFORE exiting.
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* `completedAt: null`. Those are the ones that the LLM got a toolCall
|
|
11
11
|
* for but did not (yet) confirm completion.
|
|
12
12
|
*
|
|
13
|
-
* This module is the helper
|
|
14
|
-
* cancel command side-effect) is the
|
|
13
|
+
* This module is the helper Code calls. The wiring (signal listener,
|
|
14
|
+
* cancel command side-effect) is the Code main loop's responsibility;
|
|
15
15
|
* this module is the pure data operation.
|
|
16
16
|
*/
|
|
17
17
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
@@ -86,7 +86,7 @@ export declare function getSkillPresence(projectRootOverride?: string): SkillPre
|
|
|
86
86
|
*
|
|
87
87
|
* - `'no-presence'` — there is no presence file on disk.
|
|
88
88
|
* Not strictly "stale", but callers (peaks-code Step 1, `peaks
|
|
89
|
-
*
|
|
89
|
+
* code should-pause --step step-1-mode-select`) want to treat
|
|
90
90
|
* this case as "no opinion yet — must ask". Surfaced as
|
|
91
91
|
* `stale: true` with reason `'no-presence'` so the ask path is
|
|
92
92
|
* uniform.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 1.x → 2.0 detection service — TypeScript mirror of
|
|
3
3
|
* `scripts/install-skills.mjs:detect1xProjectState`.
|
|
4
4
|
*
|
|
5
|
-
* Slice: 2026-06-12-
|
|
5
|
+
* Slice: 2026-06-12-code-step-0-55-1x-detection.
|
|
6
6
|
*
|
|
7
7
|
* The canonical implementation lives in the .mjs postinstall
|
|
8
8
|
* (because the postinstall runs before any TS compile step).
|
|
@@ -63,7 +63,7 @@ export type PipelineVerification = {
|
|
|
63
63
|
*/
|
|
64
64
|
gateH?: 'pass' | 'fail';
|
|
65
65
|
/**
|
|
66
|
-
* Slice 2026-06-28-
|
|
66
|
+
* Slice 2026-06-28-code-mode-bypass-fix (defect #3): `true` when
|
|
67
67
|
* every evidence file resolved on the canonical path
|
|
68
68
|
* (`.peaks/_runtime/change/<sessionId>/...`). `false` when at least
|
|
69
69
|
* one evidence file resolved via a legacy fallback (`.peaks/<sessionId>/...`
|
|
@@ -26,7 +26,7 @@ async function findRequestFile(projectRoot, role, rid) {
|
|
|
26
26
|
const artifact = await showRequestArtifact({ projectRoot, role: role, requestId: rid });
|
|
27
27
|
if (artifact === null)
|
|
28
28
|
return null;
|
|
29
|
-
// Slice 2026-06-28-
|
|
29
|
+
// Slice 2026-06-28-code-mode-bypass-fix (defect #3): the legacy
|
|
30
30
|
// `showRequestArtifact` returns the FULL SCOPE (`_runtime/<sid>`)
|
|
31
31
|
// as `sessionId`, not just the trailing id segment. The canonical
|
|
32
32
|
// evidence lookup needs only the bare id (`.peaks/_runtime/change/<id>/`).
|
|
@@ -158,7 +158,7 @@ export async function verifyPipeline(options) {
|
|
|
158
158
|
// preferred filesystem scope; falling through to `options.rid` would
|
|
159
159
|
// make every missing-evidence path look like a per-rid scope dir.
|
|
160
160
|
const rdEvidenceDir = resolvedChangeId || options.sessionId || getSessionIdCanonical(options.projectRoot) || options.rid;
|
|
161
|
-
// Slice 2026-06-28-
|
|
161
|
+
// Slice 2026-06-28-code-mode-bypass-fix (defect #3): track whether
|
|
162
162
|
// every resolved evidence file landed on the canonical path. Drives
|
|
163
163
|
// the `usedCanonicalPath` envelope field. The flag stays `true` if
|
|
164
164
|
// no evidence file was resolved at all (nothing to be non-canonical
|
|
@@ -410,7 +410,7 @@ export async function verifyPipeline(options) {
|
|
|
410
410
|
: 'suffixed';
|
|
411
411
|
const gateC = allQaGatesPassed ? 'pass' : 'fail';
|
|
412
412
|
const gateH = allFeedbackGatesPassed ? 'pass' : 'fail';
|
|
413
|
-
// Slice 2026-06-28-
|
|
413
|
+
// Slice 2026-06-28-code-mode-bypass-fix (defect #3): `true` when
|
|
414
414
|
// every gate resolved on the canonical path; `false` when at least
|
|
415
415
|
// one fell back to a legacy form. QA / TXT surface the value so the
|
|
416
416
|
// user knows the legacy content must be moved into the canonical
|