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.
Files changed (115) hide show
  1. package/CHANGELOG.md +105 -87
  2. package/README-en.md +1 -1
  3. package/README.md +1 -1
  4. package/dist/src/cli/commands/{solo-commands.d.ts → code-commands.d.ts} +24 -24
  5. package/dist/src/cli/commands/{solo-commands.js → code-commands.js} +78 -78
  6. package/dist/src/cli/commands/core/skill-command.js +1 -1
  7. package/dist/src/cli/commands/dispatch-from-dag.js +1 -1
  8. package/dist/src/cli/commands/hook-handle.js +7 -7
  9. package/dist/src/cli/commands/job-commands.js +2 -2
  10. package/dist/src/cli/commands/session-auto-compact-hook-command.js +2 -2
  11. package/dist/src/cli/commands/sub-agent-shared.d.ts +1 -1
  12. package/dist/src/cli/commands/user-touchpoint-commands.d.ts +4 -4
  13. package/dist/src/cli/commands/user-touchpoint-commands.js +14 -14
  14. package/dist/src/cli/commands/workflow-commands.js +22 -22
  15. package/dist/src/cli/program.js +6 -6
  16. package/dist/src/services/artifacts/repair-cycle-service.js +1 -1
  17. package/dist/src/services/audit/enforcers/active-skill-resolver.d.ts +1 -1
  18. package/dist/src/services/audit/enforcers/active-skill-resolver.js +1 -1
  19. package/dist/src/services/audit/enforcers/{solo-code-ban.d.ts → code-ban.d.ts} +6 -6
  20. package/dist/src/services/audit/enforcers/{solo-code-ban.js → code-ban.js} +6 -6
  21. package/dist/src/services/audit/red-line-catalog.d.ts +2 -2
  22. package/dist/src/services/audit/red-line-catalog.js +5 -5
  23. package/dist/src/services/audit/types.d.ts +2 -2
  24. package/dist/src/services/{solo → code}/auto-compact-orchestrator.d.ts +1 -1
  25. package/dist/src/services/{solo → code}/auto-compact-orchestrator.js +3 -3
  26. package/dist/src/services/{solo → code}/dag-orchestrator.d.ts +1 -1
  27. package/dist/src/services/{solo → code}/dag-orchestrator.js +1 -1
  28. package/dist/src/services/{solo → code}/emit-handoff.d.ts +1 -1
  29. package/dist/src/services/{solo → code}/emit-handoff.js +1 -1
  30. package/dist/src/services/{solo → code}/job-shape-decision.d.ts +1 -1
  31. package/dist/src/services/{solo → code}/job-shape-decision.js +5 -5
  32. package/dist/src/services/{solo → code}/mode-gate.d.ts +9 -9
  33. package/dist/src/services/{solo → code}/mode-gate.js +5 -5
  34. package/dist/src/services/{solo → code}/post-compact-detector.d.ts +3 -3
  35. package/dist/src/services/{solo → code}/post-compact-detector.js +4 -4
  36. package/dist/src/services/{solo → code}/step-08-gate.d.ts +4 -4
  37. package/dist/src/services/{solo → code}/step-08-gate.js +4 -4
  38. package/dist/src/services/{solo → code}/user-touchpoint-classifier.d.ts +1 -1
  39. package/dist/src/services/{solo → code}/user-touchpoint-classifier.js +1 -1
  40. package/dist/src/services/context/auto-compact-dispatcher.d.ts +2 -2
  41. package/dist/src/services/context/auto-compact-dispatcher.js +2 -2
  42. package/dist/src/services/context/auto-compact-types.d.ts +1 -1
  43. package/dist/src/services/dispatch/slice-dag.d.ts +2 -2
  44. package/dist/src/services/dispatch/test-tool-detection.d.ts +1 -1
  45. package/dist/src/services/dispatch/test-tool-detection.js +1 -1
  46. package/dist/src/services/feedback/feedback-promotion-service.js +2 -2
  47. package/dist/src/services/job/job-progress-store.d.ts +1 -1
  48. package/dist/src/services/job/job-progress-store.js +1 -1
  49. package/dist/src/services/preferences/preferences-service.d.ts +1 -1
  50. package/dist/src/services/preferences/preferences-types.d.ts +1 -1
  51. package/dist/src/services/rd/standards-diagnostic.d.ts +1 -1
  52. package/dist/src/services/rd/standards-diagnostic.js +2 -2
  53. package/dist/src/services/recommendations/capability-seed-items.js +1 -1
  54. package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
  55. package/dist/src/services/recommendations/recommendation-service.js +1 -1
  56. package/dist/src/services/refactor/refactor-service.d.ts +1 -1
  57. package/dist/src/services/signal/cancel-handler.js +3 -3
  58. package/dist/src/services/skill/resume-detector.js +1 -1
  59. package/dist/src/services/skills/skill-presence-service.d.ts +1 -1
  60. package/dist/src/services/upgrade/1x-detector-service.js +1 -1
  61. package/dist/src/services/workflow/pipeline-verify-service.d.ts +1 -1
  62. package/dist/src/services/workflow/pipeline-verify-service.js +3 -3
  63. package/dist/src/services/workflow/workflow-autonomous-service.d.ts +3 -3
  64. package/dist/src/services/workflow/workflow-autonomous-service.js +2 -2
  65. package/dist/src/services/workflow/workflow-router-service.d.ts +6 -6
  66. package/dist/src/services/workflow/workflow-router-service.js +33 -33
  67. package/dist/src/services/workspace/claude-settings-template.d.ts +1 -1
  68. package/dist/src/services/workspace/claude-settings-template.js +5 -5
  69. package/dist/src/shared/version.d.ts +1 -1
  70. package/dist/src/shared/version.js +1 -1
  71. package/output-styles/peaks-skill-swarm.md +3 -3
  72. package/package.json +1 -1
  73. package/skills/bee/peaks-qa/SKILL.md +1 -1
  74. package/skills/bee/peaks-qa/references/artifact-per-request.md +3 -3
  75. package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +6 -6
  76. package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +1 -1
  77. package/skills/bee/peaks-rd/references/rd-runbook.md +1 -1
  78. package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +11 -11
  79. package/skills/bee/peaks-rd/references/rd-transition-gates.md +1 -1
  80. package/skills/bee/peaks-sc/SKILL.md +1 -1
  81. package/skills/bee/peaks-txt/SKILL.md +3 -3
  82. package/skills/bee/peaks-ui/SKILL.md +8 -8
  83. package/skills/peaks-code/SKILL.md +21 -21
  84. package/skills/peaks-code/references/anchoring-and-session-info.md +2 -2
  85. package/skills/peaks-code/references/artifact-contracts.md +1 -1
  86. package/skills/peaks-code/references/boundaries.md +3 -3
  87. package/skills/peaks-code/references/codegraph-orchestration.md +1 -1
  88. package/skills/peaks-code/references/dag-orchestrator.md +7 -7
  89. package/skills/peaks-code/references/external-references.md +2 -2
  90. package/skills/peaks-code/references/fanout-mandatory.md +3 -3
  91. package/skills/peaks-code/references/fast-mode.md +2 -2
  92. package/skills/peaks-code/references/frontend-only-mode.md +9 -9
  93. package/skills/peaks-code/references/job-loop.md +1 -1
  94. package/skills/peaks-code/references/local-artifact-workspace.md +2 -2
  95. package/skills/peaks-code/references/micro-cycle.md +14 -14
  96. package/skills/peaks-code/references/mode-selection-with-stale-presence.md +5 -5
  97. package/skills/peaks-code/references/mode-selection.md +3 -3
  98. package/skills/peaks-code/references/openspec-workflow.md +16 -16
  99. package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
  100. package/skills/peaks-code/references/quality-gate-cheatsheet.md +1 -1
  101. package/skills/peaks-code/references/refactor-mode.md +1 -1
  102. package/skills/peaks-code/references/runbook.md +15 -15
  103. package/skills/peaks-code/references/step-0-55-1x-detection.md +1 -1
  104. package/skills/peaks-code/references/step-0-8-gate.md +11 -11
  105. package/skills/peaks-code/references/sub-agent-dispatch.md +8 -8
  106. package/skills/peaks-code/references/swarm-dispatch-contract.md +17 -17
  107. package/skills/peaks-code/references/workflow-gates-and-types.md +2 -2
  108. package/skills/peaks-code/references/workflow.md +5 -5
  109. package/skills/peaks-resume/SKILL.md +2 -2
  110. package/skills/peaks-status/SKILL.md +2 -2
  111. package/skills/peaks-test/SKILL.md +2 -2
  112. /package/dist/src/services/{solo → code}/batch-heartbeat-poller.d.ts +0 -0
  113. /package/dist/src/services/{solo → code}/batch-heartbeat-poller.js +0 -0
  114. /package/dist/src/services/{solo → code}/status-line-renderer.d.ts +0 -0
  115. /package/dist/src/services/{solo → code}/status-line-renderer.js +0 -0
