ai-engineering-loop 1.0.2 → 1.0.3
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/README.full.md +251 -0
- package/README.md +23 -30
- package/agents/devil-advocate.md +54 -92
- package/core/judge-policy.md +48 -101
- package/core/orchestration-model.md +87 -0
- package/core/verification-loop.md +47 -83
- package/lib/orchestration.js +409 -0
- package/package.json +2 -2
- package/policies/evidence-policy.md +33 -15
- package/policies/finding-policy.md +39 -71
- package/tests/capability-selection.test.js +207 -0
- package/tests/orchestration.test.js +288 -0
- package/.README.github.bak.md +0 -272
- package/scripts/publish-npm.js +0 -32
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const assert = require('node:assert');
|
|
3
|
+
const {
|
|
4
|
+
EXECUTION_MODES,
|
|
5
|
+
createCapabilityEvidence,
|
|
6
|
+
selectExecutionMode,
|
|
7
|
+
formatExecutionReport
|
|
8
|
+
} = require('../lib/orchestration.js');
|
|
9
|
+
|
|
10
|
+
// Test 1: Distinction between CONFIGURATION_SUPPORTED and INVOCATION_AVAILABLE / EXECUTION_PROVEN
|
|
11
|
+
test('1. CONFIGURATION_SUPPORTED = true, INVOCATION_AVAILABLE = false, EXECUTION_PROVEN = false resolves to CONTEXT_ISOLATION_ONLY', () => {
|
|
12
|
+
const antigravityDiscovery = {
|
|
13
|
+
nativeSubagent: createCapabilityEvidence({
|
|
14
|
+
mechanism: 'antigravity-custom-agent-config',
|
|
15
|
+
classification: 'CONFIGURATION_SUPPORTED_WITHOUT_INVOCATION_TOOL',
|
|
16
|
+
configurationSupported: true, // .agents/plugins/.../AGENT.md with subagent: true is discoverable
|
|
17
|
+
invocationAvailable: false, // No invoke_subagent tool in active prompt
|
|
18
|
+
executionProven: false, // No child execution occurred
|
|
19
|
+
isDocumentationOnly: false,
|
|
20
|
+
reason: 'Antigravity custom subagent configuration is supported/discoverable, but native subagent invocation is not exposed or executable from the current standalone agent runtime'
|
|
21
|
+
}),
|
|
22
|
+
sdkAgent: createCapabilityEvidence({
|
|
23
|
+
mechanism: 'google-antigravity-python-sdk',
|
|
24
|
+
classification: 'UNAVAILABLE',
|
|
25
|
+
available: false,
|
|
26
|
+
reason: 'Package not installed in Python environment'
|
|
27
|
+
}),
|
|
28
|
+
headlessProcessAgent: createCapabilityEvidence({
|
|
29
|
+
mechanism: 'claude-code-cli',
|
|
30
|
+
classification: 'UNAVAILABLE',
|
|
31
|
+
available: false,
|
|
32
|
+
reason: 'CLI unauthenticated'
|
|
33
|
+
}),
|
|
34
|
+
artifactIsolation: createCapabilityEvidence({
|
|
35
|
+
mechanism: 'clean-slate-artifact-barrier',
|
|
36
|
+
classification: 'CONTEXT_ISOLATION_ONLY',
|
|
37
|
+
available: true,
|
|
38
|
+
commandOrApi: 'buildReviewContextBarrier',
|
|
39
|
+
result: 'Verified 100% prompt history exclusion',
|
|
40
|
+
modelExecutionProven: false,
|
|
41
|
+
independentContextProven: false
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const selected = selectExecutionMode(antigravityDiscovery);
|
|
46
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.CONTEXT_ISOLATION_ONLY.id);
|
|
47
|
+
assert.strictEqual(selected.isIndependentExecutionProven, false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Test 2: browser_subagent is browser automation and CANNOT activate LLM subagent execution
|
|
51
|
+
test('2. browser_subagent cannot activate LLM subagent execution mode', () => {
|
|
52
|
+
const browserSubagentEvidence = createCapabilityEvidence({
|
|
53
|
+
mechanism: 'browser_subagent-tool',
|
|
54
|
+
classification: 'BROWSER_AUTOMATION_TOOL',
|
|
55
|
+
available: true,
|
|
56
|
+
isBrowserAutomationOnly: true,
|
|
57
|
+
reason: 'browser_subagent is scoped to DOM/browser navigation automation, not general LLM code review'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const registry = {
|
|
61
|
+
nativeSubagent: browserSubagentEvidence,
|
|
62
|
+
artifactIsolation: createCapabilityEvidence({
|
|
63
|
+
mechanism: 'clean-slate-artifact-barrier',
|
|
64
|
+
classification: 'CONTEXT_ISOLATION_ONLY',
|
|
65
|
+
available: true
|
|
66
|
+
})
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const selected = selectExecutionMode(registry);
|
|
70
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.CONTEXT_ISOLATION_ONLY.id);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Test 3: agentapi.send-message is IPC communication and cannot activate an agent capability
|
|
74
|
+
test('3. agentapi.send-message is IPC_MESSAGE_DISPATCH and cannot activate agent capability', () => {
|
|
75
|
+
const ipcEvidence = createCapabilityEvidence({
|
|
76
|
+
mechanism: 'antigravity-agentapi-send-message',
|
|
77
|
+
classification: 'IPC_MESSAGE_DISPATCH',
|
|
78
|
+
available: true,
|
|
79
|
+
commandOrApi: 'agentapi send-message',
|
|
80
|
+
result: 'Message delivered to existing conversation over gRPC',
|
|
81
|
+
modelExecutionProven: false
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const registry = {
|
|
85
|
+
nativeSubagent: ipcEvidence,
|
|
86
|
+
artifactIsolation: createCapabilityEvidence({
|
|
87
|
+
mechanism: 'clean-slate-artifact-barrier',
|
|
88
|
+
classification: 'CONTEXT_ISOLATION_ONLY',
|
|
89
|
+
available: true
|
|
90
|
+
})
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const selected = selectExecutionMode(registry);
|
|
94
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.CONTEXT_ISOLATION_ONLY.id);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Test 4: agentapi.new-conversation failure cannot activate an agent capability
|
|
98
|
+
test('4. agentapi.new-conversation failure cannot activate an agent capability', () => {
|
|
99
|
+
const rpcFailedEvidence = createCapabilityEvidence({
|
|
100
|
+
mechanism: 'antigravity-agentapi-new-conversation',
|
|
101
|
+
classification: 'UNAVAILABLE',
|
|
102
|
+
available: false,
|
|
103
|
+
commandOrApi: 'agentapi new-conversation',
|
|
104
|
+
result: 'rpc error: project_id is required when providing project_env_config',
|
|
105
|
+
modelExecutionProven: false,
|
|
106
|
+
reason: 'new-conversation reaches the Language Server but is blocked by project_id authorization in the current standalone workspace'
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const registry = {
|
|
110
|
+
nativeSubagent: rpcFailedEvidence,
|
|
111
|
+
artifactIsolation: createCapabilityEvidence({
|
|
112
|
+
mechanism: 'clean-slate-artifact-barrier',
|
|
113
|
+
classification: 'CONTEXT_ISOLATION_ONLY',
|
|
114
|
+
available: true
|
|
115
|
+
})
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const selected = selectExecutionMode(registry);
|
|
119
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.CONTEXT_ISOLATION_ONLY.id);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Test 5: Missing child model response cannot activate an independent agent
|
|
123
|
+
test('5. Missing model response cannot activate an independent agent', () => {
|
|
124
|
+
const threadWithoutModelResponse = createCapabilityEvidence({
|
|
125
|
+
mechanism: 'child-thread-without-response',
|
|
126
|
+
classification: 'THREAD_CREATED_WITHOUT_RESPONSE',
|
|
127
|
+
available: true,
|
|
128
|
+
childConversationId: 'child-conv-1234',
|
|
129
|
+
modelExecutionProven: false, // No response produced
|
|
130
|
+
independentContextProven: false
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const registry = {
|
|
134
|
+
nativeSubagent: threadWithoutModelResponse,
|
|
135
|
+
artifactIsolation: createCapabilityEvidence({
|
|
136
|
+
mechanism: 'clean-slate-artifact-barrier',
|
|
137
|
+
classification: 'CONTEXT_ISOLATION_ONLY',
|
|
138
|
+
available: true
|
|
139
|
+
})
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const selected = selectExecutionMode(registry);
|
|
143
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.CONTEXT_ISOLATION_ONLY.id);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Test 6: Truthful report format strictly produces the required 4-line disclosure
|
|
147
|
+
test('6. Truthful report format strictly produces the required 4-line disclosure', () => {
|
|
148
|
+
const capabilityRegistry = {
|
|
149
|
+
nativeSubagent: {
|
|
150
|
+
invocationAvailable: false
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const report = formatExecutionReport({
|
|
155
|
+
selectedMode: EXECUTION_MODES.CONTEXT_ISOLATION_ONLY,
|
|
156
|
+
capabilityRegistry
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const expected = [
|
|
160
|
+
'Execution Mode: CONTEXT_ISOLATION_ONLY',
|
|
161
|
+
'Independent LLM Execution: NOT PROVEN',
|
|
162
|
+
'Native Subagent Invocation: UNAVAILABLE',
|
|
163
|
+
'Review Method: Clean-Slate Artifact Isolation Barrier'
|
|
164
|
+
].join('\n');
|
|
165
|
+
|
|
166
|
+
assert.strictEqual(report, expected);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Test 7: TRUE_INDEPENDENT_AGENT is selected ONLY when full execution evidence is proven
|
|
170
|
+
test('7. TRUE_INDEPENDENT_AGENT is selected ONLY when child session, response, identity, and context are proven', () => {
|
|
171
|
+
const fullyProvenEvidence = createCapabilityEvidence({
|
|
172
|
+
mechanism: 'native-subagent-runtime-tool',
|
|
173
|
+
classification: 'TRUE_INDEPENDENT_AGENT',
|
|
174
|
+
available: true,
|
|
175
|
+
commandOrApi: 'invoke_subagent',
|
|
176
|
+
childConversationId: 'child-session-9876',
|
|
177
|
+
executionIdentity: 'grpc-stream-552',
|
|
178
|
+
childModelResponse: 'CHILD_AGENT_EXECUTION_OK',
|
|
179
|
+
modelExecutionProven: true,
|
|
180
|
+
independentContextProven: true,
|
|
181
|
+
historyInherited: false,
|
|
182
|
+
result: 'Actual child response captured: CHILD_AGENT_EXECUTION_OK'
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const registry = {
|
|
186
|
+
nativeSubagent: fullyProvenEvidence,
|
|
187
|
+
artifactIsolation: { available: true }
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const selected = selectExecutionMode(registry);
|
|
191
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.TRUE_INDEPENDENT_AGENT.id);
|
|
192
|
+
assert.strictEqual(selected.isIndependentExecutionProven, true);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Test 8: Fallback to UNAVAILABLE when all modes including artifact isolation are unavailable
|
|
196
|
+
test('8. Fallback to UNAVAILABLE when all modes are false', () => {
|
|
197
|
+
const emptyRegistry = {
|
|
198
|
+
nativeSubagent: { available: false },
|
|
199
|
+
sdkAgent: { available: false },
|
|
200
|
+
headlessProcessAgent: { available: false },
|
|
201
|
+
artifactIsolation: { available: false }
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const selected = selectExecutionMode(emptyRegistry);
|
|
205
|
+
assert.strictEqual(selected.id, EXECUTION_MODES.UNAVAILABLE.id);
|
|
206
|
+
assert.strictEqual(selected.isIndependentExecutionProven, false);
|
|
207
|
+
});
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const assert = require('node:assert');
|
|
3
|
+
const {
|
|
4
|
+
EXECUTION_MODES,
|
|
5
|
+
createCapabilityEvidence,
|
|
6
|
+
selectExecutionMode,
|
|
7
|
+
buildReviewContextBarrier,
|
|
8
|
+
validateVerificationEvidence,
|
|
9
|
+
validateFindingLedger,
|
|
10
|
+
computeJudgeVerdict
|
|
11
|
+
} = require('../lib/orchestration.js');
|
|
12
|
+
|
|
13
|
+
// Test A: Independent execution mode selection priority using capability registry
|
|
14
|
+
test('A. Independent execution mode selection priority using capability registry', () => {
|
|
15
|
+
// Priority 1: Native subagent with full execution proof
|
|
16
|
+
assert.strictEqual(
|
|
17
|
+
selectExecutionMode({
|
|
18
|
+
nativeSubagent: createCapabilityEvidence({
|
|
19
|
+
mechanism: 'native-subagent',
|
|
20
|
+
classification: 'TRUE_INDEPENDENT_AGENT',
|
|
21
|
+
available: true,
|
|
22
|
+
executionProven: true,
|
|
23
|
+
childConversationId: 'child-101',
|
|
24
|
+
executionIdentity: 'exec-101',
|
|
25
|
+
modelExecutionProven: true,
|
|
26
|
+
independentContextProven: true
|
|
27
|
+
}),
|
|
28
|
+
sdkAgent: createCapabilityEvidence({
|
|
29
|
+
mechanism: 'sdk-agent',
|
|
30
|
+
classification: 'ISOLATED_AGENT_INSTANCE',
|
|
31
|
+
available: true,
|
|
32
|
+
executionProven: true,
|
|
33
|
+
childConversationId: 'child-102',
|
|
34
|
+
executionIdentity: 'exec-102',
|
|
35
|
+
modelExecutionProven: true
|
|
36
|
+
})
|
|
37
|
+
}).id,
|
|
38
|
+
EXECUTION_MODES.TRUE_INDEPENDENT_AGENT.id
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Priority 2: SDK Agent Instance
|
|
42
|
+
assert.strictEqual(
|
|
43
|
+
selectExecutionMode({
|
|
44
|
+
nativeSubagent: createCapabilityEvidence({
|
|
45
|
+
mechanism: 'native-subagent',
|
|
46
|
+
classification: 'UNAVAILABLE',
|
|
47
|
+
available: false
|
|
48
|
+
}),
|
|
49
|
+
sdkAgent: createCapabilityEvidence({
|
|
50
|
+
mechanism: 'sdk-agent',
|
|
51
|
+
classification: 'ISOLATED_AGENT_INSTANCE',
|
|
52
|
+
available: true,
|
|
53
|
+
executionProven: true,
|
|
54
|
+
childConversationId: 'child-102',
|
|
55
|
+
executionIdentity: 'exec-102',
|
|
56
|
+
modelExecutionProven: true
|
|
57
|
+
})
|
|
58
|
+
}).id,
|
|
59
|
+
EXECUTION_MODES.ISOLATED_AGENT_INSTANCE.id
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Priority 3: Headless Subprocess
|
|
63
|
+
assert.strictEqual(
|
|
64
|
+
selectExecutionMode({
|
|
65
|
+
headlessProcessAgent: createCapabilityEvidence({
|
|
66
|
+
mechanism: 'cli-agent',
|
|
67
|
+
classification: 'FRESH_PROCESS_AGENT',
|
|
68
|
+
available: true,
|
|
69
|
+
executionProven: true,
|
|
70
|
+
executionIdentity: 'pid-8821',
|
|
71
|
+
modelExecutionProven: true
|
|
72
|
+
})
|
|
73
|
+
}).id,
|
|
74
|
+
EXECUTION_MODES.FRESH_PROCESS_AGENT.id
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Priority 4: Fallback to Artifact Isolated Review
|
|
78
|
+
const fallback = selectExecutionMode({
|
|
79
|
+
artifactIsolation: createCapabilityEvidence({
|
|
80
|
+
mechanism: 'artifact-barrier',
|
|
81
|
+
classification: 'CONTEXT_ISOLATION_ONLY',
|
|
82
|
+
available: true
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
assert.strictEqual(fallback.id, EXECUTION_MODES.CONTEXT_ISOLATION_ONLY.id);
|
|
86
|
+
assert.strictEqual(fallback.isIndependentExecutionProven, false);
|
|
87
|
+
assert.strictEqual(fallback.description, 'Isolated review context within the same LLM session; independent agent execution is NOT proven');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Test B & H: Artifact isolation strictly bounds review context without conversational history
|
|
91
|
+
test('B & H. Artifact isolation strictly bounds review context without conversational history', () => {
|
|
92
|
+
const goalContract = {
|
|
93
|
+
objective: 'Fix race condition in payment queue',
|
|
94
|
+
acceptanceCriteria: ['AC-1: Lock payment row before update'],
|
|
95
|
+
technicalConstraints: ['Zero schema migrations'],
|
|
96
|
+
outOfScope: ['Refund system']
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const rawDiff = `
|
|
100
|
+
diff --git a/src/pay.ts b/src/pay.ts
|
|
101
|
+
+ const lock = await db.query('SELECT FOR UPDATE');
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
const verificationLogs = {
|
|
105
|
+
exitCode: 0,
|
|
106
|
+
summary: '10 passed, 0 failed'
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const payload = buildReviewContextBarrier({
|
|
110
|
+
goalContract,
|
|
111
|
+
gitDiff: rawDiff,
|
|
112
|
+
verificationLogs,
|
|
113
|
+
projectContext: { profile: 'backend-api' }
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Verify only objective fields exist
|
|
117
|
+
assert.ok(payload.diffHash);
|
|
118
|
+
assert.strictEqual(payload.goalContract.objective, 'Fix race condition in payment queue');
|
|
119
|
+
assert.strictEqual(payload.gitDiff.includes('SELECT FOR UPDATE'), true);
|
|
120
|
+
assert.strictEqual(payload.verificationLogs.exitCode, 0);
|
|
121
|
+
|
|
122
|
+
// Verify conversational scratchpad / thoughts are NOT in payload
|
|
123
|
+
assert.strictEqual(payload.makerThoughts, undefined);
|
|
124
|
+
assert.strictEqual(payload.chatHistory, undefined);
|
|
125
|
+
assert.strictEqual(payload.intermediateDrafts, undefined);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Test C: Finding Ledger schema validation
|
|
129
|
+
test('C. Finding Ledger schema validation', () => {
|
|
130
|
+
const validLedger = {
|
|
131
|
+
findings: [
|
|
132
|
+
{
|
|
133
|
+
id: 'DA-1',
|
|
134
|
+
topic: 'correctness',
|
|
135
|
+
severity: 'BLOCKER',
|
|
136
|
+
validity: 'VALID',
|
|
137
|
+
disposition: 'STRONG',
|
|
138
|
+
location: 'src/pay.ts#L20-L30',
|
|
139
|
+
failureScenario: 'Deadlock under concurrent traffic',
|
|
140
|
+
evidence: 'Race condition reproduced in load test',
|
|
141
|
+
concreteAlternativeDiff: '- lock()\n+ lockWithTimeout()'
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const check = validateFindingLedger(validLedger);
|
|
147
|
+
assert.strictEqual(check.valid, true);
|
|
148
|
+
|
|
149
|
+
// Invalid severity test
|
|
150
|
+
const invalidLedger = {
|
|
151
|
+
findings: [
|
|
152
|
+
{
|
|
153
|
+
id: 'DA-2',
|
|
154
|
+
severity: 'SUPER_CRITICAL', // invalid
|
|
155
|
+
validity: 'VALID',
|
|
156
|
+
disposition: 'STRONG',
|
|
157
|
+
location: 'src/pay.ts#L10',
|
|
158
|
+
failureScenario: 'Crash',
|
|
159
|
+
evidence: 'Log trace'
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
};
|
|
163
|
+
const invalidCheck = validateFindingLedger(invalidLedger);
|
|
164
|
+
assert.strictEqual(invalidCheck.valid, false);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Test E: Verification Evidence Contract
|
|
168
|
+
test('E. Verification Evidence Contract strictly enforces execution proof', () => {
|
|
169
|
+
// 1. Valid execution evidence
|
|
170
|
+
const validEvidence = {
|
|
171
|
+
command: 'npm test',
|
|
172
|
+
executionIdentity: 'pid-12345',
|
|
173
|
+
startTime: '2026-08-25T10:00:00Z',
|
|
174
|
+
endTime: '2026-08-25T10:00:05Z',
|
|
175
|
+
exitCode: 0,
|
|
176
|
+
stdout: 'PASS: 12 tests passed',
|
|
177
|
+
stderr: '',
|
|
178
|
+
timeoutStatus: 'COMPLETED',
|
|
179
|
+
testCounts: { passed: 12, failed: 0, skipped: 0 }
|
|
180
|
+
};
|
|
181
|
+
assert.strictEqual(validateVerificationEvidence(validEvidence).valid, true);
|
|
182
|
+
|
|
183
|
+
// 2. Reject non-zero exit code
|
|
184
|
+
const failingEvidence = { ...validEvidence, exitCode: 1 };
|
|
185
|
+
assert.strictEqual(validateVerificationEvidence(failingEvidence).valid, false);
|
|
186
|
+
|
|
187
|
+
// 3. Reject vague speculative statements without test counts
|
|
188
|
+
const vagueEvidence = {
|
|
189
|
+
command: 'npm test',
|
|
190
|
+
executionIdentity: 'pid-12345',
|
|
191
|
+
startTime: '2026-08-25T10:00:00Z',
|
|
192
|
+
endTime: '2026-08-25T10:00:05Z',
|
|
193
|
+
exitCode: 0,
|
|
194
|
+
stdout: 'command was launched in background',
|
|
195
|
+
stderr: '',
|
|
196
|
+
timeoutStatus: 'COMPLETED',
|
|
197
|
+
testCounts: { passed: 0, failed: 0 }
|
|
198
|
+
};
|
|
199
|
+
assert.strictEqual(validateVerificationEvidence(vagueEvidence).valid, false);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Test D, F, G: Judge Decision Matrix: VALID BLOCKER forces ITERATE; INVALID does not block delivery
|
|
203
|
+
test('D, F, G. Judge Decision Matrix: VALID BLOCKER forces ITERATE; INVALID does not block delivery', () => {
|
|
204
|
+
const goalContract = { objective: 'Test' };
|
|
205
|
+
const verificationEvidence = {
|
|
206
|
+
command: 'npm test',
|
|
207
|
+
executionIdentity: 'exec-1',
|
|
208
|
+
startTime: '2026-08-25T10:00:00Z',
|
|
209
|
+
endTime: '2026-08-25T10:00:02Z',
|
|
210
|
+
exitCode: 0,
|
|
211
|
+
stdout: '10 passed',
|
|
212
|
+
timeoutStatus: 'COMPLETED',
|
|
213
|
+
testCounts: { passed: 10, failed: 0 }
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// Scenario G: VALID + BLOCKER/HIGH forces ITERATE
|
|
217
|
+
const blockerLedger = {
|
|
218
|
+
findings: [
|
|
219
|
+
{
|
|
220
|
+
id: 'DA-1',
|
|
221
|
+
severity: 'BLOCKER',
|
|
222
|
+
validity: 'VALID',
|
|
223
|
+
disposition: 'STRONG',
|
|
224
|
+
location: 'src/auth.ts#L10',
|
|
225
|
+
failureScenario: 'Auth token unsigned',
|
|
226
|
+
evidence: 'JWT verify missing secret',
|
|
227
|
+
concreteAlternativeDiff: '+ jwt.verify(token, SECRET)'
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const verdictBlocker = computeJudgeVerdict({
|
|
233
|
+
goalContract,
|
|
234
|
+
verificationEvidence,
|
|
235
|
+
findingLedger: blockerLedger,
|
|
236
|
+
activeIteration: 1
|
|
237
|
+
});
|
|
238
|
+
assert.strictEqual(verdictBlocker.verdict, 'ITERATE');
|
|
239
|
+
assert.strictEqual(verdictBlocker.blockingFindings.length, 1);
|
|
240
|
+
|
|
241
|
+
// Scenario F: INVALID is DISMISSED and does NOT block delivery
|
|
242
|
+
const invalidLedger = {
|
|
243
|
+
findings: [
|
|
244
|
+
{
|
|
245
|
+
id: 'DA-2',
|
|
246
|
+
severity: 'BLOCKER',
|
|
247
|
+
validity: 'INVALID', // Hallucinated by reviewer
|
|
248
|
+
disposition: 'WEAK',
|
|
249
|
+
location: 'src/auth.ts#L20',
|
|
250
|
+
failureScenario: 'Reviewer claims function does not exist, but it exists in import',
|
|
251
|
+
evidence: 'Import checked and exists'
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const verdictDismissed = computeJudgeVerdict({
|
|
257
|
+
goalContract,
|
|
258
|
+
verificationEvidence,
|
|
259
|
+
findingLedger: invalidLedger,
|
|
260
|
+
activeIteration: 1
|
|
261
|
+
});
|
|
262
|
+
assert.strictEqual(verdictDismissed.verdict, 'PASS');
|
|
263
|
+
assert.strictEqual(verdictDismissed.dismissedFindings.length, 1);
|
|
264
|
+
|
|
265
|
+
// Scenario: VALID + LOW/ACCEPTABLE tradeoff passes and documents tradeoff
|
|
266
|
+
const tradeoffLedger = {
|
|
267
|
+
findings: [
|
|
268
|
+
{
|
|
269
|
+
id: 'DA-3',
|
|
270
|
+
severity: 'LOW',
|
|
271
|
+
validity: 'VALID',
|
|
272
|
+
disposition: 'ACCEPTABLE',
|
|
273
|
+
location: 'src/logger.ts#L5',
|
|
274
|
+
failureScenario: 'Log message could be more verbose',
|
|
275
|
+
evidence: 'Verbose flag not checked'
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const verdictTradeoff = computeJudgeVerdict({
|
|
281
|
+
goalContract,
|
|
282
|
+
verificationEvidence,
|
|
283
|
+
findingLedger: tradeoffLedger,
|
|
284
|
+
activeIteration: 1
|
|
285
|
+
});
|
|
286
|
+
assert.strictEqual(verdictTradeoff.verdict, 'PASS');
|
|
287
|
+
assert.strictEqual(verdictTradeoff.acceptableTradeoffs.length, 1);
|
|
288
|
+
});
|