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.
- package/CHANGELOG.md +38 -0
- package/dist/cli/commands/_register.js +2 -0
- package/dist/cli/commands/baseline-commands.d.ts +3 -0
- package/dist/cli/commands/baseline-commands.js +146 -0
- package/dist/cli/commands/container-commands.js +2 -1
- package/dist/cli/commands/core/skill-command.js +32 -5
- package/dist/cli/commands/openspec-commands.js +2 -1
- package/dist/cli/commands/statusline-commands.js +1 -1
- package/dist/services/audit/enforcers/active-skill-resolver.d.ts +11 -0
- package/dist/services/audit/enforcers/active-skill-resolver.js +50 -39
- package/dist/services/capability-audit-service/cross-check.d.ts +8 -0
- package/dist/services/capability-audit-service/cross-check.js +11 -0
- package/dist/services/capability-audit-service/index.d.ts +3 -0
- package/dist/services/capability-audit-service/index.js +2 -0
- package/dist/services/capability-audit-service/runner.d.ts +27 -0
- package/dist/services/capability-audit-service/runner.js +40 -0
- package/dist/services/capability-audit-service/staleness.d.ts +1 -0
- package/dist/services/capability-audit-service/staleness.js +7 -0
- package/dist/services/capability-audit-service/types.d.ts +24 -0
- package/dist/services/capability-audit-service/types.js +1 -0
- package/dist/services/capability-baseline/store.d.ts +33 -0
- package/dist/services/capability-baseline/store.js +80 -0
- package/dist/services/capability-baseline/types.d.ts +45 -0
- package/dist/services/capability-baseline/types.js +5 -0
- package/dist/services/capability-baseline/validator.d.ts +19 -0
- package/dist/services/capability-baseline/validator.js +38 -0
- package/dist/services/capability-guard-runner/contracts/J01.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J01.js +48 -0
- package/dist/services/capability-guard-runner/contracts/J02.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J02.js +34 -0
- package/dist/services/capability-guard-runner/contracts/J03.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J03.js +24 -0
- package/dist/services/capability-guard-runner/contracts/J04.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J04.js +40 -0
- package/dist/services/capability-guard-runner/contracts/J05.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J05.js +21 -0
- package/dist/services/capability-guard-runner/contracts/J06.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J06.js +43 -0
- package/dist/services/capability-guard-runner/contracts/J07.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J07.js +53 -0
- package/dist/services/capability-guard-runner/contracts/J08.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J08.js +43 -0
- package/dist/services/capability-guard-runner/contracts/J09.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J09.js +44 -0
- package/dist/services/capability-guard-runner/contracts/J10.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J10.js +40 -0
- package/dist/services/capability-guard-runner/contracts/J11.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J11.js +39 -0
- package/dist/services/capability-guard-runner/contracts/J12.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J12.js +34 -0
- package/dist/services/capability-guard-runner/contracts/J13.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J13.js +45 -0
- package/dist/services/capability-guard-runner/contracts/J14.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J14.js +36 -0
- package/dist/services/capability-guard-runner/contracts/J15.d.ts +2 -0
- package/dist/services/capability-guard-runner/contracts/J15.js +40 -0
- package/dist/services/capability-guard-runner/diff.d.ts +2 -0
- package/dist/services/capability-guard-runner/diff.js +7 -0
- package/dist/services/capability-guard-runner/runner.d.ts +9 -0
- package/dist/services/capability-guard-runner/runner.js +22 -0
- package/dist/services/capability-guard-runner/types.d.ts +39 -0
- package/dist/services/capability-guard-runner/types.js +1 -0
- package/dist/services/container/container-lease.js +2 -1
- package/dist/services/evolution/evolution-types.d.ts +16 -16
- package/dist/services/final-review/final-review-service.d.ts +8 -0
- package/dist/services/final-review/final-review-service.js +14 -0
- package/dist/services/final-review/final-review-types.d.ts +1 -1
- package/dist/services/impact/impact-scan-service.js +4 -3
- package/dist/services/job/job-progress-store.d.ts +2 -2
- package/dist/services/job/job-types.d.ts +26 -26
- package/dist/services/migrate-skill-name/migrate.js +2 -1
- package/dist/services/observability/observability-service.d.ts +2 -2
- package/dist/services/openspec/artifact-boundary.js +3 -2
- package/dist/services/openspec/coverage-evidence-reader.js +9 -8
- package/dist/services/prd/handoff-auto-regen.js +2 -1
- package/dist/services/scan/type-sanity-service.js +2 -1
- package/dist/services/sediment/json-schema.d.ts +4 -4
- package/dist/services/session/session-binding-bridge.js +17 -19
- package/dist/services/session/session-manager.js +36 -12
- package/dist/services/session/session-resume-service.d.ts +4 -0
- package/dist/services/session/session-resume-service.js +4 -0
- package/dist/services/skills/skill-statusline-renderer.d.ts +46 -56
- package/dist/services/skills/skill-statusline-renderer.js +335 -126
- package/dist/services/skills/skill-statusline-service.d.ts +6 -0
- package/dist/services/skills/skill-statusline-service.js +105 -7
- package/dist/services/vm/vm-lease.js +2 -1
- package/dist/services/workflow/workflow-autonomous-resume-helpers.js +3 -2
- package/dist/services/workspace/workspace-service.js +2 -1
- package/dist/services/worktree/worktree-lease.js +2 -1
- package/dist/shared/path-safety.js +3 -5
- package/dist/shared/path-utils.d.ts +48 -0
- package/dist/shared/path-utils.js +65 -1
- package/package.json +5 -4
|
@@ -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,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,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,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,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,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,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
|
|
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';
|