@@ -193,7 +193,7 @@ export function registerSkillCommand(program, io) {
193
193
  printResult(io, ok('skill.presence:clear', { active: false, removed, projectContextUpdated: true }), options.json);
194
194
  });
195
195
  // Slice 002 (v2.15.0) — AC-1: presence staleness detector.
196
- // peaks-code Step 1 (and `peaks solo should-pause --step
196
+ // peaks-code Step 1 (and `peaks code should-pause --step
197
197
  // step-1-mode-select`) calls this to decide whether the recorded
198
198
  // `mode` field can be trusted or whether the LLM must AskUserQuestion.
199
199
  addJsonOption(skill
@@ -54,7 +54,7 @@ export async function runDispatchFromDag(role, options, asJson, io) {
54
54
  const [{ readFileSync }, sliceDagMod, dagOrchestratorMod, contractStoreMod] = await Promise.all([
55
55
  import('node:fs'),
56
56
  import('../../services/dispatch/slice-dag.js'),
57
- import('../../services/solo/dag-orchestrator.js'),
57
+ import('../../services/code/dag-orchestrator.js'),
58
58
  import('../../services/dispatch/contract-store.js')
59
59
  ]);
60
60
  const { validateDag, topologicalLevels, isSliceComplexity } = sliceDagMod;
@@ -2,7 +2,7 @@ import { addJsonOption, printResult } from '../cli-helpers.js';
2
2
  import { detectIdeFromContext, parseAdapterStdin, parseClaudeShapeStdin, pluckObject, pluckString } from '../../services/ide/hook-translator.js';
3
3
  import { buildCanonicalHook, formatDecisionResponse } from '../../services/ide/hook-protocol.js';
4
4
  import { getAdapter } from '../../services/ide/ide-registry.js';
5
- import { evaluateSoloCodeBan } from '../../services/audit/enforcers/solo-code-ban.js';
5
+ import { evaluateCodeBan } from '../../services/audit/enforcers/code-ban.js';
6
6
  import { isRootWrite } from '../../services/audit/enforcers/no-root-pollution.js';
7
7
  import { checkLoginGate } from '../../services/audit/enforcers/login-gate.js';
8
8
  import { resolveActiveSkillForCaller } from '../../services/audit/enforcers/active-skill-resolver.js';
@@ -82,17 +82,17 @@ export function registerHookHandleCommand(program, io) {
82
82
  // Dispatch by toolName. For slice #1+, we only handle Bash. Task tool sub-agent dispatch goes through `peaks sub-agent dispatch` (slice #009) and does not need a hook entry.
83
83
  // Other tools: allow (no-op; future events will be added here).
84
84
  if (hook.toolName === 'Bash' && typeof fallbackCommand === 'string' && fallbackCommand.trim().length > 0) {
85
- // L2.1 P0 #1: solo-code-ban. Deny `git commit` / `git apply` from peaks-* skills
85
+ // L2.1 P0 #1: code-commit-ban. Deny `git commit` / `git apply` from peaks-* skills
86
86
  // BEFORE the SOP gate runs. The active skill is read from the per-caller
87
87
  // active-skill file (see active-skill-resolver.ts).
88
88
  const activeSkill = resolveActiveSkillForCaller(projectRoot);
89
89
  if (activeSkill.skill !== null) {
90
- const soloDecision = evaluateSoloCodeBan({ skill: activeSkill.skill, command: fallbackCommand });
91
- if (soloDecision.denied) {
92
- const formatted = formatDecisionResponse(ide, 'deny', soloDecision.reason);
90
+ const codeDecision = evaluateCodeBan({ skill: activeSkill.skill, command: fallbackCommand });
91
+ if (codeDecision.denied) {
92
+ const formatted = formatDecisionResponse(ide, 'deny', codeDecision.reason);
93
93
  emitDecision(io, formatted.stdout);
94
94
  if (options.json === true) {
95
- emitHint(io, JSON.stringify(ok('hook.handle', { ide, tool: hook.toolName, decision: 'deny', reason: soloDecision.reason, enforcer: 'solo-code-ban' })));
95
+ emitHint(io, JSON.stringify(ok('hook.handle', { ide, tool: hook.toolName, decision: 'deny', reason: codeDecision.reason, enforcer: 'code-ban' })));
96
96
  }
97
97
  return;
98
98
  }
@@ -109,7 +109,7 @@ export function registerHookHandleCommand(program, io) {
109
109
  return;
110
110
  }
111
111
  }
112
- // L2.2 P1 #1: login-gate. After solo-code-ban + gate-enforce pass,
112
+ // L2.2 P1 #1: login-gate. After code-commit-ban + gate-enforce pass,
113
113
  // flag destructive patterns (uninstall, force-push, --force, --hard,
114
114
  // rm -rf) so the LLM gets a soft warning (still allow). The user
115
115
  // gets the warning via the warn channel; the command proceeds.
@@ -174,7 +174,7 @@ export function registerJobCommands(program, io = { stdout: (t) => process.stdou
174
174
  await orch.checkpointDone({ jobId: parsed.data.jobId, sliceId: parsed.data.sliceId, ...(parsed.data.commitSha ? { commitSha: parsed.data.commitSha } : {}) });
175
175
  // v3.1.2: after each --state done, mirror slice progress to
176
176
  // .peaks/_runtime/<sessionId>/job/<jid>/progress.json so the
177
- // next LLM turn (or peaks solo gate-step-08 hook) can read it.
177
+ // next LLM turn (or peaks code gate-step-08 hook) can read it.
178
178
  const project = projectRoot(opts);
179
179
  const sessId = jobRoot.sessionId;
180
180
  const state = orch.status(parsed.data.jobId);
@@ -238,7 +238,7 @@ export function registerJobCommands(program, io = { stdout: (t) => process.stdou
238
238
  });
239
239
  addJsonOption(job.commands.find(c => c.name() === 'resume'));
240
240
  // v3.1.2: read the on-disk slice progress mirror written by `peaks
241
- // job checkpoint --state done`. Used by peaks solo gate-step-08 and
241
+ // job checkpoint --state done`. Used by peaks code gate-step-08 and
242
242
  // by peaks-code Step 0.7 (resume) to surface `Next: slice #N of M
243
243
  // (<currentSlice>)` without re-deriving from state.json.
244
244
  job
@@ -86,7 +86,7 @@ export function registerSessionAutoCompactHookCommand(session) {
86
86
  if (probe.ratio < RED_LINE_RATIO) {
87
87
  // Below red line → exit 0 silent. The orchestrator's
88
88
  // pre-compact zone (0.85–0.95) is handled out-of-band by
89
- // the LLM firing `peaks solo auto-compact --execute`; the
89
+ // the LLM firing `peaks code auto-compact --execute`; the
90
90
  // hook only fires on the synchronous red-line path.
91
91
  return;
92
92
  }
@@ -102,7 +102,7 @@ export function registerSessionAutoCompactHookCommand(session) {
102
102
  // binary), `spawn` raises ENOENT. Catching this MUST NOT crash
103
103
  // the runner's tool call — the hook must exit 0 silently with
104
104
  // a one-line stderr hint so the runner keeps working. The user
105
- // can then run `/compact` manually (or `peaks solo auto-compact`
105
+ // can then run `/compact` manually (or `peaks code auto-compact`
106
106
  // from another terminal).
107
107
  try {
108
108
  const child = spawn('claude', ['--compact'], {
@@ -71,7 +71,7 @@ export type AwaitOptions = {
71
71
  * to keep the warm-path dispatch CLI cold-start fast (slice 9).
72
72
  */
73
73
  export type SliceDagModule = typeof import('../../services/dispatch/slice-dag.js');
74
- export type DagOrchestratorModule = typeof import('../../services/solo/dag-orchestrator.js');
74
+ export type DagOrchestratorModule = typeof import('../../services/code/dag-orchestrator.js');
75
75
  export type ContractStoreModule = typeof import('../../services/dispatch/contract-store.js');
76
76
  /**
77
77
  * Validate a role string. Returns `null` when valid, otherwise the
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * v2.15.0 follow-up — G4: user touchpoint CLI.
3
3
  *
4
- * - `peaks solo gate-classify --step <step-id>` — classify a single
5
- * Solo gate (business / tech / mode-selection / commit-boundary /
4
+ * - `peaks code gate-classify --step <step-id>` — classify a single
5
+ * Code gate (business / tech / mode-selection / commit-boundary /
6
6
  * commit-floor)
7
- * - `peaks solo user-touchpoints` — list all gates the
7
+ * - `peaks code user-touchpoints` — list all gates the
8
8
  * user must review (vs AI auto-decides in full-auto)
9
- * - `peaks solo commit-boundary-actions` — list the 5
9
+ * - `peaks code commit-boundary-actions` — list the 5
10
10
  * hard-floor commit actions (push / tag / publish / global
11
11
  * install)
12
12
  *
@@ -1,45 +1,45 @@
1
1
  /**
2
2
  * v2.15.0 follow-up — G4: user touchpoint CLI.
3
3
  *
4
- * - `peaks solo gate-classify --step <step-id>` — classify a single
5
- * Solo gate (business / tech / mode-selection / commit-boundary /
4
+ * - `peaks code gate-classify --step <step-id>` — classify a single
5
+ * Code gate (business / tech / mode-selection / commit-boundary /
6
6
  * commit-floor)
7
- * - `peaks solo user-touchpoints` — list all gates the
7
+ * - `peaks code user-touchpoints` — list all gates the
8
8
  * user must review (vs AI auto-decides in full-auto)
9
- * - `peaks solo commit-boundary-actions` — list the 5
9
+ * - `peaks code commit-boundary-actions` — list the 5
10
10
  * hard-floor commit actions (push / tag / publish / global
11
11
  * install)
12
12
  *
13
13
  * Surfaces the 12 Gaps positioning memory rule:
14
14
  * "user 在循环里 = 业务/产品审阅者,不参与技术决策"
15
15
  */
16
- import { aiAutoDecidesGates, classifyGate, COMMIT_BOUNDARY_ACTIONS_LIST, userMustReviewGates } from '../../services/solo/user-touchpoint-classifier.js';
16
+ import { aiAutoDecidesGates, classifyGate, COMMIT_BOUNDARY_ACTIONS_LIST, userMustReviewGates } from '../../services/code/user-touchpoint-classifier.js';
17
17
  import { fail, ok } from '../../shared/result.js';
18
18
  import { addJsonOption, printResult } from '../cli-helpers.js';
19
19
  export function registerUserTouchpointCommands(program, io) {
20
20
  // G4 commands are registered as TOP-LEVEL commands (not sub-commands
21
- // of `peaks solo`) because `peaks solo` is a SKILL (consumed by the
21
+ // of `peaks code`) because `peaks code` is a SKILL (consumed by the
22
22
  // LLM in SKILL.md), not a CLI command. Top-level names: gate-classify /
23
23
  // user-touchpoints / commit-boundary-actions.
24
24
  //
25
- // We do NOT create a new `peaks solo` CLI command here because that
25
+ // We do NOT create a new `peaks code` CLI command here because that
26
26
  // would conflict with the peaks-code skill presence tracking (see
27
27
  // `src/services/skills/skill-presence-service.ts`).
28
28
  addJsonOption(program
29
29
  .command('gate-classify')
30
- .description('v2.15.0 follow-up G4: classify a single Solo gate by its decision kind: ' +
30
+ .description('v2.15.0 follow-up G4: classify a single Code gate by its decision kind: ' +
31
31
  'business / tech / mode-selection / commit-boundary / commit-floor. ' +
32
32
  'Returns null when the step is unknown.')
33
33
  .requiredOption('--step <step-id>', 'step id (e.g. step-1-mode-select, phase-2-prd-confirm)')).action((opts) => {
34
34
  const c = classifyGate(opts.step);
35
35
  if (c === null) {
36
- printResult(io, fail('solo.gate-classify', 'UNKNOWN_STEP', `unknown step "${opts.step}"`, {}, [
37
- 'Run `peaks solo user-touchpoints` to list all known steps.'
36
+ printResult(io, fail('code.gate-classify', 'UNKNOWN_STEP', `unknown step "${opts.step}"`, {}, [
37
+ 'Run `peaks code user-touchpoints` to list all known steps.'
38
38
  ]), opts.json ?? false);
39
39
  process.exitCode = 1;
40
40
  return;
41
41
  }
42
- printResult(io, ok('solo.gate-classify', { classification: c }, [], [
42
+ printResult(io, ok('code.gate-classify', { classification: c }, [], [
43
43
  c.userShouldReview === 'always'
44
44
  ? 'User must review this gate in all modes.'
45
45
  : c.userShouldReview === 'business-only'
@@ -49,12 +49,12 @@ export function registerUserTouchpointCommands(program, io) {
49
49
  });
50
50
  addJsonOption(program
51
51
  .command('user-touchpoints')
52
- .description('List all Solo gates the user must review. The 12 Gaps positioning ' +
52
+ .description('List all Code gates the user must review. The 12 Gaps positioning ' +
53
53
  'memory: user 在循环里 = 业务/产品审阅者,不参与技术决策。 ' +
54
54
  'These are the only gates where the user is asked to decide.')).action((opts) => {
55
55
  const must = userMustReviewGates();
56
56
  const auto = aiAutoDecidesGates();
57
- printResult(io, ok('solo.user-touchpoints', {
57
+ printResult(io, ok('code.user-touchpoints', {
58
58
  userMustReview: must,
59
59
  aiAutoDecides: auto,
60
60
  counts: {
@@ -71,7 +71,7 @@ export function registerUserTouchpointCommands(program, io) {
71
71
  .description('List the 5 commit-boundary hard-floor actions. These are the ' +
72
72
  'actions that PAUSE even in full-auto (v2.15.0 slice 002 AC-4 rule: ' +
73
73
  '"full-auto 只做到 commit"). The user is always asked to confirm.')).action((opts) => {
74
- printResult(io, ok('solo.commit-boundary-actions', { actions: COMMIT_BOUNDARY_ACTIONS_LIST }, [], [
74
+ printResult(io, ok('code.commit-boundary-actions', { actions: COMMIT_BOUNDARY_ACTIONS_LIST }, [], [
75
75
  'Even in full-auto, the user must explicitly confirm these actions.'
76
76
  ]), opts.json ?? false);
77
77
  });
@@ -1,6 +1,6 @@
1
1
  import { createRdSwarmPlan } from '../../services/rd/rd-service.js';
2
2
  import { createTechPlan, getTechStatus } from '../../services/tech/tech-service.js';
3
- import { createWorkflowRouterPlan, isSoloMode, isWorkflowMode } from '../../services/workflow/workflow-router-service.js';
3
+ import { createWorkflowRouterPlan, isCodeMode, isWorkflowMode } from '../../services/workflow/workflow-router-service.js';
4
4
  import { createAutonomousWorkflowPlan } from '../../services/workflow/workflow-autonomous-service.js';
5
5
  import { writeAutonomousResumeArtifacts } from '../../services/workflow/autonomous-resume-writer.js';
6
6
  import { createRecommendationPlan } from '../../services/recommendations/recommendation-service.js';
@@ -87,21 +87,21 @@ function validatePlanningInput(goal) {
87
87
  throw new Error('Goal must be non-empty');
88
88
  }
89
89
  }
90
- function parseSoloMode(io, command, mode, soloMode, asJson) {
91
- if (mode !== 'solo' && soloMode) {
92
- printResult(io, fail(command, 'SOLO_MODE_REQUIRES_SOLO_WORKFLOW', '--solo-mode can only be used with --mode solo', {}, ['Remove --solo-mode or use --mode solo']), asJson);
90
+ function parseCodeMode(io, command, mode, codeMode, asJson) {
91
+ if (mode !== 'code' && codeMode) {
92
+ printResult(io, fail(command, 'CODE_MODE_REQUIRES_CODE_WORKFLOW', '--code-mode can only be used with --mode code', {}, ['Remove --code-mode or use --mode code']), asJson);
93
93
  process.exitCode = 1;
94
94
  return null;
95
95
  }
96
- if (mode !== 'solo' || !soloMode) {
96
+ if (mode !== 'code' || !codeMode) {
97
97
  return undefined;
98
98
  }
99
- if (!isSoloMode(soloMode)) {
100
- printResult(io, fail(command, 'UNSUPPORTED_SOLO_MODE', `Unsupported solo mode ${soloMode}`, {}, ['Use --solo-mode full-auto, guided, or rnd']), asJson);
99
+ if (!isCodeMode(codeMode)) {
100
+ printResult(io, fail(command, 'UNSUPPORTED_CODE_MODE', `Unsupported code mode ${codeMode}`, {}, ['Use --code-mode full-auto, guided, or rnd']), asJson);
101
101
  process.exitCode = 1;
102
102
  return null;
103
103
  }
104
- return soloMode;
104
+ return codeMode;
105
105
  }
106
106
  function runTechPlan(io, options) {
107
107
  if (options.dryRun === false) {
@@ -145,15 +145,15 @@ function runWorkflowRoute(io, options) {
145
145
  return;
146
146
  }
147
147
  if (!isWorkflowMode(options.mode)) {
148
- printResult(io, fail('workflow.route', 'UNSUPPORTED_WORKFLOW_MODE', `Unsupported workflow mode ${options.mode}`, {}, ['Use --mode solo or --mode team']), options.json);
148
+ printResult(io, fail('workflow.route', 'UNSUPPORTED_WORKFLOW_MODE', `Unsupported workflow mode ${options.mode}`, {}, ['Use --mode code or --mode team']), options.json);
149
149
  process.exitCode = 1;
150
150
  return;
151
151
  }
152
152
  const maxWorkers = parseMaxWorkers(io, 'workflow.route', options.maxWorkers, options.json);
153
153
  if (maxWorkers === null)
154
154
  return;
155
- const soloMode = parseSoloMode(io, 'workflow.route', options.mode, options.soloMode, options.json);
156
- if (soloMode === null)
155
+ const codeMode = parseCodeMode(io, 'workflow.route', options.mode, options.codeMode, options.json);
156
+ if (codeMode === null)
157
157
  return;
158
158
  try {
159
159
  validatePlanningInput(options.goal);
@@ -162,7 +162,7 @@ function runWorkflowRoute(io, options) {
162
162
  sessionId: '',
163
163
  goal: options.goal,
164
164
  mode: options.mode,
165
- ...(soloMode ? { soloMode } : {}),
165
+ ...(codeMode ? { codeMode } : {}),
166
166
  maxWorkers,
167
167
  dryRun: true,
168
168
  config: readConfig(),
@@ -181,15 +181,15 @@ function runAutonomousWorkflow(io, options) {
181
181
  return;
182
182
  }
183
183
  if (!isWorkflowMode(options.mode)) {
184
- printResult(io, fail('workflow.autonomous', 'UNSUPPORTED_WORKFLOW_MODE', `Unsupported workflow mode ${options.mode}`, {}, ['Use --mode solo or --mode team']), options.json);
184
+ printResult(io, fail('workflow.autonomous', 'UNSUPPORTED_WORKFLOW_MODE', `Unsupported workflow mode ${options.mode}`, {}, ['Use --mode code or --mode team']), options.json);
185
185
  process.exitCode = 1;
186
186
  return;
187
187
  }
188
188
  const maxWorkers = parseMaxWorkers(io, 'workflow.autonomous', options.maxWorkers, options.json);
189
189
  if (maxWorkers === null)
190
190
  return;
191
- const soloMode = parseSoloMode(io, 'workflow.autonomous', options.mode, options.soloMode, options.json);
192
- if (soloMode === null)
191
+ const codeMode = parseCodeMode(io, 'workflow.autonomous', options.mode, options.codeMode, options.json);
192
+ if (codeMode === null)
193
193
  return;
194
194
  try {
195
195
  validatePlanningInput(options.goal);
@@ -198,7 +198,7 @@ function runAutonomousWorkflow(io, options) {
198
198
  sessionId: '',
199
199
  goal: options.goal,
200
200
  mode: options.mode,
201
- ...(soloMode ? { soloMode } : {}),
201
+ ...(codeMode ? { codeMode } : {}),
202
202
  maxWorkers,
203
203
  dryRun: true,
204
204
  config: readConfig(),
@@ -300,9 +300,9 @@ function addTechStatusOptions(command) {
300
300
  function addWorkflowRouteOptions(command, description) {
301
301
  return addJsonOption(command
302
302
  .description(description)
303
- .requiredOption('--mode <mode>', 'workflow mode: solo or team')
303
+ .requiredOption('--mode <mode>', 'workflow mode: code or team')
304
304
  .requiredOption('--goal <goal>', 'planning goal')
305
- .option('--solo-mode <mode>', 'solo mode: full-auto, guided, or rnd')
305
+ .option('--code-mode <mode>', 'code mode: full-auto, guided, or rnd')
306
306
  .option('--max-workers <count>', 'maximum worker count', '40')
307
307
  .option('--dry-run', 'preview without writing files', true)
308
308
  .option('--no-dry-run', 'unsupported: do not execute workflow planning from this CLI'));
@@ -330,7 +330,7 @@ function addAutonomousResumeInitOptions(command) {
330
330
  export function registerWorkflowCommands(program, io) {
331
331
  const refactor = program.command('refactor').description('Plan a Peaks refactor run without modifying code');
332
332
  addJsonOption(refactor
333
- .option('--solo', 'use peaks-code orchestration mode')
333
+ .option('--code', 'use peaks-code orchestration mode')
334
334
  .option('--rd', 'use peaks-rd direct mode')
335
335
  .option('--dry-run', 'print gates and required artifacts', true)
336
336
  .option('--no-dry-run', 'unsupported: do not modify code from this command')).action((options) => {
@@ -338,12 +338,12 @@ export function registerWorkflowCommands(program, io) {
338
338
  failUnsupportedNonDryRun(io, 'refactor', options.json);
339
339
  return;
340
340
  }
341
- if (options.solo && options.rd) {
342
- printResult(io, fail('refactor', 'CONFLICTING_REFACTOR_MODE', 'Choose either --solo or --rd, not both', {}, ['Run peaks refactor --solo --dry-run']), options.json);
341
+ if (options.code && options.rd) {
342
+ printResult(io, fail('refactor', 'CONFLICTING_REFACTOR_MODE', 'Choose either --code or --rd, not both', {}, ['Run peaks refactor --code --dry-run']), options.json);
343
343
  process.exitCode = 1;
344
344
  return;
345
345
  }
346
- const mode = options.rd ? 'rd' : 'solo';
346
+ const mode = options.rd ? 'rd' : 'code';
347
347
  printResult(io, ok('refactor', createRefactorDryRun(mode), [], ['This dry run never edits code']), options.json);
348
348
  });
349
349
  const tech = program.command('tech').description('Plan and inspect technical dry-run gates');
@@ -64,7 +64,7 @@ import { registerLogCommands } from './commands/log-commands.js';
64
64
  import { registerQaCommands } from './commands/qa-commands.js';
65
65
  import { registerTestCommands } from './commands/test-commands.js';
66
66
  import { registerPlaywrightCommands } from './commands/playwright-commands.js';
67
- import { registerSoloCommands } from './commands/solo-commands.js';
67
+ import { registerCodeCommands } from './commands/code-commands.js';
68
68
  import { registerMutCommands } from './commands/mut-commands.js';
69
69
  import { registerFixtureCommands } from './commands/fixture-commands.js';
70
70
  import { registerReviewerCommands } from './commands/reviewer-commands.js';
@@ -295,7 +295,7 @@ Run peaks (no arguments) for a quickstart. You likely want one of:
295
295
  // command conflict (peaks-loop-when-adding-a-new-subcommand-check-for-existing-top-level-first).
296
296
  // Slice #14: peaks loop * + peaks goal compose — L4 Agent Loop sub-features.
297
297
  registerLoopCommands(program, io);
298
- // Slice v3.0.0 loop-eng-native-solo-a-b: peaks workflow run|plan|lint
298
+ // Slice v3.0.0 loop-eng-native-code-a-b: peaks workflow run|plan|lint
299
299
  // + peaks loop eval. Wraps the existing workflow + loop groups so the
300
300
  // add-a-new-subcommand-check-for-existing-top-level-first rule is honoured.
301
301
  registerWorkflowEvalCommands(program, io);
@@ -321,10 +321,10 @@ Run peaks (no arguments) for a quickstart. You likely want one of:
321
321
  // Slice 2026-06-17-2.5.0-sub-fix-C: `peaks playwright start|ls|stop`
322
322
  // (multi-terminal Playwright MCP lifecycle).
323
323
  registerPlaywrightCommands(program, io);
324
- // Slice 2 (peaks-code fast mode): `peaks solo plan [--fast] <change-id>`
325
- // v2.11.0 Group F (D5 + D7): also registers `peaks solo should-pause` and
326
- // `peaks solo post-compact-detect` for runtime-friction probes.
327
- registerSoloCommands(program, io);
324
+ // Slice 2 (peaks-code fast mode): `peaks code plan [--fast] <change-id>`
325
+ // v2.11.0 Group F (D5 + D7): also registers `peaks code should-pause` and
326
+ // `peaks code post-compact-detect` for runtime-friction probes.
327
+ registerCodeCommands(program, io);
328
328
  // Plan 2 / Task 6: `peaks mut run|mutants|asserts|report` — mutation
329
329
  // testing + assertion validity scan (spec §4.2 / §7). The
330
330
  // production Stryker invoker is wired here; tests use the
@@ -1,6 +1,6 @@
1
1
  import { showRequestArtifact } from './request-artifact-service.js';
2
2
  const DEFAULT_MAX_CYCLES = 3;
3
- // Matches transition notes Solo writes during repair routing.
3
+ // Matches transition notes Code writes during repair routing.
4
4
  // Format example:
5
5
  // - transition note (2026-05-25T08:00:00.000Z): QA return-to-rd cycle 1: failing acceptance items A, B
6
6
  // - transition note (2026-05-25T09:00:00.000Z): QA cycle 2: regression in module X
@@ -2,7 +2,7 @@
2
2
  * active-skill-resolver — utility for hook enforcers.
3
3
  *
4
4
  * Resolves the active peak skill name for the current session, so hook
5
- * enforcers (e.g. solo-code-ban) can decide whether to fire.
5
+ * enforcers (e.g. code-ban) can decide whether to fire.
6
6
  *
7
7
  * Per `src/services/session/caller-id-types.ts`: the active-skill file is
8
8
  * at `.peaks/_runtime/<peakSessionId>/active-skill-<callerId>.json`.
@@ -2,7 +2,7 @@
2
2
  * active-skill-resolver — utility for hook enforcers.
3
3
  *
4
4
  * Resolves the active peak skill name for the current session, so hook
5
- * enforcers (e.g. solo-code-ban) can decide whether to fire.
5
+ * enforcers (e.g. code-ban) can decide whether to fire.
6
6
  *
7
7
  * Per `src/services/session/caller-id-types.ts`: the active-skill file is
8
8
  * at `.peaks/_runtime/<peakSessionId>/active-skill-<callerId>.json`.
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Solo-code-ban enforcer — PreToolUse Bash guard.
2
+ * Code-commit-ban enforcer — PreToolUse Bash guard.
3
3
  *
4
4
  * Per L2 redesign §5.4. Deny `git commit` or `git apply` invocations from
5
- * a peaks-* skill. The Solo Code-Change Red Line says peaks-code / peaks-rd
5
+ * a peaks-* skill. The Code Commit Ban Red Line says peaks-code / peaks-rd
6
6
  * are orchestrators, not implementers; the actual `git commit` step must
7
7
  * go through `peaks request transition`, which itself enforces spec-locked
8
8
  * + tech-doc-presence.
@@ -11,13 +11,13 @@
11
11
  * manifest read fails, the hook must fail-OPEN (warn + allow). The LLM is
12
12
  * never bricked by a peaks bug.
13
13
  */
14
- export interface SoloCodeBanInput {
14
+ export interface CodeBanInput {
15
15
  readonly skill: string;
16
16
  readonly command: string;
17
17
  }
18
- export interface SoloCodeBanResult {
18
+ export interface CodeBanResult {
19
19
  readonly denied: boolean;
20
20
  readonly reason: string;
21
21
  }
22
- export declare function isSoloCodeCommit(skill: string, command: string): boolean;
23
- export declare function evaluateSoloCodeBan(input: SoloCodeBanInput): SoloCodeBanResult;
22
+ export declare function isCodeCommit(skill: string, command: string): boolean;
23
+ export declare function evaluateCodeBan(input: CodeBanInput): CodeBanResult;
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Solo-code-ban enforcer — PreToolUse Bash guard.
2
+ * Code-commit-ban enforcer — PreToolUse Bash guard.
3
3
  *
4
4
  * Per L2 redesign §5.4. Deny `git commit` or `git apply` invocations from
5
- * a peaks-* skill. The Solo Code-Change Red Line says peaks-code / peaks-rd
5
+ * a peaks-* skill. The Code Commit Ban Red Line says peaks-code / peaks-rd
6
6
  * are orchestrators, not implementers; the actual `git commit` step must
7
7
  * go through `peaks request transition`, which itself enforces spec-locked
8
8
  * + tech-doc-presence.
@@ -12,15 +12,15 @@
12
12
  * never bricked by a peaks bug.
13
13
  */
14
14
  const COMMIT_APPLY_PATTERN = /^\s*git\s+(commit|apply)\b/;
15
- const DENY_REASON = 'Solo Code-Change Red Line: peaks-* skills must go through peaks-code / peaks-rd. ' +
15
+ const DENY_REASON = 'Code Commit Ban Red Line: peaks-* skills must go through peaks-code / peaks-rd. ' +
16
16
  'Use `peaks request transition` instead of `git commit` / `git apply` directly.';
17
- export function isSoloCodeCommit(skill, command) {
17
+ export function isCodeCommit(skill, command) {
18
18
  if (!skill.startsWith('peaks-'))
19
19
  return false;
20
20
  return COMMIT_APPLY_PATTERN.test(command);
21
21
  }
22
- export function evaluateSoloCodeBan(input) {
23
- if (isSoloCodeCommit(input.skill, input.command)) {
22
+ export function evaluateCodeBan(input) {
23
+ if (isCodeCommit(input.skill, input.command)) {
24
24
  return { denied: true, reason: DENY_REASON };
25
25
  }
26
26
  return { denied: false, reason: '' };
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import type { RedLineMarker } from './types.js';
9
9
  export interface RedLineCatalogEntry {
10
- /** Stable id, e.g. "rl-solo-code-ban-001". */
10
+ /** Stable id, e.g. "rl-code-ban-001". */
11
11
  readonly id: string;
12
12
  readonly rule: string;
13
13
  /** Markers that, if found near the rule's text, identify this red line. */
@@ -26,7 +26,7 @@ export declare const RED_LINE_CATALOG: readonly RedLineCatalogEntry[];
26
26
  * the integration seam is missing. When the integration lands, the entry
27
27
  * is removed from this set in a single-line follow-up commit.
28
28
  *
29
- * L2.1 final state: Tasks 5 (solo-code-ban) + 6 (no-root-pollution) are
29
+ * L2.1 final state: Tasks 5 (code-ban) + 6 (no-root-pollution) are
30
30
  * wired into peaks hook handle (Tasks 1-4: framework + 3 enforcers also
31
31
  * integrated). Tasks 3 (tech-doc-presence) and 4 (mock-placement) are
32
32
  * deferred — their request-transition / slice-check integrations are
@@ -9,15 +9,15 @@ import { RED_LINE_CATALOG_P2_A } from './red-line-catalog-p2-a.js';
9
9
  import { RED_LINE_CATALOG_P2_B } from './red-line-catalog-p2-b.js';
10
10
  export const RED_LINE_CATALOG = [
11
11
  {
12
- id: 'rl-solo-code-ban-001',
13
- rule: 'Solo Code-Change Red Line',
12
+ id: 'rl-code-ban-001',
13
+ rule: 'Code Commit Ban',
14
14
  markers: ['BLOCKING', 'MANDATORY'],
15
15
  phrases: [
16
16
  'peaks-code',
17
17
  'orchestrator, NOT an implementer',
18
- 'solo',
18
+ 'code',
19
19
  ],
20
- enforcerRef: 'src/services/audit/enforcers/solo-code-ban.ts',
20
+ enforcerRef: 'src/services/audit/enforcers/code-ban.ts',
21
21
  },
22
22
  {
23
23
  id: 'rl-no-root-pollution-001',
@@ -146,7 +146,7 @@ export const RED_LINE_CATALOG = [
146
146
  * the integration seam is missing. When the integration lands, the entry
147
147
  * is removed from this set in a single-line follow-up commit.
148
148
  *
149
- * L2.1 final state: Tasks 5 (solo-code-ban) + 6 (no-root-pollution) are
149
+ * L2.1 final state: Tasks 5 (code-ban) + 6 (no-root-pollution) are
150
150
  * wired into peaks hook handle (Tasks 1-4: framework + 3 enforcers also
151
151
  * integrated). Tasks 3 (tech-doc-presence) and 4 (mock-placement) are
152
152
  * deferred — their request-transition / slice-check integrations are
@@ -21,9 +21,9 @@ export interface RedLineSource {
21
21
  readonly context: string;
22
22
  }
23
23
  export interface RedLineEntry {
24
- /** Stable id, e.g. "rl-solo-code-ban-001". */
24
+ /** Stable id, e.g. "rl-code-ban-001". */
25
25
  readonly id: string;
26
- /** Human-readable rule name, e.g. "Solo Code-Change Red Line". */
26
+ /** Human-readable rule name, e.g. "Code Commit Ban". */
27
27
  readonly rule: string;
28
28
  readonly source: RedLineSource;
29
29
  readonly backing: RedLineBacking;
@@ -20,7 +20,7 @@ export interface AutoCompactInput {
20
20
  /** Injectable clock for mtime checks (test seam). */
21
21
  readonly now?: Date | undefined;
22
22
  /**
23
- * Slice 2026-06-28-solo-mode-bypass-fix (defect #4): which session
23
+ * Slice 2026-06-28-code-mode-bypass-fix (defect #4): which session
24
24
  * the compact should target. Default `'main'` — the orchestrator
25
25
  * (peaks-code body) runs in the main-session Claude Code window and
26
26
  * wants to compress *its* context. Sub-agent shells pass
@@ -16,7 +16,7 @@
16
16
  * 3. If 0.85 ≤ ratio < 0.95 (pre-compact zone): peaks-loop prepares
17
17
  * the convergence toolkit (checkpoint + auto-decisions log +
18
18
  * IDE-dispatch handle) and surfaces it to the LLM. The LLM
19
- * DECIDES when to fire `peaks solo auto-compact --execute`;
19
+ * DECIDES when to fire `peaks code auto-compact --execute`;
20
20
  * peaks-loop does NOT auto-fire. The toolkit is ready so the
21
21
  * LLM doesn't lose context to a last-second `/compact` panic.
22
22
  * 4. If ratio < 0.85: skip — return a one-line info row.
@@ -64,7 +64,7 @@ export function evaluateCompactTrigger(ratio) {
64
64
  kind: 'pre-compact',
65
65
  ratio,
66
66
  toolkitReady: true,
67
- message: `Context at ${(ratio * 100).toFixed(1)}% in pre-compact zone (0.85–0.95). Convergence toolkit is ready; LLM decides when to fire \`peaks solo auto-compact --execute\`.`
67
+ message: `Context at ${(ratio * 100).toFixed(1)}% in pre-compact zone (0.85–0.95). Convergence toolkit is ready; LLM decides when to fire \`peaks code auto-compact --execute\`.`
68
68
  };
69
69
  }
70
70
  /**
@@ -146,7 +146,7 @@ function appendAutoDecisionLog(input) {
146
146
  writeFileSync(logPath, `${existing}${row}`, 'utf8');
147
147
  }
148
148
  /**
149
- * Slice 2026-06-28-solo-mode-bypass-fix (defect #4): write the
149
+ * Slice 2026-06-28-code-mode-bypass-fix (defect #4): write the
150
150
  * main-session compact intent so the main-session LLM picks it up on
151
151
  * its next turn and fires `/compact` in-band. Without this file the
152
152
  * orchestrator's "main-session compact" request is invisible to the
@@ -20,7 +20,7 @@
20
20
  * orchestrator writes its public contract to disk via `writeContract`,
21
21
  * and the next dispatch's prompt is built with `formatContractInjection`.
22
22
  *
23
- * Why this lives in `services/solo/`:
23
+ * Why this lives in `services/code/`:
24
24
  * `peaks-code` is the natural caller. The CLI surface (`peaks sub-agent
25
25
  * dispatch --from-dag`) consumes the planner's output but the planner
26
26
  * itself is a library.
@@ -20,7 +20,7 @@
20
20
  * orchestrator writes its public contract to disk via `writeContract`,
21
21
  * and the next dispatch's prompt is built with `formatContractInjection`.
22
22
  *
23
- * Why this lives in `services/solo/`:
23
+ * Why this lives in `services/code/`:
24
24
  * `peaks-code` is the natural caller. The CLI surface (`peaks sub-agent
25
25
  * dispatch --from-dag`) consumes the planner's output but the planner
26
26
  * itself is a library.
@@ -16,7 +16,7 @@
16
16
  * --force-under-job → ALLOW (override path)
17
17
  *
18
18
  * Karpathy §2 (Simplicity First): ~70 lines, no LLM call, no regex.
19
- * Pure read + arithmetic. The CLI wrapper in solo-commands.ts
19
+ * Pure read + arithmetic. The CLI wrapper in code-commands.ts
20
20
  * translates the verdict into exit code + JSON envelope.
21
21
  */
22
22
  export declare const JOB_NOT_INITIALIZED: "JOB_NOT_INITIALIZED";
@@ -16,7 +16,7 @@
16
16
  * --force-under-job → ALLOW (override path)
17
17
  *
18
18
  * Karpathy §2 (Simplicity First): ~70 lines, no LLM call, no regex.
19
- * Pure read + arithmetic. The CLI wrapper in solo-commands.ts
19
+ * Pure read + arithmetic. The CLI wrapper in code-commands.ts
20
20
  * translates the verdict into exit code + JSON envelope.
21
21
  */
22
22
  import { existsSync, readFileSync } from 'node:fs';
@@ -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 solo detect-job`; this service persists the verdict to
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
  *