peaks-loop 4.0.8 → 4.0.10

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 (93) hide show
  1. package/CHANGELOG.md +38 -0
  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/container-commands.js +2 -1
  6. package/dist/cli/commands/core/skill-command.js +32 -5
  7. package/dist/cli/commands/openspec-commands.js +2 -1
  8. package/dist/cli/commands/statusline-commands.js +1 -1
  9. package/dist/services/audit/enforcers/active-skill-resolver.d.ts +11 -0
  10. package/dist/services/audit/enforcers/active-skill-resolver.js +50 -39
  11. package/dist/services/capability-audit-service/cross-check.d.ts +8 -0
  12. package/dist/services/capability-audit-service/cross-check.js +11 -0
  13. package/dist/services/capability-audit-service/index.d.ts +3 -0
  14. package/dist/services/capability-audit-service/index.js +2 -0
  15. package/dist/services/capability-audit-service/runner.d.ts +27 -0
  16. package/dist/services/capability-audit-service/runner.js +40 -0
  17. package/dist/services/capability-audit-service/staleness.d.ts +1 -0
  18. package/dist/services/capability-audit-service/staleness.js +7 -0
  19. package/dist/services/capability-audit-service/types.d.ts +24 -0
  20. package/dist/services/capability-audit-service/types.js +1 -0
  21. package/dist/services/capability-baseline/store.d.ts +33 -0
  22. package/dist/services/capability-baseline/store.js +80 -0
  23. package/dist/services/capability-baseline/types.d.ts +45 -0
  24. package/dist/services/capability-baseline/types.js +5 -0
  25. package/dist/services/capability-baseline/validator.d.ts +19 -0
  26. package/dist/services/capability-baseline/validator.js +38 -0
  27. package/dist/services/capability-guard-runner/contracts/J01.d.ts +2 -0
  28. package/dist/services/capability-guard-runner/contracts/J01.js +48 -0
  29. package/dist/services/capability-guard-runner/contracts/J02.d.ts +2 -0
  30. package/dist/services/capability-guard-runner/contracts/J02.js +34 -0
  31. package/dist/services/capability-guard-runner/contracts/J03.d.ts +2 -0
  32. package/dist/services/capability-guard-runner/contracts/J03.js +24 -0
  33. package/dist/services/capability-guard-runner/contracts/J04.d.ts +2 -0
  34. package/dist/services/capability-guard-runner/contracts/J04.js +40 -0
  35. package/dist/services/capability-guard-runner/contracts/J05.d.ts +2 -0
  36. package/dist/services/capability-guard-runner/contracts/J05.js +21 -0
  37. package/dist/services/capability-guard-runner/contracts/J06.d.ts +2 -0
  38. package/dist/services/capability-guard-runner/contracts/J06.js +43 -0
  39. package/dist/services/capability-guard-runner/contracts/J07.d.ts +2 -0
  40. package/dist/services/capability-guard-runner/contracts/J07.js +53 -0
  41. package/dist/services/capability-guard-runner/contracts/J08.d.ts +2 -0
  42. package/dist/services/capability-guard-runner/contracts/J08.js +43 -0
  43. package/dist/services/capability-guard-runner/contracts/J09.d.ts +2 -0
  44. package/dist/services/capability-guard-runner/contracts/J09.js +44 -0
  45. package/dist/services/capability-guard-runner/contracts/J10.d.ts +2 -0
  46. package/dist/services/capability-guard-runner/contracts/J10.js +40 -0
  47. package/dist/services/capability-guard-runner/contracts/J11.d.ts +2 -0
  48. package/dist/services/capability-guard-runner/contracts/J11.js +39 -0
  49. package/dist/services/capability-guard-runner/contracts/J12.d.ts +2 -0
  50. package/dist/services/capability-guard-runner/contracts/J12.js +34 -0
  51. package/dist/services/capability-guard-runner/contracts/J13.d.ts +2 -0
  52. package/dist/services/capability-guard-runner/contracts/J13.js +45 -0
  53. package/dist/services/capability-guard-runner/contracts/J14.d.ts +2 -0
  54. package/dist/services/capability-guard-runner/contracts/J14.js +36 -0
  55. package/dist/services/capability-guard-runner/contracts/J15.d.ts +2 -0
  56. package/dist/services/capability-guard-runner/contracts/J15.js +40 -0
  57. package/dist/services/capability-guard-runner/diff.d.ts +2 -0
  58. package/dist/services/capability-guard-runner/diff.js +7 -0
  59. package/dist/services/capability-guard-runner/runner.d.ts +9 -0
  60. package/dist/services/capability-guard-runner/runner.js +22 -0
  61. package/dist/services/capability-guard-runner/types.d.ts +39 -0
  62. package/dist/services/capability-guard-runner/types.js +1 -0
  63. package/dist/services/container/container-lease.js +2 -1
  64. package/dist/services/evolution/evolution-types.d.ts +16 -16
  65. package/dist/services/final-review/final-review-service.d.ts +8 -0
  66. package/dist/services/final-review/final-review-service.js +14 -0
  67. package/dist/services/final-review/final-review-types.d.ts +1 -1
  68. package/dist/services/impact/impact-scan-service.js +4 -3
  69. package/dist/services/job/job-progress-store.d.ts +2 -2
  70. package/dist/services/job/job-types.d.ts +26 -26
  71. package/dist/services/migrate-skill-name/migrate.js +2 -1
  72. package/dist/services/observability/observability-service.d.ts +2 -2
  73. package/dist/services/openspec/artifact-boundary.js +3 -2
  74. package/dist/services/openspec/coverage-evidence-reader.js +9 -8
  75. package/dist/services/prd/handoff-auto-regen.js +2 -1
  76. package/dist/services/scan/type-sanity-service.js +2 -1
  77. package/dist/services/sediment/json-schema.d.ts +4 -4
  78. package/dist/services/session/session-binding-bridge.js +17 -19
  79. package/dist/services/session/session-manager.js +36 -12
  80. package/dist/services/session/session-resume-service.d.ts +4 -0
  81. package/dist/services/session/session-resume-service.js +4 -0
  82. package/dist/services/skills/skill-statusline-renderer.d.ts +46 -56
  83. package/dist/services/skills/skill-statusline-renderer.js +335 -126
  84. package/dist/services/skills/skill-statusline-service.d.ts +6 -0
  85. package/dist/services/skills/skill-statusline-service.js +105 -7
  86. package/dist/services/vm/vm-lease.js +2 -1
  87. package/dist/services/workflow/workflow-autonomous-resume-helpers.js +3 -2
  88. package/dist/services/workspace/workspace-service.js +2 -1
  89. package/dist/services/worktree/worktree-lease.js +2 -1
  90. package/dist/shared/path-safety.js +3 -5
  91. package/dist/shared/path-utils.d.ts +48 -0
  92. package/dist/shared/path-utils.js +65 -1
  93. package/package.json +5 -4
