peaks-loop 4.0.7 → 4.0.9

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 (156) hide show
  1. package/CHANGELOG.md +58 -288
  2. package/dist/cli/commands/_register.js +2 -0
  3. package/dist/cli/commands/baseline-commands.d.ts +3 -0
  4. package/dist/cli/commands/baseline-commands.js +146 -0
  5. package/dist/cli/commands/code-job-shape-commands.js +8 -11
  6. package/dist/cli/commands/code-mode-gate-commands.js +1 -43
  7. package/dist/cli/commands/code-runtime-commands.js +36 -14
  8. package/dist/cli/commands/core/skill-command.js +75 -13
  9. package/dist/cli/commands/core/standards-command.js +5 -50
  10. package/dist/cli/commands/dispatch-commands.d.ts +20 -0
  11. package/dist/cli/commands/dispatch-commands.js +39 -38
  12. package/dist/cli/commands/dispatch-from-dag.js +17 -0
  13. package/dist/cli/commands/heartbeat-commands.d.ts +21 -0
  14. package/dist/cli/commands/heartbeat-commands.js +40 -0
  15. package/dist/cli/commands/hook-handle.js +5 -2
  16. package/dist/cli/commands/hooks-commands.js +9 -26
  17. package/dist/cli/commands/loop-eval-commands.js +5 -2
  18. package/dist/cli/commands/statusline-commands.js +1 -1
  19. package/dist/cli/commands/sub-agent-commands.js +0 -2
  20. package/dist/cli/commands/sub-agent-shared.d.ts +7 -9
  21. package/dist/cli/commands/workflow-commands.js +8 -0
  22. package/dist/cli/commands/workflow-lifecycle-commands.d.ts +63 -0
  23. package/dist/cli/commands/workflow-lifecycle-commands.js +302 -0
  24. package/dist/cli/commands/workspace/init-command.js +19 -0
  25. package/dist/services/audit/backing-detector.d.ts +2 -19
  26. package/dist/services/audit/backing-detector.js +7 -66
  27. package/dist/services/audit/enforcers/active-skill-resolver.d.ts +25 -9
  28. package/dist/services/audit/enforcers/active-skill-resolver.js +83 -21
  29. package/dist/services/audit/enforcers/lint-audit-regression.js +1 -10
  30. package/dist/services/capability-audit-service/cross-check.d.ts +8 -0
  31. package/dist/services/capability-audit-service/cross-check.js +11 -0
  32. package/dist/services/capability-audit-service/index.d.ts +3 -0
  33. package/dist/services/capability-audit-service/index.js +2 -0
  34. package/dist/services/capability-audit-service/runner.d.ts +27 -0
  35. package/dist/services/capability-audit-service/runner.js +40 -0
  36. package/dist/services/capability-audit-service/staleness.d.ts +1 -0
  37. package/dist/services/capability-audit-service/staleness.js +7 -0
  38. package/dist/services/capability-audit-service/types.d.ts +24 -0
  39. package/dist/services/capability-audit-service/types.js +1 -0
  40. package/dist/services/capability-baseline/store.d.ts +33 -0
  41. package/dist/services/capability-baseline/store.js +80 -0
  42. package/dist/services/capability-baseline/types.d.ts +45 -0
  43. package/dist/services/capability-baseline/types.js +5 -0
  44. package/dist/services/capability-baseline/validator.d.ts +19 -0
  45. package/dist/services/capability-baseline/validator.js +38 -0
  46. package/dist/services/capability-guard-runner/contracts/J01.d.ts +2 -0
  47. package/dist/services/capability-guard-runner/contracts/J01.js +48 -0
  48. package/dist/services/capability-guard-runner/contracts/J02.d.ts +2 -0
  49. package/dist/services/capability-guard-runner/contracts/J02.js +34 -0
  50. package/dist/services/capability-guard-runner/contracts/J03.d.ts +2 -0
  51. package/dist/services/capability-guard-runner/contracts/J03.js +24 -0
  52. package/dist/services/capability-guard-runner/contracts/J04.d.ts +2 -0
  53. package/dist/services/capability-guard-runner/contracts/J04.js +40 -0
  54. package/dist/services/capability-guard-runner/contracts/J05.d.ts +2 -0
  55. package/dist/services/capability-guard-runner/contracts/J05.js +21 -0
  56. package/dist/services/capability-guard-runner/contracts/J06.d.ts +2 -0
  57. package/dist/services/capability-guard-runner/contracts/J06.js +43 -0
  58. package/dist/services/capability-guard-runner/contracts/J07.d.ts +2 -0
  59. package/dist/services/capability-guard-runner/contracts/J07.js +53 -0
  60. package/dist/services/capability-guard-runner/contracts/J08.d.ts +2 -0
  61. package/dist/services/capability-guard-runner/contracts/J08.js +43 -0
  62. package/dist/services/capability-guard-runner/contracts/J09.d.ts +2 -0
  63. package/dist/services/capability-guard-runner/contracts/J09.js +44 -0
  64. package/dist/services/capability-guard-runner/contracts/J10.d.ts +2 -0
  65. package/dist/services/capability-guard-runner/contracts/J10.js +40 -0
  66. package/dist/services/capability-guard-runner/contracts/J11.d.ts +2 -0
  67. package/dist/services/capability-guard-runner/contracts/J11.js +39 -0
  68. package/dist/services/capability-guard-runner/contracts/J12.d.ts +2 -0
  69. package/dist/services/capability-guard-runner/contracts/J12.js +34 -0
  70. package/dist/services/capability-guard-runner/contracts/J13.d.ts +2 -0
  71. package/dist/services/capability-guard-runner/contracts/J13.js +45 -0
  72. package/dist/services/capability-guard-runner/contracts/J14.d.ts +2 -0
  73. package/dist/services/capability-guard-runner/contracts/J14.js +36 -0
  74. package/dist/services/capability-guard-runner/contracts/J15.d.ts +2 -0
  75. package/dist/services/capability-guard-runner/contracts/J15.js +40 -0
  76. package/dist/services/capability-guard-runner/diff.d.ts +2 -0
  77. package/dist/services/capability-guard-runner/diff.js +7 -0
  78. package/dist/services/capability-guard-runner/runner.d.ts +9 -0
  79. package/dist/services/capability-guard-runner/runner.js +22 -0
  80. package/dist/services/capability-guard-runner/types.d.ts +39 -0
  81. package/dist/services/capability-guard-runner/types.js +1 -0
  82. package/dist/services/code/auto-compact-orchestrator.d.ts +35 -2
  83. package/dist/services/code/auto-compact-orchestrator.js +29 -9
  84. package/dist/services/context/build-dispatch-system-prompt.js +0 -18
  85. package/dist/services/dispatch/dispatch-record-writer.d.ts +25 -1
  86. package/dist/services/dispatch/dispatch-record-writer.js +85 -15
  87. package/dist/services/dispatch/test-tool-detection.d.ts +0 -14
  88. package/dist/services/dispatch/test-tool-detection.js +0 -22
  89. package/dist/services/doctor/doctor-service/checks/skill-presence.d.ts +8 -0
  90. package/dist/services/doctor/doctor-service/checks/skill-presence.js +9 -1
  91. package/dist/services/evolution/evolution-types.d.ts +16 -16
  92. package/dist/services/final-review/final-review-service.d.ts +8 -0
  93. package/dist/services/final-review/final-review-service.js +14 -0
  94. package/dist/services/final-review/final-review-types.d.ts +1 -1
  95. package/dist/services/hooks/presence-marker-detector.d.ts +6 -0
  96. package/dist/services/hooks/presence-marker-detector.js +48 -0
  97. package/dist/services/ide/adapters/claude-code-adapter.js +20 -0
  98. package/dist/services/ide/adapters/codex-adapter.js +20 -1
  99. package/dist/services/ide/adapters/cursor-adapter.js +21 -1
  100. package/dist/services/ide/adapters/hermes-adapter.js +20 -1
  101. package/dist/services/ide/adapters/openclaw-adapter.js +20 -1
  102. package/dist/services/ide/adapters/qoder-adapter.js +20 -1
  103. package/dist/services/ide/adapters/tongyi-lingma-adapter.js +20 -1
  104. package/dist/services/ide/adapters/trae-adapter.js +21 -1
  105. package/dist/services/ide/adapters/zcode-adapter.js +19 -0
  106. package/dist/services/ide/ide-types.d.ts +15 -0
  107. package/dist/services/job/job-progress-store.d.ts +2 -2
  108. package/dist/services/job/job-types.d.ts +26 -26
  109. package/dist/services/observability/observability-service.d.ts +4 -4
  110. package/dist/services/scan/archetype-service.js +2 -52
  111. package/dist/services/sediment/json-schema.d.ts +4 -4
  112. package/dist/services/session/caller-binding-service.d.ts +21 -0
  113. package/dist/services/session/caller-binding-service.js +35 -0
  114. package/dist/services/session/caller-id-types.d.ts +62 -13
  115. package/dist/services/session/caller-id-types.js +25 -13
  116. package/dist/services/session/index.d.ts +4 -2
  117. package/dist/services/session/index.js +8 -2
  118. package/dist/services/session/platform-fallbacks.d.ts +25 -17
  119. package/dist/services/session/platform-fallbacks.js +26 -28
  120. package/dist/services/session/resolve-caller-id.d.ts +64 -29
  121. package/dist/services/session/resolve-caller-id.js +122 -48
  122. package/dist/services/session/session-manager.d.ts +0 -29
  123. package/dist/services/session/session-manager.js +0 -33
  124. package/dist/services/session/session-resume-service.d.ts +4 -0
  125. package/dist/services/session/session-resume-service.js +4 -0
  126. package/dist/services/skills/hooks-settings-service.d.ts +0 -41
  127. package/dist/services/skills/hooks-settings-service.js +5 -61
  128. package/dist/services/skills/presence-lease-service.d.ts +73 -0
  129. package/dist/services/skills/presence-lease-service.js +358 -0
  130. package/dist/services/skills/presence-lease-types.d.ts +75 -0
  131. package/dist/services/skills/presence-lease-types.js +16 -0
  132. package/dist/services/skills/skill-presence-service.js +86 -22
  133. package/dist/services/skills/skill-statusline-renderer.d.ts +46 -56
  134. package/dist/services/skills/skill-statusline-renderer.js +312 -100
  135. package/dist/services/slice/slice-check-service.js +0 -59
  136. package/dist/services/standards/project-standards-service.js +0 -44
  137. package/dist/services/workflow/workflow-graph-store.d.ts +77 -0
  138. package/dist/services/workflow/workflow-graph-store.js +278 -0
  139. package/dist/services/workflow/workflow-graph-types.d.ts +56 -0
  140. package/dist/services/workflow/workflow-graph-types.js +67 -0
  141. package/dist/services/workflow/workflow-inflight-probe.d.ts +52 -0
  142. package/dist/services/workflow/workflow-inflight-probe.js +86 -0
  143. package/dist/services/workflow/workflow-node-lifecycle.d.ts +67 -0
  144. package/dist/services/workflow/workflow-node-lifecycle.js +348 -0
  145. package/dist/services/workflow/workflow-presence-lifecycle.d.ts +58 -0
  146. package/dist/services/workflow/workflow-presence-lifecycle.js +196 -0
  147. package/dist/services/workspace/reconcile-service.d.ts +31 -0
  148. package/dist/services/workspace/reconcile-service.js +132 -1
  149. package/package.json +5 -4
  150. package/skills/peaks-code/SKILL.md +5 -43
  151. package/skills/peaks-code/references/completion-handoff.md +1 -1
  152. package/skills/peaks-code/references/skill-presence-and-title.md +1 -1
  153. package/dist/cli/commands/sub-agent-exec-command.d.ts +0 -25
  154. package/dist/cli/commands/sub-agent-exec-command.js +0 -132
  155. package/dist/services/standards/find-skills-integration.d.ts +0 -59
  156. package/dist/services/standards/find-skills-integration.js +0 -225
