@principles/core 1.112.4 → 1.112.5
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/dist/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.d.ts +2 -0
- package/dist/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.d.ts.map +1 -0
- package/dist/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.js +372 -0
- package/dist/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"golden-path-diagnostician-e2e.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-357: Golden-path E2E integration test for the diagnostician context pipeline.
|
|
3
|
+
*
|
|
4
|
+
* This test exercises the REAL production path end-to-end:
|
|
5
|
+
* PainSignalBridge.onPainDetected() → task creation with diagnosticJson
|
|
6
|
+
* SqliteContextAssembler.assemble() → DiagnosticianContextPayload
|
|
7
|
+
*
|
|
8
|
+
* It uses REAL SQLite databases (state.db via RuntimeStateManager) and a REAL
|
|
9
|
+
* SqliteContextAssembler.* Only the runner/intake/ledger (which are NOT the path
|
|
10
|
+
* under test) are mocked, and the TrajectoryTurnReader is mocked because it
|
|
11
|
+
* represents an external database (TrajectoryDB in the plugin layer).
|
|
12
|
+
*
|
|
13
|
+
* Assertions:
|
|
14
|
+
* 1. workspaceDir !== '<unknown>' && equals the input workspaceDir
|
|
15
|
+
* 2. conversationWindow.length > 0 (populated from trajectory fallback)
|
|
16
|
+
* 3. diagnosisTarget.evidence.length > 0
|
|
17
|
+
* 4. eventSummaries is NOT in the payload schema (PRI-352 removal confirmed)
|
|
18
|
+
*
|
|
19
|
+
* ── Reverse Validation (why this test catches PRI-349/350/352 regressions) ──
|
|
20
|
+
*
|
|
21
|
+
* | Regression | Why this test would FAIL on old code |
|
|
22
|
+
* |-------------------------------|-----------------------------------------------------|
|
|
23
|
+
* | PRI-349: workspaceDir unknown | diagnosticJson lacked workspaceDir → assembler |
|
|
24
|
+
* | | falls back to '<unknown>' → assertion 1 fires |
|
|
25
|
+
* | PRI-350: conversationWindow | No TrajectoryTurnReader in assembler → |
|
|
26
|
+
* | empty after historyQuery empty | conversationWindow = [] → assertion 2 fires |
|
|
27
|
+
* | PRI-352: eventSummaries | If eventSummaries reappears in schema, assertion 4 |
|
|
28
|
+
* | dangling field | catches it immediately |
|
|
29
|
+
*
|
|
30
|
+
* ERR entries considered:
|
|
31
|
+
* - ERR-002 (silent degradation): evidence/workspaceDir/conversationWindow
|
|
32
|
+
* silently falling back to empty/null/'<unknown>' is silent degradation.
|
|
33
|
+
* This test makes those failures LOUD (assertions fail).
|
|
34
|
+
* - ERR-009 (required fields silently skipped): Required payload fields
|
|
35
|
+
* (workspaceDir, conversationWindow, evidence) must be non-empty when
|
|
36
|
+
* input data is complete. This test asserts non-emptiness.
|
|
37
|
+
* - ERR-024/ERR-025 (production path wiring): This test exercises the
|
|
38
|
+
* REAL SqliteContextAssembler and REAL SqliteConnection, not mocks.
|
|
39
|
+
* - ERR-048 (write path disconnected from read path): This test runs
|
|
40
|
+
* onPainDetected (write) → assemble (read) in the same DB, proving
|
|
41
|
+
* the write path correctly populates data that the read path consumes.
|
|
42
|
+
*/
|
|
43
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
44
|
+
import * as fs from 'fs';
|
|
45
|
+
import * as path from 'path';
|
|
46
|
+
import * as os from 'os';
|
|
47
|
+
import { Value } from '@sinclair/typebox/value';
|
|
48
|
+
import { RuntimeStateManager } from '../store/runtime-state-manager.js';
|
|
49
|
+
import { SqliteHistoryQuery } from '../store/history/sqlite-history-query.js';
|
|
50
|
+
import { SqliteContextAssembler } from '../store/context/sqlite-context-assembler.js';
|
|
51
|
+
import { PainSignalBridge } from '../pain-signal-bridge.js';
|
|
52
|
+
import { DiagnosticianContextPayloadSchema } from '../context-payload.js';
|
|
53
|
+
// ── Constants ────────────────────────────────────────────────────────────
|
|
54
|
+
const GOLDEN_WORKSPACE_DIR = '/home/user/projects/my-golden-app';
|
|
55
|
+
const GOLDEN_PAIN_ID = 'pain-golden-e2e-001';
|
|
56
|
+
const GOLDEN_SESSION_ID = 'sess-golden-e2e';
|
|
57
|
+
const GOLDEN_TASK_ID = `diagnosis_${GOLDEN_PAIN_ID}`;
|
|
58
|
+
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
59
|
+
function notesInclude(notes, substring) {
|
|
60
|
+
return notes !== undefined && notes.some((n) => n.includes(substring));
|
|
61
|
+
}
|
|
62
|
+
/** Create a mock TrajectoryTurnReader with pre-seeded turns for a session. */
|
|
63
|
+
function createMockTrajectoryTurnReader(userTurns, assistantTurns) {
|
|
64
|
+
return {
|
|
65
|
+
listUserTurnsForSession: vi.fn((sessionId) => userTurns.get(sessionId) ?? []),
|
|
66
|
+
listAssistantTurns: vi.fn((sessionId) => assistantTurns.get(sessionId) ?? []),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Create a mock DiagnosticianRunner that returns a basic "succeeded" result. */
|
|
70
|
+
function createMockRunner() {
|
|
71
|
+
return {
|
|
72
|
+
run: vi.fn().mockResolvedValue({
|
|
73
|
+
status: 'succeeded',
|
|
74
|
+
taskId: GOLDEN_TASK_ID,
|
|
75
|
+
attemptCount: 1,
|
|
76
|
+
output: {
|
|
77
|
+
valid: true,
|
|
78
|
+
diagnosisId: 'diag-golden-e2e',
|
|
79
|
+
summary: 'Golden path test diagnosis',
|
|
80
|
+
rootCause: 'Test root cause',
|
|
81
|
+
violatedPrinciples: [],
|
|
82
|
+
evidence: [{ sourceRef: 'src-golden', note: 'Evidence from golden test' }],
|
|
83
|
+
recommendations: [{ kind: 'principle', description: 'Add defensive check for null context' }],
|
|
84
|
+
confidence: 0.9,
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Create a mock CandidateIntakeService. */
|
|
90
|
+
function createMockIntakeService() {
|
|
91
|
+
return {
|
|
92
|
+
intake: vi.fn().mockResolvedValue({ id: 'ledger-golden-1' }),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** Create a mock LedgerAdapter. */
|
|
96
|
+
function createMockLedgerAdapter() {
|
|
97
|
+
return {
|
|
98
|
+
register: vi.fn(),
|
|
99
|
+
existsForCandidate: vi.fn().mockReturnValue({
|
|
100
|
+
id: 'ledger-golden-1',
|
|
101
|
+
status: 'probation',
|
|
102
|
+
createdAt: new Date().toISOString(),
|
|
103
|
+
text: 'Golden path test principle',
|
|
104
|
+
sourceRef: 'candidate://c-golden-1',
|
|
105
|
+
title: 'Golden Test Principle',
|
|
106
|
+
evaluability: 'weak_heuristic',
|
|
107
|
+
}),
|
|
108
|
+
getEntries: vi.fn(),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async function createGoldenFixture(userTurns, assistantTurns) {
|
|
112
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-golden-e2e-'));
|
|
113
|
+
const stateManager = new RuntimeStateManager({ workspaceDir: tmpDir });
|
|
114
|
+
await stateManager.initialize();
|
|
115
|
+
const trajectoryTurnReader = createMockTrajectoryTurnReader(userTurns, assistantTurns);
|
|
116
|
+
const runner = createMockRunner();
|
|
117
|
+
const intakeService = createMockIntakeService();
|
|
118
|
+
const ledgerAdapter = createMockLedgerAdapter();
|
|
119
|
+
// Create SqliteContextAssembler with REAL stores from the same DB
|
|
120
|
+
const assembler = new SqliteContextAssembler(stateManager.taskStore, new SqliteHistoryQuery(stateManager.connection), stateManager.runStore, { trajectoryTurnReader });
|
|
121
|
+
// Create PainSignalBridge with real stateManager but mocked runner/intake/ledger
|
|
122
|
+
const bridge = new PainSignalBridge({
|
|
123
|
+
stateManager,
|
|
124
|
+
runner,
|
|
125
|
+
intakeService,
|
|
126
|
+
ledgerAdapter,
|
|
127
|
+
workspaceDir: GOLDEN_WORKSPACE_DIR,
|
|
128
|
+
autoIntakeEnabled: true,
|
|
129
|
+
});
|
|
130
|
+
return { tmpDir, stateManager, assembler, bridge, trajectoryTurnReader, runner };
|
|
131
|
+
}
|
|
132
|
+
function cleanupGoldenFixture(fixture) {
|
|
133
|
+
fixture.stateManager.close();
|
|
134
|
+
fs.rmSync(fixture.tmpDir, { recursive: true, force: true });
|
|
135
|
+
}
|
|
136
|
+
// ── Tests ────────────────────────────────────────────────────────────────
|
|
137
|
+
describe('PRI-357: Golden-path diagnostician E2E (real SQLite, no mock of assembly path)', () => {
|
|
138
|
+
it('G1: onPainDetected → assemble produces payload with non-empty workspaceDir, conversationWindow, evidence, and no eventSummaries in schema', async () => {
|
|
139
|
+
// ── Seed trajectory turns ──
|
|
140
|
+
const userTurns = new Map([
|
|
141
|
+
[GOLDEN_SESSION_ID, [
|
|
142
|
+
{ id: 1, turnIndex: 0, rawExcerpt: 'Help me fix the login bug in auth.ts', correctionDetected: false, correctionCue: null, createdAt: '2026-06-10T10:00:00.000Z' },
|
|
143
|
+
{ id: 3, turnIndex: 2, rawExcerpt: 'No, the login is still broken after your fix', correctionDetected: true, correctionCue: 'rejected', createdAt: '2026-06-10T10:04:00.000Z' },
|
|
144
|
+
]],
|
|
145
|
+
]);
|
|
146
|
+
const assistantTurns = new Map([
|
|
147
|
+
[GOLDEN_SESSION_ID, [
|
|
148
|
+
{ id: 2, sessionId: GOLDEN_SESSION_ID, runId: 'run-golden-1', provider: 'anthropic', model: 'claude-sonnet-4-20250514', sanitizedText: 'I found a null reference in the auth validation. Let me fix it.', createdAt: '2026-06-10T10:02:00.000Z' },
|
|
149
|
+
{ id: 4, sessionId: GOLDEN_SESSION_ID, runId: 'run-golden-2', provider: 'anthropic', model: 'claude-sonnet-4-20250514', sanitizedText: 'You are right. The null check was in the wrong place. Moving it to the controller layer.', createdAt: '2026-06-10T10:06:00.000Z' },
|
|
150
|
+
]],
|
|
151
|
+
]);
|
|
152
|
+
const f = await createGoldenFixture(userTurns, assistantTurns);
|
|
153
|
+
try {
|
|
154
|
+
// ── Step 1: onPainDetected ──
|
|
155
|
+
const bridgeResult = await f.bridge.onPainDetected({
|
|
156
|
+
painId: GOLDEN_PAIN_ID,
|
|
157
|
+
painType: 'tool_failure',
|
|
158
|
+
source: 'pain',
|
|
159
|
+
reason: 'Login auth.ts bug: null reference in validation layer',
|
|
160
|
+
score: 85,
|
|
161
|
+
sessionId: GOLDEN_SESSION_ID,
|
|
162
|
+
evidence: [
|
|
163
|
+
{ sourceRef: 'tool_call:Edit:auth.ts', note: 'User reported null reference in auth validation; assistant fix was misplaced' },
|
|
164
|
+
{ sourceRef: 'user_correction:turn_3', note: 'User correction: login still broken after fix attempt' },
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
// Verify bridge produced a result (task was created and runner called)
|
|
168
|
+
expect(bridgeResult.painId).toBe(GOLDEN_PAIN_ID);
|
|
169
|
+
expect(bridgeResult.taskId).toBe(GOLDEN_TASK_ID);
|
|
170
|
+
// Verify the task exists in the real DB
|
|
171
|
+
const taskInDb = await f.stateManager.getTask(GOLDEN_TASK_ID);
|
|
172
|
+
expect(taskInDb).not.toBeNull();
|
|
173
|
+
expect(taskInDb?.taskKind).toBe('diagnostician');
|
|
174
|
+
expect(taskInDb?.diagnosticJson).toBeDefined();
|
|
175
|
+
// ── Step 2: assemble ──
|
|
176
|
+
const payload = await f.assembler.assemble(GOLDEN_TASK_ID);
|
|
177
|
+
// ── Assertion 1: workspaceDir ──
|
|
178
|
+
expect(payload.workspaceDir).not.toBe('<unknown>');
|
|
179
|
+
expect(payload.workspaceDir).toBe(GOLDEN_WORKSPACE_DIR);
|
|
180
|
+
// ── Assertion 2: conversationWindow ──
|
|
181
|
+
expect(payload.conversationWindow.length).toBeGreaterThan(0);
|
|
182
|
+
// Should contain at least the 4 turns (2 user + 2 assistant) from trajectory
|
|
183
|
+
expect(payload.conversationWindow.length).toBeGreaterThanOrEqual(4);
|
|
184
|
+
// Entries must be sorted by timestamp ascending
|
|
185
|
+
expect(payload.conversationWindow[0]?.role).toBe('user');
|
|
186
|
+
expect(payload.conversationWindow[0]?.ts).toBe('2026-06-10T10:00:00.000Z');
|
|
187
|
+
// User turn text from rawExcerpt
|
|
188
|
+
expect(payload.conversationWindow[0]?.text).toContain('login bug');
|
|
189
|
+
// Assistant text is sanitized
|
|
190
|
+
expect(payload.conversationWindow[1]?.role).toBe('assistant');
|
|
191
|
+
expect(payload.conversationWindow[1]?.text).toContain('null reference');
|
|
192
|
+
// ── Assertion 3: evidence ──
|
|
193
|
+
const { evidence } = payload.diagnosisTarget;
|
|
194
|
+
expect(evidence).toBeDefined();
|
|
195
|
+
if (!evidence)
|
|
196
|
+
throw new Error('evidence must be defined');
|
|
197
|
+
expect(evidence.length).toBeGreaterThan(0);
|
|
198
|
+
// Evidence must contain the entries we seeded
|
|
199
|
+
const evidenceSourceRefs = evidence.map(e => e.sourceRef);
|
|
200
|
+
expect(evidenceSourceRefs).toContain('tool_call:Edit:auth.ts');
|
|
201
|
+
expect(evidenceSourceRefs).toContain('user_correction:turn_3');
|
|
202
|
+
// ── Assertion 4: eventSummaries resolution (PRI-352) ──
|
|
203
|
+
// The DiagnosticianContextPayloadSchema must NOT contain eventSummaries
|
|
204
|
+
const schemaKeys = Object.keys(DiagnosticianContextPayloadSchema.properties);
|
|
205
|
+
expect(schemaKeys).not.toContain('eventSummaries');
|
|
206
|
+
// The assembled payload must not have an eventSummaries property
|
|
207
|
+
expect(Object.prototype.hasOwnProperty.call(payload, 'eventSummaries')).toBe(false);
|
|
208
|
+
// The payload must validate against the schema
|
|
209
|
+
expect(Value.Check(DiagnosticianContextPayloadSchema, payload)).toBe(true);
|
|
210
|
+
// ── Additional quality checks ──
|
|
211
|
+
// diagnosisTarget must have reasonSummary, source, severity
|
|
212
|
+
expect(payload.diagnosisTarget.reasonSummary).toBeTruthy();
|
|
213
|
+
expect(payload.diagnosisTarget.source).toBe('pain');
|
|
214
|
+
expect(payload.diagnosisTarget.severity).toBe('severe');
|
|
215
|
+
// provenance must be set (openclaw_context_bound since we have sessionId)
|
|
216
|
+
expect(payload.diagnosisTarget.provenance).toBe('openclaw_context_bound');
|
|
217
|
+
// sessionIdHint must propagate from diagnosticJson
|
|
218
|
+
expect(payload.diagnosisTarget.sessionIdHint).toBe(GOLDEN_SESSION_ID);
|
|
219
|
+
}
|
|
220
|
+
finally {
|
|
221
|
+
cleanupGoldenFixture(f);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
it('G2: payload validates against DiagnosticianContextPayloadSchema after full assembly', async () => {
|
|
225
|
+
// G2 ensures the assembled payload passes TypeBox schema validation.
|
|
226
|
+
// This catches future schema changes that break the DiagnosticianContextPayload contract.
|
|
227
|
+
const userTurns = new Map([
|
|
228
|
+
[GOLDEN_SESSION_ID, [
|
|
229
|
+
{ id: 10, turnIndex: 0, rawExcerpt: 'Simple query', correctionDetected: false, correctionCue: null, createdAt: '2026-06-10T09:00:00.000Z' },
|
|
230
|
+
]],
|
|
231
|
+
]);
|
|
232
|
+
const assistantTurns = new Map([
|
|
233
|
+
[GOLDEN_SESSION_ID, [
|
|
234
|
+
{ id: 11, sessionId: GOLDEN_SESSION_ID, runId: 'run-schema', provider: 'openai', model: 'gpt-4', sanitizedText: 'Simple response', createdAt: '2026-06-10T09:01:00.000Z' },
|
|
235
|
+
]],
|
|
236
|
+
]);
|
|
237
|
+
const f = await createGoldenFixture(userTurns, assistantTurns);
|
|
238
|
+
try {
|
|
239
|
+
await f.bridge.onPainDetected({
|
|
240
|
+
painId: GOLDEN_PAIN_ID,
|
|
241
|
+
painType: 'user_frustration',
|
|
242
|
+
source: 'write',
|
|
243
|
+
reason: 'Schema validation test pain',
|
|
244
|
+
sessionId: GOLDEN_SESSION_ID,
|
|
245
|
+
evidence: [{ sourceRef: 'schema-test', note: 'Schema validation' }],
|
|
246
|
+
});
|
|
247
|
+
const payload = await f.assembler.assemble(GOLDEN_TASK_ID);
|
|
248
|
+
// Schema already checked inside assemble(), double-check explicitly
|
|
249
|
+
expect(Value.Check(DiagnosticianContextPayloadSchema, payload)).toBe(true);
|
|
250
|
+
// Verify conversationWindow from trajectory fallback works
|
|
251
|
+
expect(payload.conversationWindow.length).toBeGreaterThan(0);
|
|
252
|
+
expect(payload.workspaceDir).not.toBe('<unknown>');
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
cleanupGoldenFixture(f);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
it('G3: workspaceDir=<unknown> when bridge has no workspaceDir (degradation is observable)', async () => {
|
|
259
|
+
// G3: When workspaceDir is NOT provided to the bridge, the payload
|
|
260
|
+
// should fall back to '<unknown>' — but this must be OBSERVABLE
|
|
261
|
+
// (ERR-002: no silent degradation). The test verifies the degradation
|
|
262
|
+
// is explicit.
|
|
263
|
+
const userTurns = new Map([
|
|
264
|
+
[GOLDEN_SESSION_ID, [
|
|
265
|
+
{ id: 20, turnIndex: 0, rawExcerpt: 'Test without workspace', correctionDetected: false, correctionCue: null, createdAt: '2026-06-10T08:00:00.000Z' },
|
|
266
|
+
]],
|
|
267
|
+
]);
|
|
268
|
+
const assistantTurns = new Map([
|
|
269
|
+
[GOLDEN_SESSION_ID, [
|
|
270
|
+
{ id: 21, sessionId: GOLDEN_SESSION_ID, runId: 'run-no-ws', provider: 'openai', model: 'gpt-4', sanitizedText: 'Response without workspace', createdAt: '2026-06-10T08:01:00.000Z' },
|
|
271
|
+
]],
|
|
272
|
+
]);
|
|
273
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-golden-e2e-no-ws-'));
|
|
274
|
+
const stateManager = new RuntimeStateManager({ workspaceDir: tmpDir });
|
|
275
|
+
await stateManager.initialize();
|
|
276
|
+
const trajectoryTurnReader = createMockTrajectoryTurnReader(userTurns, assistantTurns);
|
|
277
|
+
const runner = createMockRunner();
|
|
278
|
+
const intakeService = createMockIntakeService();
|
|
279
|
+
const ledgerAdapter = createMockLedgerAdapter();
|
|
280
|
+
const assembler = new SqliteContextAssembler(stateManager.taskStore, new SqliteHistoryQuery(stateManager.connection), stateManager.runStore, { trajectoryTurnReader });
|
|
281
|
+
// Bridge WITHOUT workspaceDir
|
|
282
|
+
const bridge = new PainSignalBridge({
|
|
283
|
+
stateManager,
|
|
284
|
+
runner,
|
|
285
|
+
intakeService,
|
|
286
|
+
ledgerAdapter,
|
|
287
|
+
autoIntakeEnabled: true,
|
|
288
|
+
// workspaceDir intentionally omitted
|
|
289
|
+
});
|
|
290
|
+
try {
|
|
291
|
+
await bridge.onPainDetected({
|
|
292
|
+
painId: 'pain-no-ws-g3',
|
|
293
|
+
painType: 'tool_failure',
|
|
294
|
+
source: 'pain',
|
|
295
|
+
reason: 'No workspaceDir test',
|
|
296
|
+
sessionId: GOLDEN_SESSION_ID,
|
|
297
|
+
evidence: [{ sourceRef: 'g3-test', note: 'G3 evidence' }],
|
|
298
|
+
});
|
|
299
|
+
const payload = await assembler.assemble('diagnosis_pain-no-ws-g3');
|
|
300
|
+
// workspaceDir is '<unknown>' (no workspaceDir in diagnosticJson + no record-level workspaceDir)
|
|
301
|
+
expect(payload.workspaceDir).toBe('<unknown>');
|
|
302
|
+
// conversationWindow should still be empty because trajectory fallback
|
|
303
|
+
// requires workspaceDir !== '<unknown>' (PRI-350 guard)
|
|
304
|
+
// This is EXPECTED degradation: when workspaceDir is unknown, we cannot
|
|
305
|
+
// safely access trajectory DB.
|
|
306
|
+
expect(payload.conversationWindow).toEqual([]);
|
|
307
|
+
expect(notesInclude(payload.ambiguityNotes, 'No conversation history')).toBe(true);
|
|
308
|
+
// evidence IS present (from diagnosticJson)
|
|
309
|
+
const g3Evidence = payload.diagnosisTarget.evidence;
|
|
310
|
+
expect(g3Evidence).toBeDefined();
|
|
311
|
+
if (!g3Evidence)
|
|
312
|
+
throw new Error('g3 evidence must be defined');
|
|
313
|
+
expect(g3Evidence.length).toBeGreaterThan(0);
|
|
314
|
+
}
|
|
315
|
+
finally {
|
|
316
|
+
stateManager.close();
|
|
317
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
it('G4: evidence from diagnosticJson survives the full onPainDetected → assemble round-trip', async () => {
|
|
321
|
+
// G4 specifically validates that evidence written by buildDiagnosticJson
|
|
322
|
+
// is correctly read by SqliteContextAssembler.reconstructDiagnosticianRecord.
|
|
323
|
+
const userTurns = new Map([
|
|
324
|
+
[GOLDEN_SESSION_ID, [
|
|
325
|
+
{ id: 30, turnIndex: 0, rawExcerpt: 'Evidence round-trip test', correctionDetected: false, correctionCue: null, createdAt: '2026-06-10T07:00:00.000Z' },
|
|
326
|
+
]],
|
|
327
|
+
]);
|
|
328
|
+
const assistantTurns = new Map([
|
|
329
|
+
[GOLDEN_SESSION_ID, [
|
|
330
|
+
{ id: 31, sessionId: GOLDEN_SESSION_ID, runId: 'run-evidence', provider: 'openai', model: 'gpt-4', sanitizedText: 'Evidence response', createdAt: '2026-06-10T07:01:00.000Z' },
|
|
331
|
+
]],
|
|
332
|
+
]);
|
|
333
|
+
const f = await createGoldenFixture(userTurns, assistantTurns);
|
|
334
|
+
try {
|
|
335
|
+
const customEvidence = [
|
|
336
|
+
{ sourceRef: 'trace:file:src/controller.ts:42', note: 'Null check was missing on line 42 — this was the root cause of the login failure' },
|
|
337
|
+
{ sourceRef: 'user_message:turn_5', note: 'User said: the fix you applied to auth.ts actually broke the registration flow too' },
|
|
338
|
+
{ sourceRef: 'tool_call:Write:controller.ts', note: 'Write tool was used to patch controller.ts with the corrected null check' },
|
|
339
|
+
];
|
|
340
|
+
await f.bridge.onPainDetected({
|
|
341
|
+
painId: GOLDEN_PAIN_ID,
|
|
342
|
+
painType: 'tool_failure',
|
|
343
|
+
source: 'pain',
|
|
344
|
+
reason: 'Evidence round-trip validation',
|
|
345
|
+
sessionId: GOLDEN_SESSION_ID,
|
|
346
|
+
evidence: customEvidence,
|
|
347
|
+
});
|
|
348
|
+
const payload = await f.assembler.assemble(GOLDEN_TASK_ID);
|
|
349
|
+
// Evidence must be exactly what we put in (round-trip integrity)
|
|
350
|
+
const roundTripEvidence = payload.diagnosisTarget.evidence;
|
|
351
|
+
expect(roundTripEvidence).toBeDefined();
|
|
352
|
+
if (!roundTripEvidence)
|
|
353
|
+
throw new Error('round-trip evidence must be defined');
|
|
354
|
+
expect(roundTripEvidence.length).toBe(customEvidence.length);
|
|
355
|
+
// Each evidence entry must be preserved
|
|
356
|
+
for (let i = 0; i < customEvidence.length; i++) {
|
|
357
|
+
const expected = customEvidence[i];
|
|
358
|
+
if (!expected)
|
|
359
|
+
throw new Error('custom evidence entry missing');
|
|
360
|
+
expect(roundTripEvidence[i]?.sourceRef).toBe(expected.sourceRef);
|
|
361
|
+
expect(roundTripEvidence[i]?.note).toBe(expected.note);
|
|
362
|
+
}
|
|
363
|
+
// Other fields still work
|
|
364
|
+
expect(payload.workspaceDir).toBe(GOLDEN_WORKSPACE_DIR);
|
|
365
|
+
expect(payload.conversationWindow.length).toBeGreaterThan(0);
|
|
366
|
+
}
|
|
367
|
+
finally {
|
|
368
|
+
cleanupGoldenFixture(f);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
//# sourceMappingURL=golden-path-diagnostician-e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"golden-path-diagnostician-e2e.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.ts"],"names":[],"mappings":"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"}
|