@@ -0,0 +1,2 @@
1
+ import type { GuardContext, GuardRunResult } from '../types.js';
2
+ export declare function runJ10Contract(ctx: GuardContext): Promise<GuardRunResult>;
@@ -0,0 +1,40 @@
1
+ // src/services/capability-guard-runner/contracts/J10.ts
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ const CANDIDATE_FILES = [
5
+ 'src/cli/commands/hooks-commands.ts',
6
+ 'src/cli/commands/ide-commands.ts',
7
+ 'src/cli/commands/hook-handle.ts',
8
+ 'src/hooks/pre-tool-use-sub-agent.ts'
9
+ ];
10
+ export async function runJ10Contract(ctx) {
11
+ const existing = CANDIDATE_FILES.filter((f) => existsSync(join(ctx.projectRoot, f)));
12
+ if (existing.length === 0) {
13
+ return {
14
+ journeyId: 'J10',
15
+ contract: 'hook-assertion',
16
+ status: 'fail',
17
+ diff: { before: 'a hooks/ide/handle CLI file exists', after: 'no candidate found', reason: 'J10#1 broken: no IDE install/hook infrastructure is present' },
18
+ artifactPath: 'src/cli/commands/hooks-commands.ts'
19
+ };
20
+ }
21
+ const primary = existing.some((f) => {
22
+ const src = readFileSync(join(ctx.projectRoot, f), 'utf8').toLowerCase();
23
+ return src.includes('hook') || src.includes('install') || src.includes('ide') || src.includes('adapter');
24
+ });
25
+ if (!primary) {
26
+ return {
27
+ journeyId: 'J10',
28
+ contract: 'hook-assertion',
29
+ status: 'fail',
30
+ diff: { before: 'hooks/ide commands reference install/hook/ide/adapter', after: 'no such reference', reason: 'J10#1 broken: hooks/ide commands do not implement install/hook/ide/adapter' },
31
+ artifactPath: existing[0]
32
+ };
33
+ }
34
+ return {
35
+ journeyId: 'J10',
36
+ contract: 'hook-assertion',
37
+ status: 'pass',
38
+ artifactPath: existing[0]
39
+ };
40
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuardContext, GuardRunResult } from '../types.js';
2
+ export declare function runJ11Contract(ctx: GuardContext): Promise<GuardRunResult>;
@@ -0,0 +1,39 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const CANDIDATE_FILES = [
4
+ 'src/services/doctor/doctor-service.ts',
5
+ 'src/services/audit/audit-service.ts',
6
+ 'src/cli/commands/openspec-commands.ts',
7
+ 'src/services/openspec/openspec-propose-from-doctor-service.ts'
8
+ ];
9
+ export async function runJ11Contract(ctx) {
10
+ const existing = CANDIDATE_FILES.filter((f) => existsSync(join(ctx.projectRoot, f)));
11
+ if (existing.length === 0) {
12
+ return {
13
+ journeyId: 'J11',
14
+ contract: 'cli-output-golden',
15
+ status: 'fail',
16
+ diff: { before: 'a doctor/audit/openspec service exists', after: 'no candidate found', reason: 'J11#1 broken: no doctor surface is present' },
17
+ artifactPath: 'src/services/doctor/doctor-service.ts'
18
+ };
19
+ }
20
+ const primary = existing.some((f) => {
21
+ const src = readFileSync(join(ctx.projectRoot, f), 'utf8').toLowerCase();
22
+ return src.includes('doctor') || src.includes('audit') || src.includes('openspec') || src.includes('health');
23
+ });
24
+ if (!primary) {
25
+ return {
26
+ journeyId: 'J11',
27
+ contract: 'cli-output-golden',
28
+ status: 'fail',
29
+ diff: { before: 'doctor/audit/openspec references health/audit/openspec', after: 'no such reference', reason: 'J11#1 broken: doctor/audit/openspec services are not wired' },
30
+ artifactPath: existing[0]
31
+ };
32
+ }
33
+ return {
34
+ journeyId: 'J11',
35
+ contract: 'cli-output-golden',
36
+ status: 'pass',
37
+ artifactPath: existing[0]
38
+ };
39
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuardContext, GuardRunResult } from '../types.js';
2
+ export declare function runJ12Contract(ctx: GuardContext): Promise<GuardRunResult>;
@@ -0,0 +1,34 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const CANDIDATE_FILES = [
4
+ 'src/services/worktree/lease-store.ts',
5
+ 'src/services/worktree/worktree-lease.ts',
6
+ 'src/services/dispatch/sub-agent-dispatcher.ts',
7
+ 'src/services/lease-metrics/lease-metrics-service.ts'
8
+ ];
9
+ const REQUIRED_FRAGMENTS = ['lease', 'release'];
10
+ export async function runJ12Contract(ctx) {
11
+ const existing = CANDIDATE_FILES.filter((f) => existsSync(join(ctx.projectRoot, f)));
12
+ if (existing.length === 0) {
13
+ return {
14
+ journeyId: 'J12',
15
+ contract: 'concurrency-lease',
16
+ status: 'fail',
17
+ diff: { before: 'a worktree/lease/dispatch service exists', after: 'no candidate found', reason: 'J12#1 broken: no lease infrastructure is present' },
18
+ artifactPath: 'src/services/worktree/'
19
+ };
20
+ }
21
+ // Soft: at least one file references BOTH 'lease' AND 'release' in its content.
22
+ const fullCoverage = existing.some((f) => {
23
+ const src = readFileSync(join(ctx.projectRoot, f), 'utf8').toLowerCase();
24
+ return REQUIRED_FRAGMENTS.every((frag) => src.includes(frag));
25
+ });
26
+ const ok = fullCoverage;
27
+ return {
28
+ journeyId: 'J12',
29
+ contract: 'concurrency-lease',
30
+ status: ok ? 'pass' : 'fail',
31
+ ...(ok ? {} : { diff: { before: 'a worktree/lease service references both lease and release', after: 'no such file', reason: 'J12#1 broken: lease lifecycle (lease + release) is incomplete' } }),
32
+ artifactPath: existing[0]
33
+ };
34
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuardContext, GuardRunResult } from '../types.js';
2
+ export declare function runJ13Contract(ctx: GuardContext): Promise<GuardRunResult>;
@@ -0,0 +1,45 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const CANDIDATE_FILES = [
4
+ 'skills/peaks-content/SKILL.md',
5
+ 'src/services/content/',
6
+ 'src/services/workflow/workflow-router-service.ts',
7
+ '.peaks/standards/loop-engineering-guidelines.md'
8
+ ];
9
+ const STAGES = ['draft', 'edit', 'tone', 'publish', 'archive'];
10
+ export async function runJ13Contract(ctx) {
11
+ const existing = CANDIDATE_FILES.filter((f) => existsSync(join(ctx.projectRoot, f)));
12
+ if (existing.length === 0) {
13
+ return {
14
+ journeyId: 'J13',
15
+ contract: 'workflow-trace',
16
+ status: 'fail',
17
+ diff: { before: 'a content / peaks-content skill exists', after: 'no candidate found', reason: 'J13#1 broken: no content production surface is present' },
18
+ artifactPath: 'skills/peaks-content/SKILL.md'
19
+ };
20
+ }
21
+ // Soft check: at least 3 of 5 stages appear in any existing file's content.
22
+ const matchedStages = new Set();
23
+ for (const file of existing) {
24
+ const src = readFileSync(join(ctx.projectRoot, file), 'utf8').toLowerCase();
25
+ for (const stage of STAGES) {
26
+ if (src.includes(stage))
27
+ matchedStages.add(stage);
28
+ }
29
+ }
30
+ if (matchedStages.size < 3) {
31
+ return {
32
+ journeyId: 'J13',
33
+ contract: 'workflow-trace',
34
+ status: 'fail',
35
+ diff: { before: 'at least 3 of draft/edit/tone/publish/archive stages are referenced', after: `only ${[...matchedStages].join(',')} found`, reason: 'J13#1 broken: content pipeline has too few stages' },
36
+ artifactPath: existing[0]
37
+ };
38
+ }
39
+ return {
40
+ journeyId: 'J13',
41
+ contract: 'workflow-trace',
42
+ status: 'pass',
43
+ artifactPath: existing[0]
44
+ };
45
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuardContext, GuardRunResult } from '../types.js';
2
+ export declare function runJ14Contract(ctx: GuardContext): Promise<GuardRunResult>;
@@ -0,0 +1,36 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const CANDIDATE_FILES = [
4
+ 'skills/peaks-issue-fix-orchestrator/SKILL.md',
5
+ '.peaks/memory/peaks-loop-positioning-loop-engineering.md',
6
+ '.peaks/standards/loop-engineering-guidelines.md'
7
+ ];
8
+ const REQUIRED_STAGES = ['triage', 'classify', 'fix', 'commit'];
9
+ export async function runJ14Contract(ctx) {
10
+ const existing = CANDIDATE_FILES.filter((f) => existsSync(join(ctx.projectRoot, f)));
11
+ if (existing.length === 0) {
12
+ return {
13
+ journeyId: 'J14',
14
+ contract: 'workflow-trace',
15
+ status: 'fail',
16
+ diff: { before: 'a peaks-issue-fix-orchestrator skill or memory file exists', after: 'no candidate found', reason: 'J14#1 broken: no issue-sweep surface is present' },
17
+ artifactPath: 'skills/peaks-issue-fix-orchestrator/SKILL.md'
18
+ };
19
+ }
20
+ const matched = new Set();
21
+ for (const file of existing) {
22
+ const src = readFileSync(join(ctx.projectRoot, file), 'utf8').toLowerCase();
23
+ for (const stage of REQUIRED_STAGES) {
24
+ if (src.includes(stage))
25
+ matched.add(stage);
26
+ }
27
+ }
28
+ const ok = matched.size >= 2;
29
+ return {
30
+ journeyId: 'J14',
31
+ contract: 'workflow-trace',
32
+ status: ok ? 'pass' : 'fail',
33
+ ...(ok ? {} : { diff: { before: 'at least 2 of triage/classify/fix/commit are referenced', after: `only ${[...matched].join(',')} found`, reason: 'J14#1 broken: issue-sweep pipeline has too few stages' } }),
34
+ artifactPath: existing[0]
35
+ };
36
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuardContext, GuardRunResult } from '../types.js';
2
+ export declare function runJ15Contract(ctx: GuardContext): Promise<GuardRunResult>;
@@ -0,0 +1,40 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const CANDIDATE_FILES = [
4
+ 'src/services/openspec/openspec-archive-service.ts',
5
+ 'src/services/openspec/coverage-evidence-reader.ts',
6
+ 'src/cli/commands/openspec-commands.ts'
7
+ ];
8
+ const REQUIRED_FRAGMENTS = ['Capability Mapping', 'coverage'];
9
+ export async function runJ15Contract(ctx) {
10
+ const existing = CANDIDATE_FILES.filter((f) => existsSync(join(ctx.projectRoot, f)));
11
+ if (existing.length === 0) {
12
+ return {
13
+ journeyId: 'J15',
14
+ contract: 'spec-coverage',
15
+ status: 'fail',
16
+ diff: { before: 'an openspec archive/coverage service exists', after: 'no candidate found', reason: 'J15#1 broken: no openspec/coverage surface is present' },
17
+ artifactPath: 'src/services/openspec/'
18
+ };
19
+ }
20
+ // At least one file references BOTH "Capability Mapping" AND "coverage".
21
+ const fullCoverage = existing.some((f) => {
22
+ const src = readFileSync(join(ctx.projectRoot, f), 'utf8');
23
+ return REQUIRED_FRAGMENTS.every((frag) => src.includes(frag));
24
+ });
25
+ if (!fullCoverage) {
26
+ return {
27
+ journeyId: 'J15',
28
+ contract: 'spec-coverage',
29
+ status: 'fail',
30
+ diff: { before: 'openspec services reference both "Capability Mapping" and "coverage"', after: 'no such service', reason: 'J15#1 broken: openspec archive gate is missing the Capability Mapping + coverage cross-check' },
31
+ artifactPath: existing[0]
32
+ };
33
+ }
34
+ return {
35
+ journeyId: 'J15',
36
+ contract: 'spec-coverage',
37
+ status: 'pass',
38
+ artifactPath: existing[0]
39
+ };
40
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuardDiff } from './types.js';
2
+ export declare function formatHumanReadableDiff(diff: GuardDiff): string;
@@ -0,0 +1,7 @@
1
+ export function formatHumanReadableDiff(diff) {
2
+ return [
3
+ `reason: ${diff.reason}`,
4
+ `- ${diff.before}`,
5
+ `+ ${diff.after}`
6
+ ].join('\n');
7
+ }
@@ -0,0 +1,9 @@
1
+ import type { GuardContract, GuardContext, GuardRunResult } from './types.js';
2
+ export declare function runGuard(contract: GuardContract, ctx: GuardContext): Promise<GuardRunResult>;
3
+ export declare function runAllGuards(contracts: ReadonlyArray<GuardContract>, ctx: GuardContext): Promise<{
4
+ readonly pass: number;
5
+ readonly fail: number;
6
+ readonly skipped: number;
7
+ readonly total: number;
8
+ readonly results: ReadonlyArray<GuardRunResult>;
9
+ }>;
@@ -0,0 +1,22 @@
1
+ function assertBaselineRef(contract) {
2
+ if (!contract.source.baselineRow || !contract.source.invariant) {
3
+ throw new Error('GUARD_CONTRACT_MISSING_BASELINE_REF: contract must reference a baseline row and invariant');
4
+ }
5
+ }
6
+ export async function runGuard(contract, ctx) {
7
+ assertBaselineRef(contract);
8
+ return contract.execute(ctx);
9
+ }
10
+ export async function runAllGuards(contracts, ctx) {
11
+ const results = [];
12
+ for (const c of contracts) {
13
+ results.push(await runGuard(c, ctx));
14
+ }
15
+ return {
16
+ pass: results.filter((r) => r.status === 'pass').length,
17
+ fail: results.filter((r) => r.status === 'fail').length,
18
+ skipped: results.filter((r) => r.status === 'skipped').length,
19
+ total: results.length,
20
+ results
21
+ };
22
+ }
@@ -0,0 +1,39 @@
1
+ import type { JourneyId } from '../capability-baseline/types.js';
2
+ export type ContractKind = 'cli-envelope' | 'workflow-trace' | 'hook-assertion' | 'cli-output-golden' | 'asset-roundtrip' | 'concurrency-lease' | 'sop-register' | 'spec-coverage' | 'envelope-arg-shapes';
3
+ export interface GuardContract {
4
+ readonly journeyId: JourneyId;
5
+ readonly kind: ContractKind;
6
+ readonly source: {
7
+ readonly baselineRow: JourneyId;
8
+ readonly invariant: string;
9
+ };
10
+ readonly execute: (ctx: GuardContext) => Promise<GuardRunResult>;
11
+ readonly evidence: {
12
+ readonly kind: ContractKind;
13
+ readonly artifact: string;
14
+ };
15
+ }
16
+ export interface GuardContext {
17
+ readonly projectRoot: string;
18
+ readonly sessionId: string;
19
+ readonly contract: GuardContract;
20
+ readonly baselineInvariant: string;
21
+ }
22
+ export type GuardStatus = 'pass' | 'fail' | 'skipped';
23
+ export interface GuardDiff {
24
+ readonly before: string;
25
+ readonly after: string;
26
+ readonly reason: string;
27
+ }
28
+ export interface GuardRunResult {
29
+ readonly journeyId: JourneyId;
30
+ readonly contract: ContractKind;
31
+ readonly status: GuardStatus;
32
+ readonly diff?: GuardDiff;
33
+ readonly artifactPath: string;
34
+ }
35
+ export type GuardErrorCode = 'GUARD_CONTRACT_MISSING_BASELINE_REF' | 'GUARD_DIFF_DETECTED' | 'GUARD_TEST_FLAKY';
36
+ export interface GuardError {
37
+ readonly code: GuardErrorCode;
38
+ readonly message: string;
39
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -29,6 +29,7 @@
29
29
  */
30
30
  import { randomBytes } from 'node:crypto';
31
31
  import { posix as path } from 'node:path';
32
+ import { normalizePath } from '../../shared/path-utils.js';
32
33
  export const DEFAULT_TTL_BY_ROLE = Object.freeze({
33
34
  rd: 30 * 60 * 1_000,
34
35
  qa: 15 * 60 * 1_000,
@@ -126,7 +127,7 @@ export function deserializeContainerLease(raw) {
126
127
  function joinPath(...segments) {
127
128
  if (segments.length === 0)
128
129
  return '';
129
- const normalized = segments.map((s) => s.replace(/\\/g, '/'));
130
+ const normalized = segments.map((s) => normalizePath(s));
130
131
  let acc = normalized[0];
131
132
  for (let i = 1; i < normalized.length; i++) {
132
133
  acc = path.join(acc, normalized[i]);
@@ -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';