@@ -73,12 +73,12 @@ export declare const EvolutionProposalInputSchema: z.ZodObject<{
73
73
  red_lines: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
74
74
  source_traces: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
75
75
  }, "strip", z.ZodTypeAny, {
76
+ diff: Record<string, unknown>;
76
77
  target_kind: "loop" | "bee" | "gate" | "policy" | "evaluator";
77
78
  target_release_id: string;
78
79
  optimization_dimension: string;
79
80
  before_snapshot: Record<string, unknown>;
80
81
  after_snapshot: Record<string, unknown>;
81
- diff: Record<string, unknown>;
82
82
  before_score: number;
83
83
  after_score: number;
84
84
  score_delta_min: number;
@@ -97,9 +97,9 @@ export declare const EvolutionProposalInputSchema: z.ZodObject<{
97
97
  author_id: string;
98
98
  single_object: true;
99
99
  single_optimization_dimension: true;
100
+ diff?: Record<string, unknown> | undefined;
100
101
  before_snapshot?: Record<string, unknown> | undefined;
101
102
  after_snapshot?: Record<string, unknown> | undefined;
102
- diff?: Record<string, unknown> | undefined;
103
103
  score_delta_min?: number | undefined;
104
104
  rubric?: Record<string, unknown> | undefined;
105
105
  red_lines?: string[] | undefined;
@@ -154,12 +154,12 @@ export declare const EvolutionProposalSchema: z.ZodObject<{
154
154
  schema_version: "peaks.evolution/1";
155
155
  id: string;
156
156
  created_at: string;
157
+ diff: Record<string, unknown>;
157
158
  target_kind: "loop" | "bee" | "gate" | "policy" | "evaluator";
158
159
  target_release_id: string;
159
160
  optimization_dimension: string;
160
161
  before_snapshot: Record<string, unknown>;
161
162
  after_snapshot: Record<string, unknown>;
162
- diff: Record<string, unknown>;
163
163
  before_score: number;
164
164
  after_score: number;
165
165
  score_delta_min: number;
@@ -187,9 +187,9 @@ export declare const EvolutionProposalSchema: z.ZodObject<{
187
187
  target_count: 1;
188
188
  score_delta: number;
189
189
  schema_version?: "peaks.evolution/1" | undefined;
190
+ diff?: Record<string, unknown> | undefined;
190
191
  before_snapshot?: Record<string, unknown> | undefined;
191
192
  after_snapshot?: Record<string, unknown> | undefined;
192
- diff?: Record<string, unknown> | undefined;
193
193
  score_delta_min?: number | undefined;
194
194
  rubric?: Record<string, unknown> | undefined;
195
195
  red_lines?: string[] | undefined;
@@ -293,12 +293,12 @@ export declare const EvolutionEvaluationInputSchema: z.ZodObject<{
293
293
  schema_version: "peaks.evolution/1";
294
294
  id: string;
295
295
  created_at: string;
296
+ diff: Record<string, unknown>;
296
297
  target_kind: "loop" | "bee" | "gate" | "policy" | "evaluator";
297
298
  target_release_id: string;
298
299
  optimization_dimension: string;
299
300
  before_snapshot: Record<string, unknown>;
300
301
  after_snapshot: Record<string, unknown>;
301
- diff: Record<string, unknown>;
302
302
  before_score: number;
303
303
  after_score: number;
304
304
  score_delta_min: number;
@@ -326,9 +326,9 @@ export declare const EvolutionEvaluationInputSchema: z.ZodObject<{
326
326
  target_count: 1;
327
327
  score_delta: number;
328
328
  schema_version?: "peaks.evolution/1" | undefined;
329
+ diff?: Record<string, unknown> | undefined;
329
330
  before_snapshot?: Record<string, unknown> | undefined;
330
331
  after_snapshot?: Record<string, unknown> | undefined;
331
- diff?: Record<string, unknown> | undefined;
332
332
  score_delta_min?: number | undefined;
333
333
  rubric?: Record<string, unknown> | undefined;
334
334
  red_lines?: string[] | undefined;
@@ -374,16 +374,17 @@ export declare const EvolutionEvaluationInputSchema: z.ZodObject<{
374
374
  schema_version: "peaks.evolution/1";
375
375
  id: string;
376
376
  created_at: string;
377
+ verdict: "keep" | "revert" | "needs-user-decision";
377
378
  proposal: {
378
379
  schema_version: "peaks.evolution/1";
379
380
  id: string;
380
381
  created_at: string;
382
+ diff: Record<string, unknown>;
381
383
  target_kind: "loop" | "bee" | "gate" | "policy" | "evaluator";
382
384
  target_release_id: string;
383
385
  optimization_dimension: string;
384
386
  before_snapshot: Record<string, unknown>;
385
387
  after_snapshot: Record<string, unknown>;
386
- diff: Record<string, unknown>;
387
388
  before_score: number;
388
389
  after_score: number;
389
390
  score_delta_min: number;
@@ -410,12 +411,12 @@ export declare const EvolutionEvaluationInputSchema: z.ZodObject<{
410
411
  safetyRegressionRisks: string[];
411
412
  blocker?: string | undefined;
412
413
  };
413
- verdict: "keep" | "revert" | "needs-user-decision";
414
414
  user_confirmation_pointer?: string | undefined;
415
415
  brief_pointer?: string | undefined;
416
416
  }, {
417
417
  id: string;
418
418
  created_at: string;
419
+ verdict: "keep" | "revert" | "needs-user-decision";
419
420
  proposal: {
420
421
  id: string;
421
422
  created_at: string;
@@ -431,9 +432,9 @@ export declare const EvolutionEvaluationInputSchema: z.ZodObject<{
431
432
  target_count: 1;
432
433
  score_delta: number;
433
434
  schema_version?: "peaks.evolution/1" | undefined;
435
+ diff?: Record<string, unknown> | undefined;
434
436
  before_snapshot?: Record<string, unknown> | undefined;
435
437
  after_snapshot?: Record<string, unknown> | undefined;
436
- diff?: Record<string, unknown> | undefined;
437
438
  score_delta_min?: number | undefined;
438
439
  rubric?: Record<string, unknown> | undefined;
439
440
  red_lines?: string[] | undefined;
@@ -452,7 +453,6 @@ export declare const EvolutionEvaluationInputSchema: z.ZodObject<{
452
453
  safetyRegressionRisks?: string[] | undefined;
453
454
  blocker?: string | undefined;
454
455
  };
455
- verdict: "keep" | "revert" | "needs-user-decision";
456
456
  schema_version?: "peaks.evolution/1" | undefined;
457
457
  user_confirmation_pointer?: string | undefined;
458
458
  brief_pointer?: string | undefined;
@@ -506,12 +506,12 @@ export declare const EvolutionEvaluationSchema: z.ZodObject<{
506
506
  schema_version: "peaks.evolution/1";
507
507
  id: string;
508
508
  created_at: string;
509
+ diff: Record<string, unknown>;
509
510
  target_kind: "loop" | "bee" | "gate" | "policy" | "evaluator";
510
511
  target_release_id: string;
511
512
  optimization_dimension: string;
512
513
  before_snapshot: Record<string, unknown>;
513
514
  after_snapshot: Record<string, unknown>;
514
- diff: Record<string, unknown>;
515
515
  before_score: number;
516
516
  after_score: number;
517
517
  score_delta_min: number;
@@ -539,9 +539,9 @@ export declare const EvolutionEvaluationSchema: z.ZodObject<{
539
539
  target_count: 1;
540
540
  score_delta: number;
541
541
  schema_version?: "peaks.evolution/1" | undefined;
542
+ diff?: Record<string, unknown> | undefined;
542
543
  before_snapshot?: Record<string, unknown> | undefined;
543
544
  after_snapshot?: Record<string, unknown> | undefined;
544
- diff?: Record<string, unknown> | undefined;
545
545
  score_delta_min?: number | undefined;
546
546
  rubric?: Record<string, unknown> | undefined;
547
547
  red_lines?: string[] | undefined;
@@ -589,17 +589,18 @@ export declare const EvolutionEvaluationSchema: z.ZodObject<{
589
589
  schema_version: "peaks.evolution/1";
590
590
  id: string;
591
591
  created_at: string;
592
+ verdict: "keep" | "revert" | "needs-user-decision";
592
593
  score_delta: number;
593
594
  proposal: {
594
595
  schema_version: "peaks.evolution/1";
595
596
  id: string;
596
597
  created_at: string;
598
+ diff: Record<string, unknown>;
597
599
  target_kind: "loop" | "bee" | "gate" | "policy" | "evaluator";
598
600
  target_release_id: string;
599
601
  optimization_dimension: string;
600
602
  before_snapshot: Record<string, unknown>;
601
603
  after_snapshot: Record<string, unknown>;
602
- diff: Record<string, unknown>;
603
604
  before_score: number;
604
605
  after_score: number;
605
606
  score_delta_min: number;
@@ -626,12 +627,12 @@ export declare const EvolutionEvaluationSchema: z.ZodObject<{
626
627
  safetyRegressionRisks: string[];
627
628
  blocker?: string | undefined;
628
629
  };
629
- verdict: "keep" | "revert" | "needs-user-decision";
630
630
  user_confirmation_pointer?: string | undefined;
631
631
  brief_pointer?: string | undefined;
632
632
  }, {
633
633
  id: string;
634
634
  created_at: string;
635
+ verdict: "keep" | "revert" | "needs-user-decision";
635
636
  score_delta: number;
636
637
  proposal: {
637
638
  id: string;
@@ -648,9 +649,9 @@ export declare const EvolutionEvaluationSchema: z.ZodObject<{
648
649
  target_count: 1;
649
650
  score_delta: number;
650
651
  schema_version?: "peaks.evolution/1" | undefined;
652
+ diff?: Record<string, unknown> | undefined;
651
653
  before_snapshot?: Record<string, unknown> | undefined;
652
654
  after_snapshot?: Record<string, unknown> | undefined;
653
- diff?: Record<string, unknown> | undefined;
654
655
  score_delta_min?: number | undefined;
655
656
  rubric?: Record<string, unknown> | undefined;
656
657
  red_lines?: string[] | undefined;
@@ -669,7 +670,6 @@ export declare const EvolutionEvaluationSchema: z.ZodObject<{
669
670
  safetyRegressionRisks?: string[] | undefined;
670
671
  blocker?: string | undefined;
671
672
  };
672
- verdict: "keep" | "revert" | "needs-user-decision";
673
673
  schema_version?: "peaks.evolution/1" | undefined;
674
674
  user_confirmation_pointer?: string | undefined;
675
675
  brief_pointer?: string | undefined;
@@ -10,6 +10,7 @@ export interface LlmRunner {
10
10
  }>;
11
11
  }
12
12
  import type { FinalReviewOutput } from './final-review-types.js';
13
+ import type { CapabilityAuditResult } from '../capability-audit-service/types.js';
13
14
  export interface PrepareFinalReviewOptions {
14
15
  readonly projectRoot: string;
15
16
  readonly sessionId: string;
@@ -20,3 +21,10 @@ export declare class IncompleteFinalReviewError extends Error {
20
21
  constructor(message: string);
21
22
  }
22
23
  export declare function prepareFinalReview(rid: string, opts: PrepareFinalReviewOptions): Promise<FinalReviewOutput>;
24
+ export declare function decideFifthDimension(input: {
25
+ readonly audit: CapabilityAuditResult | null;
26
+ readonly nowMs: number;
27
+ }): {
28
+ readonly verdict: 'pass' | 'fail' | 'inconclusive';
29
+ readonly reason: string;
30
+ };
@@ -1,5 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
+ import { isStale } from '../capability-audit-service/staleness.js';
3
4
  const REQUIRED_DIMENSIONS = [
4
5
  'functional-completeness',
5
6
  'problem-resolution',
@@ -50,3 +51,16 @@ export async function prepareFinalReview(rid, opts) {
50
51
  }
51
52
  return output;
52
53
  }
54
+ export function decideFifthDimension(input) {
55
+ if (input.audit === null)
56
+ return { verdict: 'inconclusive', reason: 'AUDIT_GUARD_NOT_RUN' };
57
+ if (isStale(input.audit.auditedAt, input.nowMs))
58
+ return { verdict: 'inconclusive', reason: 'AUDIT_STALE' };
59
+ if (input.audit.crossCheck.guardVsAudit === 'diverge')
60
+ return { verdict: 'inconclusive', reason: 'AUDIT_CROSS_CHECK_DIVERGE' };
61
+ if (input.audit.verdict === 'consistent')
62
+ return { verdict: 'pass', reason: 'audit consistent' };
63
+ if (input.audit.verdict === 'drifted')
64
+ return { verdict: 'fail', reason: 'audit drifted' };
65
+ return { verdict: 'inconclusive', reason: 'audit inconclusive' };
66
+ }
@@ -15,7 +15,7 @@
15
15
  * failure (return to human for re-prompting) — autonomous work must
16
16
  * never proceed on a partial review.
17
17
  */
18
- export type DimensionKind = 'functional-completeness' | 'problem-resolution' | 'no-new-bugs' | 'existing-functionality-intact';
18
+ export type DimensionKind = 'functional-completeness' | 'problem-resolution' | 'no-new-bugs' | 'existing-functionality-intact' | 'capability-consistency';
19
19
  export type DimensionVerdict = 'pass' | 'fail' | 'inconclusive';
20
20
  export type EvidenceKind = 'test-result' | 'test-coverage' | 'manual-spot-check' | 'pre-post-diff' | 'regression-suite' | 'ac-mapping';
21
21
  export type DimensionConfidence = 'high' | 'medium' | 'low';
@@ -12,5 +12,11 @@ export type PresenceMarkerWarning = (typeof PRESENCE_MARKER_WARNING)[number];
12
12
  export declare const PRESENCE_MARKER_WARNING: readonly ["Peaks skill context may have been lost from this conversation; please re-invoke /peaks-<skill>."];
13
13
  /**
14
14
  * Pure read-only presence-marker detection. No I/O side effects.
15
+ *
16
+ * Slice 4.0.8: the canonical 4.0.7 behavior is preserved (read legacy
17
+ * `active-skill.json` or `.peaks/.active-skill.json`, project the
18
+ * `Peaks-Loop Skill:` marker). The new diagnostic for a broken
19
+ * canonical graph is surfaced via the `warning` field, NOT swallowed,
20
+ * so the statusline / hook / doctor consumers can render it.
15
21
  */
16
22
  export declare function detectPresenceMarker(input: DetectPresenceMarkerInput): DetectPresenceMarkerResult;
@@ -73,6 +73,41 @@ function readPresenceFile(absolutePath) {
73
73
  return null;
74
74
  return { skill: skillMatch[1] };
75
75
  }
76
+ /**
77
+ * Slice 4.0.8: surface a typed `PEAKS_GRAPH_REF_BROKEN` warning
78
+ * when the canonical presence lease / index points at a missing or
79
+ * corrupt graph. The legacy `active-skill.json` walk never
80
+ * inspected graphRef; in 4.0.8 we surface the broken graph in the
81
+ * `warnings` array so downstream consumers (statusline, doctor,
82
+ * hooks) can render the diagnostic instead of silently rendering
83
+ * "active" for a half-wired presence.
84
+ */
85
+ function tryDetectBrokenGraph(projectRoot) {
86
+ try {
87
+ const presenceIndexDir = resolve(projectRoot, '.peaks', '_runtime');
88
+ if (!existsSync(presenceIndexDir))
89
+ return null;
90
+ // Best-effort: walk a single directory level for the legacy
91
+ // `active-skill.json` indicator. A broken graphRef would be
92
+ // surfaced by the canonical lease service (PEAKS_GRAPH_REF_BROKEN
93
+ // is the typed error), but the marker detector is a *read* —
94
+ // we don't import the lease service here. The diagnostic is
95
+ // best-effort: we report the index file's `graphRef` field
96
+ // when it names a missing file.
97
+ const legacyPath = resolve(projectRoot, '.peaks', '_runtime', 'active-skill.json');
98
+ if (!existsSync(legacyPath))
99
+ return null;
100
+ const raw = readFileSync(legacyPath, 'utf8');
101
+ const parsed = JSON.parse(raw);
102
+ if (typeof parsed.graphRef !== 'string')
103
+ return null;
104
+ const graphPath = resolve(projectRoot, '.peaks', '_runtime', parsed.graphRef);
105
+ if (!existsSync(graphPath))
106
+ return 'PEAKS_GRAPH_REF_BROKEN';
107
+ }
108
+ catch { /* swallow — diagnostic only */ }
109
+ return null;
110
+ }
76
111
  function readPresenceBackCompat(project) {
77
112
  const projectRoot = resolve(project);
78
113
  const canonicalPath = resolve(projectRoot, PRESENCE_CANONICAL_PATH);
@@ -92,6 +127,12 @@ function messageHasMarker(message) {
92
127
  }
93
128
  /**
94
129
  * Pure read-only presence-marker detection. No I/O side effects.
130
+ *
131
+ * Slice 4.0.8: the canonical 4.0.7 behavior is preserved (read legacy
132
+ * `active-skill.json` or `.peaks/.active-skill.json`, project the
133
+ * `Peaks-Loop Skill:` marker). The new diagnostic for a broken
134
+ * canonical graph is surfaced via the `warning` field, NOT swallowed,
135
+ * so the statusline / hook / doctor consumers can render it.
95
136
  */
96
137
  export function detectPresenceMarker(input) {
97
138
  const project = input.project;
@@ -100,10 +141,17 @@ export function detectPresenceMarker(input) {
100
141
  if (presence === null) {
101
142
  return { active: false, markerFound: false };
102
143
  }
144
+ const brokenGraph = tryDetectBrokenGraph(project);
103
145
  const markerFound = messageHasMarker(message);
104
146
  if (markerFound) {
147
+ if (brokenGraph !== null) {
148
+ return { active: true, skill: presence.skill, markerFound: true, warning: `Peaks presence active but graph is broken (${brokenGraph}); run \`peaks workspace reconcile\` to repair.` };
149
+ }
105
150
  return { active: true, skill: presence.skill, markerFound: true };
106
151
  }
152
+ if (brokenGraph !== null) {
153
+ return { active: true, skill: presence.skill, markerFound: false, warning: `Peaks presence active but graph is broken (${brokenGraph}); run \`peaks workspace reconcile\` to repair.` };
154
+ }
107
155
  return {
108
156
  active: true,
109
157
  skill: presence.skill,
@@ -100,4 +100,24 @@ export const CLAUDE_CODE_ADAPTER = {
100
100
  installStrategy: 'symlink',
101
101
  envVarOverride: 'PEAKS_CLAUDE_SKILLS_DIR',
102
102
  },
103
+ // Slice 4.0.8 RD §5: Claude Code resolves PEAKS_CALLER_ID (override) →
104
+ // CLAUDE_CODE_SESSION_ID. Empty/invalid → typed PEAKS_CALLER_NOT_RESOLVED.
105
+ resolveCallerId: (env) => {
106
+ const e = env ?? process.env;
107
+ const override = e.PEAKS_CALLER_ID;
108
+ if (typeof override === 'string' && override.trim().length > 0) {
109
+ const trimmed = override.trim();
110
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
111
+ return trimmed;
112
+ }
113
+ const v = e.CLAUDE_CODE_SESSION_ID;
114
+ if (typeof v === 'string' && v.trim().length > 0) {
115
+ const trimmed = v.trim();
116
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
117
+ return trimmed;
118
+ }
119
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: no Claude Code session id available');
120
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
121
+ throw err;
122
+ },
103
123
  };
@@ -86,7 +86,26 @@ export const CODEX_ADAPTER = {
86
86
  // return a clear "not supported" stderr message (slice #008 P-5
87
87
  // capability-check contract preserved).
88
88
  statusline: false,
89
- }
89
+ },
90
+ // Slice 4.0.8 RD §5: Codex vendor signal reserved; fail closed.
91
+ resolveCallerId: (env) => {
92
+ const e = env ?? process.env;
93
+ const override = e.PEAKS_CALLER_ID;
94
+ if (typeof override === 'string' && override.trim().length > 0) {
95
+ const trimmed = override.trim();
96
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
97
+ return trimmed;
98
+ }
99
+ const candidate = e.CODEX_SESSION_ID;
100
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
101
+ const trimmed = candidate.trim();
102
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
103
+ return trimmed;
104
+ }
105
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: Codex vendor signal reserved');
106
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
107
+ throw err;
108
+ },
90
109
  // Standards: UNVERIFIED — see slice #013+ (Codex real-install dogfood for
91
110
  // the `standardsProfile` and `skillInstall` fields). Until then, `peaks
92
111
  // standards init` on a Codex-detected project falls back to the Claude
@@ -73,7 +73,7 @@ export const CURSOR_ADAPTER = {
73
73
  // Cursor has a statusline UI (Cmd+Shift+P → "Cursor: Open Status Bar")
74
74
  // that can host peaks statusline output, so opt in to the capability.
75
75
  statusline: true,
76
- }
76
+ },
77
77
  // Standards: UNVERIFIED — see slice #012+ (Cursor real-install dogfood for
78
78
  // the `standardsProfile` and `skillInstall` fields). Until then, `peaks
79
79
  // standards init` on a Cursor-detected project falls back to the Claude
@@ -81,4 +81,24 @@ export const CURSOR_ADAPTER = {
81
81
  // postinstall script writes skills + output-styles to the legacy
82
82
  // `~/.claude/{skills,output-styles}` paths with a stderr warning. Users
83
83
  // who want Cursor-specific paths must move the files manually.
84
+ // Slice 4.0.8 RD §5: Cursor vendor signal is unverified; reserve-only resolver.
85
+ resolveCallerId: (env) => {
86
+ const e = env ?? process.env;
87
+ const override = e.PEAKS_CALLER_ID;
88
+ if (typeof override === 'string' && override.trim().length > 0) {
89
+ const trimmed = override.trim();
90
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
91
+ return trimmed;
92
+ }
93
+ // Reserved vendor variable (UNVERIFIED): do not synthesize project identity.
94
+ const candidate = e.CURSOR_SESSION_ID;
95
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
96
+ const trimmed = candidate.trim();
97
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
98
+ return trimmed;
99
+ }
100
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: Cursor vendor signal unverified in 4.0.8');
101
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
102
+ throw err;
103
+ },
84
104
  };
@@ -47,5 +47,24 @@ export const HERMES_ADAPTER = {
47
47
  capabilities: {
48
48
  gateEnforce: true,
49
49
  statusline: true
50
- }
50
+ },
51
+ // Slice 4.0.8 RD §5: Hermes vendor signal unverified — fail closed.
52
+ resolveCallerId: (env) => {
53
+ const e = env ?? process.env;
54
+ const override = e.PEAKS_CALLER_ID;
55
+ if (typeof override === 'string' && override.trim().length > 0) {
56
+ const trimmed = override.trim();
57
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
58
+ return trimmed;
59
+ }
60
+ const candidate = e.HERMES_SESSION_ID;
61
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
62
+ const trimmed = candidate.trim();
63
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
64
+ return trimmed;
65
+ }
66
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: Hermes vendor signal unverified');
67
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
68
+ throw err;
69
+ },
51
70
  };
@@ -38,5 +38,24 @@ export const OPENCLAW_ADAPTER = {
38
38
  capabilities: {
39
39
  gateEnforce: true,
40
40
  statusline: true
41
- }
41
+ },
42
+ // Slice 4.0.8 RD §5: OpenClaw vendor signal unverified — fail closed.
43
+ resolveCallerId: (env) => {
44
+ const e = env ?? process.env;
45
+ const override = e.PEAKS_CALLER_ID;
46
+ if (typeof override === 'string' && override.trim().length > 0) {
47
+ const trimmed = override.trim();
48
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
49
+ return trimmed;
50
+ }
51
+ const candidate = e.OPENCLAW_SESSION_ID;
52
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
53
+ const trimmed = candidate.trim();
54
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
55
+ return trimmed;
56
+ }
57
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: OpenClaw vendor signal unverified');
58
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
59
+ throw err;
60
+ },
42
61
  };
@@ -53,5 +53,24 @@ export const QODER_ADAPTER = {
53
53
  capabilities: {
54
54
  gateEnforce: true,
55
55
  statusline: true
56
- }
56
+ },
57
+ // Slice 4.0.8 RD §5: Qoder vendor signal unverified — fail closed.
58
+ resolveCallerId: (env) => {
59
+ const e = env ?? process.env;
60
+ const override = e.PEAKS_CALLER_ID;
61
+ if (typeof override === 'string' && override.trim().length > 0) {
62
+ const trimmed = override.trim();
63
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
64
+ return trimmed;
65
+ }
66
+ const candidate = e.QODER_SESSION_ID;
67
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
68
+ const trimmed = candidate.trim();
69
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
70
+ return trimmed;
71
+ }
72
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: Qoder vendor signal unverified');
73
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
74
+ throw err;
75
+ },
57
76
  };
@@ -41,5 +41,24 @@ export const TONGYI_LINGMA_ADAPTER = {
41
41
  capabilities: {
42
42
  gateEnforce: true,
43
43
  statusline: true
44
- }
44
+ },
45
+ // Slice 4.0.8 RD §5: Tongyi Lingma vendor signal unverified — fail closed.
46
+ resolveCallerId: (env) => {
47
+ const e = env ?? process.env;
48
+ const override = e.PEAKS_CALLER_ID;
49
+ if (typeof override === 'string' && override.trim().length > 0) {
50
+ const trimmed = override.trim();
51
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
52
+ return trimmed;
53
+ }
54
+ const candidate = e.TONGYI_LINGMA_SESSION_ID;
55
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
56
+ const trimmed = candidate.trim();
57
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
58
+ return trimmed;
59
+ }
60
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: Tongyi Lingma vendor signal unverified');
61
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
62
+ throw err;
63
+ },
45
64
  };
@@ -71,7 +71,7 @@ export const TRAE_ADAPTER = {
71
71
  capabilities: {
72
72
  gateEnforce: true,
73
73
  statusline: true,
74
- }
74
+ },
75
75
  // Standards: UNVERIFIED — see slice #012+ (Trae real-install dogfood for
76
76
  // the `standardsProfile` and `skillInstall` fields). The slice #011
77
77
  // framework lands; per-IDE values for Trae are a follow-up gated on
@@ -80,4 +80,24 @@ export const TRAE_ADAPTER = {
80
80
  // (CLAUDE.md + .claude/rules/**) with a stderr warning, and the
81
81
  // postinstall script writes skills + output-styles to the legacy
82
82
  // `~/.claude/{skills,output-styles}` paths with a stderr warning.
83
+ // Slice 4.0.8 RD §5: Trae resolves PEAKS_CALLER_ID (override) →
84
+ // TRAE_SESSION_ID. Empty/invalid → typed PEAKS_CALLER_NOT_RESOLVED.
85
+ resolveCallerId: (env) => {
86
+ const e = env ?? process.env;
87
+ const override = e.PEAKS_CALLER_ID;
88
+ if (typeof override === 'string' && override.trim().length > 0) {
89
+ const trimmed = override.trim();
90
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
91
+ return trimmed;
92
+ }
93
+ const v = e.TRAE_SESSION_ID;
94
+ if (typeof v === 'string' && v.trim().length > 0) {
95
+ const trimmed = v.trim();
96
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
97
+ return trimmed;
98
+ }
99
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: no Trae session id available');
100
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
101
+ throw err;
102
+ },
83
103
  };
@@ -217,4 +217,23 @@ export const ZCODE_ADAPTER = {
217
217
  // provider → first enabled → first provider). Returns undefined
218
218
  // on any failure (consistent with the cross-IDE contract).
219
219
  detectCurrentModel: detectZcodeCurrentModel,
220
+ // Slice 4.0.8 RD §5: z-code vendor signal unverified — fail closed.
221
+ resolveCallerId: (env) => {
222
+ const e = env ?? process.env;
223
+ const override = e.PEAKS_CALLER_ID;
224
+ if (typeof override === 'string' && override.trim().length > 0) {
225
+ const trimmed = override.trim();
226
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
227
+ return trimmed;
228
+ }
229
+ const candidate = e.ZCODE_SESSION_ID;
230
+ if (typeof candidate === 'string' && candidate.trim().length > 0) {
231
+ const trimmed = candidate.trim();
232
+ if (/^[a-zA-Z0-9._-]{1,200}$/.test(trimmed))
233
+ return trimmed;
234
+ }
235
+ const err = new Error('PEAKS_CALLER_NOT_RESOLVED: z-code vendor signal unverified');
236
+ err.code = 'PEAKS_CALLER_NOT_RESOLVED';
237
+ throw err;
238
+ },
220
239
  };
@@ -148,6 +148,21 @@ export interface IdeAdapter {
148
148
  * other IDEs without changing this signature (optional method).
149
149
  */
150
150
  readonly detectCurrentModel?: () => Promise<string | undefined>;
151
+ /**
152
+ * Slice 4.0.8 presence-lease-graph (RD §5): per-IDE caller-id resolution.
153
+ *
154
+ * Returns the calling window's `callerId` derived from the IDE's own
155
+ * session signal (e.g. `CLAUDE_CODE_SESSION_ID` for Claude Code). The
156
+ * adapter owns the priority rules (vendor-neutral override first, then
157
+ * the IDE-declared variable). Empty / missing / unsupported values
158
+ * resolve to a thrown `PEAKS_CALLER_NOT_RESOLVED` error so the CLI
159
+ * boundary can surface a typed envelope.
160
+ *
161
+ * Core presence / graph services MUST accept `callerId` as an argument
162
+ * and never inspect vendor env vars. Vendor neutrality is preserved by
163
+ * funnelling all vendor signal through this method.
164
+ */
165
+ readonly resolveCallerId: (env?: NodeJS.ProcessEnv) => string;
151
166
  }
152
167
  /**
153
168
  * Per-IDE auto-compact capability descriptor. See `IdeAdapter.compact`
@@ -31,16 +31,16 @@ export declare const JobProgressSchema: z.ZodObject<{
31
31
  updatedAt: z.ZodString;
32
32
  }, "strip", z.ZodTypeAny, {
33
33
  updatedAt: string;
34
- done: number;
35
34
  schemaVersion: 1;
35
+ done: number;
36
36
  jobId: string;
37
37
  total: number;
38
38
  currentSlice: string;
39
39
  lastCommitSha: string | null;
40
40
  }, {
41
41
  updatedAt: string;
42
- done: number;
43
42
  schemaVersion: 1;
43
+ done: number;
44
44
  jobId: string;
45
45
  total: number;
46
46
  currentSlice: string;