@principles/core 1.128.0 → 1.130.0
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/quality-scorecard/__tests__/quality-scorecard.test.d.ts +2 -0
- package/dist/quality-scorecard/__tests__/quality-scorecard.test.d.ts.map +1 -0
- package/dist/quality-scorecard/__tests__/quality-scorecard.test.js +271 -0
- package/dist/quality-scorecard/__tests__/quality-scorecard.test.js.map +1 -0
- package/dist/quality-scorecard/index.d.ts +11 -0
- package/dist/quality-scorecard/index.d.ts.map +1 -0
- package/dist/quality-scorecard/index.js +4 -0
- package/dist/quality-scorecard/index.js.map +1 -0
- package/dist/quality-scorecard/report-generator.d.ts +11 -0
- package/dist/quality-scorecard/report-generator.d.ts.map +1 -0
- package/dist/quality-scorecard/report-generator.js +204 -0
- package/dist/quality-scorecard/report-generator.js.map +1 -0
- package/dist/quality-scorecard/types.d.ts +106 -0
- package/dist/quality-scorecard/types.d.ts.map +1 -0
- package/dist/quality-scorecard/types.js +51 -0
- package/dist/quality-scorecard/types.js.map +1 -0
- package/dist/quality-scorecard/validation.d.ts +73 -0
- package/dist/quality-scorecard/validation.d.ts.map +1 -0
- package/dist/quality-scorecard/validation.js +251 -0
- package/dist/quality-scorecard/validation.js.map +1 -0
- package/dist/runtime-v2/__tests__/internalization-consumer-product-path.test.d.ts +2 -0
- package/dist/runtime-v2/__tests__/internalization-consumer-product-path.test.d.ts.map +1 -0
- package/dist/runtime-v2/__tests__/internalization-consumer-product-path.test.js +222 -0
- package/dist/runtime-v2/__tests__/internalization-consumer-product-path.test.js.map +1 -0
- package/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +2 -0
- package/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/dist/runtime-v2/feature-flags/feature-flag-contract.js +1 -0
- package/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/dist/runtime-v2/feature-flags/plugin-surface-registry.d.ts.map +1 -1
- package/dist/runtime-v2/feature-flags/plugin-surface-registry.js +16 -0
- package/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -1
- package/dist/runtime-v2/index.d.ts +2 -0
- package/dist/runtime-v2/index.d.ts.map +1 -1
- package/dist/runtime-v2/index.js +2 -0
- package/dist/runtime-v2/index.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/internalization-consumer-decision.test.d.ts +2 -0
- package/dist/runtime-v2/internalization/__tests__/internalization-consumer-decision.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/internalization-consumer-decision.test.js +71 -0
- package/dist/runtime-v2/internalization/__tests__/internalization-consumer-decision.test.js.map +1 -0
- package/dist/runtime-v2/internalization/internalization-consumer-decision.d.ts +17 -0
- package/dist/runtime-v2/internalization/internalization-consumer-decision.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/internalization-consumer-decision.js +28 -0
- package/dist/runtime-v2/internalization/internalization-consumer-decision.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-scorecard.test.d.ts","sourceRoot":"","sources":["../../../src/quality-scorecard/__tests__/quality-scorecard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-361 Quality Scorecard — Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests pure logic from @principles/core only.
|
|
5
|
+
* I/O layer tests belong in pd-cli.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import { RUBRIC_DIMENSIONS, RUBRIC_LABELS, meetsMvpThreshold, escapeHtml, escapeMarkdownTable, validateLlmScoreResponse, validateAdjudicationResponse, validatePainRow, validateGateRow, validateCliOptions, needsAdjudication, determineFinalLabel, sanitize, } from '../index.js';
|
|
9
|
+
// ── Rubric Tests ───────────────────────────────────────────────────
|
|
10
|
+
describe('Rubric definitions', () => {
|
|
11
|
+
it('has exactly 7 dimensions (G1-G7)', () => {
|
|
12
|
+
expect(RUBRIC_DIMENSIONS).toHaveLength(7);
|
|
13
|
+
expect(RUBRIC_DIMENSIONS).toEqual(['G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7']);
|
|
14
|
+
});
|
|
15
|
+
it('every dimension has a label', () => {
|
|
16
|
+
for (const dim of RUBRIC_DIMENSIONS) {
|
|
17
|
+
expect(RUBRIC_LABELS[dim]).toBeTruthy();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('meetsMvpThreshold', () => {
|
|
22
|
+
const perfectScores = {
|
|
23
|
+
G1: 2, G2: 2, G3: 2, G4: 2, G5: 2, G6: 2, G7: 2,
|
|
24
|
+
};
|
|
25
|
+
it('passes with perfect scores', () => {
|
|
26
|
+
expect(meetsMvpThreshold(perfectScores)).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
it('fails when G1 < 2', () => {
|
|
29
|
+
const scores = { ...perfectScores, G1: 1 };
|
|
30
|
+
expect(meetsMvpThreshold(scores)).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
it('fails when G2 < 2', () => {
|
|
33
|
+
const scores = { ...perfectScores, G2: 1 };
|
|
34
|
+
expect(meetsMvpThreshold(scores)).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
it('fails when G5 < 2', () => {
|
|
37
|
+
const scores = { ...perfectScores, G5: 1 };
|
|
38
|
+
expect(meetsMvpThreshold(scores)).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it('fails when G3 = 0 (must be >= 1)', () => {
|
|
41
|
+
const scores = { ...perfectScores, G3: 0 };
|
|
42
|
+
expect(meetsMvpThreshold(scores)).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
it('fails when total < 10', () => {
|
|
45
|
+
const scores = {
|
|
46
|
+
G1: 2, G2: 2, G3: 1,
|
|
47
|
+
G4: 0, G5: 2, G6: 0, G7: 0,
|
|
48
|
+
};
|
|
49
|
+
expect(meetsMvpThreshold(scores)).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it('fails with all zeros', () => {
|
|
52
|
+
const zeros = Object.fromEntries(RUBRIC_DIMENSIONS.map(d => [d, 0]));
|
|
53
|
+
expect(meetsMvpThreshold(zeros)).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
// ── Escaping Tests ─────────────────────────────────────────────────
|
|
57
|
+
describe('escapeHtml', () => {
|
|
58
|
+
it('escapes < > & " \'', () => {
|
|
59
|
+
expect(escapeHtml('<script>alert("xss")</script>')).toBe('<script>alert("xss")</script>');
|
|
60
|
+
});
|
|
61
|
+
it('escapes ampersands', () => {
|
|
62
|
+
expect(escapeHtml('a & b')).toBe('a & b');
|
|
63
|
+
});
|
|
64
|
+
it('leaves safe text unchanged', () => {
|
|
65
|
+
expect(escapeHtml('hello world')).toBe('hello world');
|
|
66
|
+
});
|
|
67
|
+
it('handles injection in pain summary', () => {
|
|
68
|
+
const malicious = '<img src=x onerror=alert(1)>';
|
|
69
|
+
const escaped = escapeHtml(malicious);
|
|
70
|
+
expect(escaped).not.toContain('<');
|
|
71
|
+
expect(escaped).not.toContain('>');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('escapeMarkdownTable', () => {
|
|
75
|
+
it('escapes pipe characters', () => {
|
|
76
|
+
expect(escapeMarkdownTable('a | b | c')).toBe('a \\| b \\| c');
|
|
77
|
+
});
|
|
78
|
+
it('replaces newlines with spaces', () => {
|
|
79
|
+
expect(escapeMarkdownTable('line1\nline2\rline3')).toBe('line1 line2line3');
|
|
80
|
+
});
|
|
81
|
+
it('leaves safe text unchanged', () => {
|
|
82
|
+
expect(escapeMarkdownTable('hello world')).toBe('hello world');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
// ── Validation Tests ───────────────────────────────────────────────
|
|
86
|
+
describe('validateLlmScoreResponse', () => {
|
|
87
|
+
it('returns zeros for null input', () => {
|
|
88
|
+
const result = validateLlmScoreResponse(null);
|
|
89
|
+
expect(result.scores.G1).toBe(0);
|
|
90
|
+
expect(result.flags).toContain('invalid_llm_response');
|
|
91
|
+
});
|
|
92
|
+
it('parses valid response', () => {
|
|
93
|
+
const result = validateLlmScoreResponse({
|
|
94
|
+
scores: { G1: 2, G2: 1, G3: 0, G4: 2, G5: 2, G6: 1, G7: 0 },
|
|
95
|
+
rationales: { G1: 'Good evidence', G2: 'Partial' },
|
|
96
|
+
flags: ['over_abstraction'],
|
|
97
|
+
});
|
|
98
|
+
expect(result.scores.G1).toBe(2);
|
|
99
|
+
expect(result.scores.G2).toBe(1);
|
|
100
|
+
expect(result.flags).toEqual(['over_abstraction']);
|
|
101
|
+
expect(result.rationales.G2).toBe('Partial');
|
|
102
|
+
});
|
|
103
|
+
it('clamps invalid scores to 0', () => {
|
|
104
|
+
const result = validateLlmScoreResponse({
|
|
105
|
+
scores: { G1: 5, G2: -1, G3: 'bad' },
|
|
106
|
+
rationales: {},
|
|
107
|
+
flags: 'not-array',
|
|
108
|
+
});
|
|
109
|
+
expect(result.scores.G1).toBe(0);
|
|
110
|
+
expect(result.scores.G2).toBe(0);
|
|
111
|
+
expect(result.scores.G3).toBe(0);
|
|
112
|
+
expect(result.flags).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe('validateAdjudicationResponse', () => {
|
|
116
|
+
it('returns needs-review for null input', () => {
|
|
117
|
+
const result = validateAdjudicationResponse(null);
|
|
118
|
+
expect(result.verdict).toBe('needs-review');
|
|
119
|
+
});
|
|
120
|
+
it('parses valid response', () => {
|
|
121
|
+
const result = validateAdjudicationResponse({
|
|
122
|
+
scores: { G1: 2, G2: 2, G3: 2, G4: 2, G5: 2, G6: 2, G7: 2 },
|
|
123
|
+
rationale: 'All good',
|
|
124
|
+
verdict: 'pass',
|
|
125
|
+
});
|
|
126
|
+
expect(result.verdict).toBe('pass');
|
|
127
|
+
expect(result.rationale).toBe('All good');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('validatePainRow', () => {
|
|
131
|
+
it('returns null for null input', () => {
|
|
132
|
+
expect(validatePainRow(null)).toBeNull();
|
|
133
|
+
});
|
|
134
|
+
it('returns null for missing required fields', () => {
|
|
135
|
+
expect(validatePainRow({})).toBeNull();
|
|
136
|
+
});
|
|
137
|
+
it('parses valid row', () => {
|
|
138
|
+
const row = validatePainRow({ id: 1, session_id: 's1', source: 'manual', score: 80, reason: 'test', severity: 'severe', created_at: '2026-01-01' });
|
|
139
|
+
expect(row).not.toBeNull();
|
|
140
|
+
if (row) {
|
|
141
|
+
expect(row.id).toBe(1);
|
|
142
|
+
expect(row.score).toBe(80);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe('validateCliOptions', () => {
|
|
147
|
+
it('rejects invalid format', () => {
|
|
148
|
+
const { errors } = validateCliOptions({ format: 'xml', minPainScore: 50, limit: 0, localModelBaseUrl: 'http://x', output: 'out.md', localModelId: 'm' });
|
|
149
|
+
expect(errors.some(e => e.field === 'format')).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
it('rejects invalid minPainScore', () => {
|
|
152
|
+
const { errors } = validateCliOptions({ format: 'json', minPainScore: -1, limit: 0, localModelBaseUrl: 'http://x', output: 'out.md', localModelId: 'm' });
|
|
153
|
+
expect(errors.some(e => e.field === 'minPainScore')).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
it('rejects invalid URL', () => {
|
|
156
|
+
const { errors } = validateCliOptions({ format: 'json', minPainScore: 50, limit: 0, localModelBaseUrl: 'ftp://x', output: 'out.md', localModelId: 'm' });
|
|
157
|
+
expect(errors.some(e => e.field === 'localModelBaseUrl')).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
it('accepts valid options', () => {
|
|
160
|
+
const { options, errors } = validateCliOptions({
|
|
161
|
+
format: 'json', minPainScore: 50, limit: 10,
|
|
162
|
+
localModelBaseUrl: 'http://localhost:12341/v1', output: 'report.json', localModelId: 'gemma',
|
|
163
|
+
});
|
|
164
|
+
expect(errors).toHaveLength(0);
|
|
165
|
+
expect(options.format).toBe('json');
|
|
166
|
+
expect(options.limit).toBe(10);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
// ── Gate Row Validation Tests ──────────────────────────────────────
|
|
170
|
+
describe('validateGateRow', () => {
|
|
171
|
+
it('returns null for null input', () => {
|
|
172
|
+
expect(validateGateRow(null)).toBeNull();
|
|
173
|
+
});
|
|
174
|
+
it('returns null for missing session_id', () => {
|
|
175
|
+
expect(validateGateRow({ cnt: 5 })).toBeNull();
|
|
176
|
+
});
|
|
177
|
+
it('parses valid row', () => {
|
|
178
|
+
const row = validateGateRow({ session_id: 'sess-1', cnt: 3 });
|
|
179
|
+
expect(row).not.toBeNull();
|
|
180
|
+
if (row) {
|
|
181
|
+
expect(row.session_id).toBe('sess-1');
|
|
182
|
+
expect(row.cnt).toBe(3);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
it('defaults cnt to 0 for non-number', () => {
|
|
186
|
+
const row = validateGateRow({ session_id: 'sess-1', cnt: 'bad' });
|
|
187
|
+
expect(row).not.toBeNull();
|
|
188
|
+
if (row) {
|
|
189
|
+
expect(row.cnt).toBe(0);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
// ── Path Sanitization Tests ─────────────────────────────────────────
|
|
194
|
+
describe('sanitize — path redaction', () => {
|
|
195
|
+
it('redacts Windows paths', () => {
|
|
196
|
+
const result = sanitize('file at D:\\Code\\principles\\src\\index.ts');
|
|
197
|
+
expect(result).not.toContain('D:\\');
|
|
198
|
+
expect(result).toContain('<path>');
|
|
199
|
+
});
|
|
200
|
+
it('redacts POSIX /home/ paths', () => {
|
|
201
|
+
const result = sanitize('error in /home/user/project/src/index.ts');
|
|
202
|
+
expect(result).not.toContain('/home/');
|
|
203
|
+
expect(result).toContain('<path>');
|
|
204
|
+
});
|
|
205
|
+
it('redacts WSL /mnt/ paths', () => {
|
|
206
|
+
const result = sanitize('mounted at /mnt/c/Users/test/file.txt');
|
|
207
|
+
expect(result).not.toContain('/mnt/');
|
|
208
|
+
expect(result).toContain('<path>');
|
|
209
|
+
});
|
|
210
|
+
it('redacts /tmp/ paths', () => {
|
|
211
|
+
const result = sanitize('temp file /tmp/build-12345/output.log');
|
|
212
|
+
expect(result).not.toContain('/tmp/');
|
|
213
|
+
expect(result).toContain('<path>');
|
|
214
|
+
});
|
|
215
|
+
it('redacts JWT-like tokens', () => {
|
|
216
|
+
const result = sanitize('bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.abc');
|
|
217
|
+
expect(result).not.toContain('eyJ');
|
|
218
|
+
expect(result).toContain('<token-redacted>');
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
// ── Adjudication Decision Tests ────────────────────────────────────
|
|
222
|
+
function makeLocalEval(overrides = {}) {
|
|
223
|
+
return {
|
|
224
|
+
model: 'test-model',
|
|
225
|
+
dimensionScores: Object.fromEntries(RUBRIC_DIMENSIONS.map(d => [d, 2])),
|
|
226
|
+
dimensionRationales: Object.fromEntries(RUBRIC_DIMENSIONS.map(d => [d, ''])),
|
|
227
|
+
totalScore: overrides.totalScore ?? 14,
|
|
228
|
+
maxScore: 14,
|
|
229
|
+
mvpMet: overrides.mvpMet ?? true,
|
|
230
|
+
flags: overrides.flags ?? [],
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function makeEpisode(overrides = {}) {
|
|
234
|
+
return {
|
|
235
|
+
episodeId: 'EP-1', summary: 'Test episode', source: 'manual', score: 80,
|
|
236
|
+
severity: 'severe', createdAt: '2026-06-12T00:00:00Z',
|
|
237
|
+
evolutionTaskResolution: null, linkedPrinciples: [], gateBlockCount: 0,
|
|
238
|
+
...overrides,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
describe('needsAdjudication', () => {
|
|
242
|
+
it('returns critical when fabricated_evidence flag present', () => {
|
|
243
|
+
const decision = needsAdjudication(makeEpisode(), makeLocalEval({ flags: ['fabricated_evidence'] }));
|
|
244
|
+
expect(decision.shouldAdjudicate).toBe(true);
|
|
245
|
+
expect(decision.priority).toBe('critical');
|
|
246
|
+
});
|
|
247
|
+
it('returns high when MVP not met', () => {
|
|
248
|
+
const local = makeLocalEval({ mvpMet: false, totalScore: 5 });
|
|
249
|
+
local.dimensionScores = { G1: 0, G2: 2, G3: 0, G4: 0, G5: 0, G6: 1, G7: 0 };
|
|
250
|
+
const decision = needsAdjudication(makeEpisode(), local);
|
|
251
|
+
expect(decision.shouldAdjudicate).toBe(true);
|
|
252
|
+
expect(decision.priority).toBe('high');
|
|
253
|
+
});
|
|
254
|
+
it('returns low (no adjudication) when score >= 12 with MVP met', () => {
|
|
255
|
+
const decision = needsAdjudication(makeEpisode(), makeLocalEval({ totalScore: 13 }));
|
|
256
|
+
expect(decision.shouldAdjudicate).toBe(false);
|
|
257
|
+
expect(decision.priority).toBe('low');
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('determineFinalLabel', () => {
|
|
261
|
+
it('returns local-pass when high score and no adjudication', () => {
|
|
262
|
+
const label = determineFinalLabel(makeLocalEval({ totalScore: 13 }), null);
|
|
263
|
+
expect(label).toBe('local-pass');
|
|
264
|
+
});
|
|
265
|
+
it('returns local-fail when very low score and no adjudication', () => {
|
|
266
|
+
const local = makeLocalEval({ totalScore: 3, mvpMet: false });
|
|
267
|
+
local.dimensionScores = { G1: 0, G2: 0, G3: 0, G4: 1, G5: 0, G6: 1, G7: 1 };
|
|
268
|
+
expect(determineFinalLabel(local, null)).toBe('local-fail');
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
//# sourceMappingURL=quality-scorecard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-scorecard.test.js","sourceRoot":"","sources":["../../../src/quality-scorecard/__tests__/quality-scorecard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @principles/core/quality-scorecard — Pure logic barrel export
|
|
3
|
+
*
|
|
4
|
+
* ZERO I/O. Re-exports types, validation, and report generation.
|
|
5
|
+
*/
|
|
6
|
+
export type { RubricDimension, RubricScore, RubricEntry, PainEpisode, LocalEvaluation, AdjudicationStatus, StrongModelAdjudication, EpisodeEvaluation, QualityScorecardReport, ScorecardOptions, } from './types.js';
|
|
7
|
+
export { RUBRIC_DIMENSIONS, RUBRIC_LABELS, RUBRIC_DESCRIPTIONS, RUBRIC_PROMPTS, sumScores, meetsMvpThreshold, } from './types.js';
|
|
8
|
+
export { escapeHtml, escapeMarkdownTable, isValidRubricScore, parseRubricScore, validateDimensionScores, validateLlmScoreResponse, validateAdjudicationResponse, validatePainRow, validateEvolutionRow, validatePrincipleEventRow, validateGateRow, validateCliOptions, extractJsonFromLlmResponse, sanitize, truncate, needsAdjudication, determineFinalLabel, } from './validation.js';
|
|
9
|
+
export type { ValidatedLlmScores, ValidatedPainRow, ValidatedEvolutionRow, ValidatedPrincipleEventRow, ValidatedGateRow, ValidationError, AdjudicationDecision, } from './validation.js';
|
|
10
|
+
export { generateMarkdownReport, generateHtmlReport, generateJsonReport, } from './report-generator.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/quality-scorecard/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,EACV,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,eAAe,EACf,oBAAoB,EACpB,yBAAyB,EACzB,eAAe,EACf,kBAAkB,EAClB,0BAA0B,EAC1B,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { RUBRIC_DIMENSIONS, RUBRIC_LABELS, RUBRIC_DESCRIPTIONS, RUBRIC_PROMPTS, sumScores, meetsMvpThreshold, } from './types.js';
|
|
2
|
+
export { escapeHtml, escapeMarkdownTable, isValidRubricScore, parseRubricScore, validateDimensionScores, validateLlmScoreResponse, validateAdjudicationResponse, validatePainRow, validateEvolutionRow, validatePrincipleEventRow, validateGateRow, validateCliOptions, extractJsonFromLlmResponse, sanitize, truncate, needsAdjudication, determineFinalLabel, } from './validation.js';
|
|
3
|
+
export { generateMarkdownReport, generateHtmlReport, generateJsonReport, } from './report-generator.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/quality-scorecard/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,eAAe,EACf,oBAAoB,EACpB,yBAAyB,EACzB,eAAe,EACf,kBAAkB,EAClB,0BAA0B,EAC1B,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-361 Quality Scorecard — Report Generator
|
|
3
|
+
*
|
|
4
|
+
* PURE LOGIC — generates report strings. ZERO I/O.
|
|
5
|
+
* All external strings are escaped before rendering.
|
|
6
|
+
*/
|
|
7
|
+
import type { QualityScorecardReport } from './types.js';
|
|
8
|
+
export declare function generateMarkdownReport(report: QualityScorecardReport): string;
|
|
9
|
+
export declare function generateHtmlReport(report: QualityScorecardReport): string;
|
|
10
|
+
export declare function generateJsonReport(report: QualityScorecardReport): string;
|
|
11
|
+
//# sourceMappingURL=report-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-generator.d.ts","sourceRoot":"","sources":["../../src/quality-scorecard/report-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,sBAAsB,EAEvB,MAAM,YAAY,CAAC;AAoBpB,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAsF7E;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAiGzE;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAEzE"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-361 Quality Scorecard — Report Generator
|
|
3
|
+
*
|
|
4
|
+
* PURE LOGIC — generates report strings. ZERO I/O.
|
|
5
|
+
* All external strings are escaped before rendering.
|
|
6
|
+
*/
|
|
7
|
+
import { RUBRIC_LABELS, RUBRIC_DIMENSIONS as DIMS } from './types.js';
|
|
8
|
+
import { escapeHtml, escapeMarkdownTable } from './validation.js';
|
|
9
|
+
// ── Markdown Report ────────────────────────────────────────────────
|
|
10
|
+
function mdTable(eval_) {
|
|
11
|
+
const local = eval_.localEvaluation;
|
|
12
|
+
const strong = eval_.strongModelAdjudication;
|
|
13
|
+
const header = '| Dimension | Label | Local | Strong | Local Rationale |';
|
|
14
|
+
const sep = '|-----------|-------|-------|--------|-----------------|';
|
|
15
|
+
const rows = DIMS.map(d => {
|
|
16
|
+
const localScore = `${local.dimensionScores[d]}/2`;
|
|
17
|
+
const strongScore = strong?.confirmedScores ? `${strong.confirmedScores[d]}/2` : '-';
|
|
18
|
+
const rationale = escapeMarkdownTable(local.dimensionRationales[d]).substring(0, 60);
|
|
19
|
+
return `| ${d} | ${RUBRIC_LABELS[d]} | ${localScore} | ${strongScore} | ${rationale} |`;
|
|
20
|
+
});
|
|
21
|
+
return [header, sep, ...rows].join('\n');
|
|
22
|
+
}
|
|
23
|
+
export function generateMarkdownReport(report) {
|
|
24
|
+
const lines = [];
|
|
25
|
+
lines.push('# PD Quality Scorecard Report');
|
|
26
|
+
lines.push('');
|
|
27
|
+
lines.push(`Generated: ${report.generatedAt}`);
|
|
28
|
+
lines.push('');
|
|
29
|
+
// Data source
|
|
30
|
+
const ds = report.dataSource;
|
|
31
|
+
lines.push('## Data Source');
|
|
32
|
+
lines.push('');
|
|
33
|
+
lines.push(`- Pain Events: ${ds.painEventCount}`);
|
|
34
|
+
lines.push(`- Evolution Tasks: ${ds.evolutionTaskCount}`);
|
|
35
|
+
lines.push(`- Principle Events: ${ds.principleEventCount}`);
|
|
36
|
+
lines.push(`- Gate Blocks: ${ds.gateBlockCount}`);
|
|
37
|
+
lines.push(`- Date Range: ${ds.dateRange.from} — ${ds.dateRange.to}`);
|
|
38
|
+
lines.push('');
|
|
39
|
+
// Config
|
|
40
|
+
lines.push('## Evaluation Config');
|
|
41
|
+
lines.push('');
|
|
42
|
+
lines.push(`- Local Model: ${report.localEvaluatorConfig.model} (${report.localEvaluatorConfig.baseUrl})`);
|
|
43
|
+
lines.push(`- API Key: ${report.localEvaluatorConfig.apiKeyStatus}`);
|
|
44
|
+
lines.push(`- Strong Model: ${report.strongModelConfig.model ?? 'not configured'} (${report.strongModelConfig.status})`);
|
|
45
|
+
lines.push('');
|
|
46
|
+
// Summary
|
|
47
|
+
lines.push('## Summary');
|
|
48
|
+
lines.push('');
|
|
49
|
+
const s = report.summary;
|
|
50
|
+
lines.push(`- Total Episodes: ${s.totalEpisodes}`);
|
|
51
|
+
lines.push(`- Local Pass: ${s.localPassCount}`);
|
|
52
|
+
lines.push(`- Local Fail: ${s.localFailCount}`);
|
|
53
|
+
lines.push(`- Strong Model Reviewed: ${s.strongModelReviewedCount}`);
|
|
54
|
+
lines.push(`- Final Pass: ${s.finalPassCount}`);
|
|
55
|
+
lines.push(`- Final Fail: ${s.finalFailCount}`);
|
|
56
|
+
lines.push(`- Needs Review: ${s.needsReviewCount}`);
|
|
57
|
+
lines.push(`- Local-only evaluated (no strong model): ${s.localOnlyCount}`);
|
|
58
|
+
lines.push(`- Average Local Score: ${s.averageLocalScore.toFixed(1)}/14`);
|
|
59
|
+
lines.push(`- MVP Threshold Met: ${s.mvpThresholdMetCount}/${s.totalEpisodes}`);
|
|
60
|
+
lines.push('');
|
|
61
|
+
// Episode details
|
|
62
|
+
lines.push('## Episode Evaluations');
|
|
63
|
+
lines.push('');
|
|
64
|
+
for (const ev of report.evaluations) {
|
|
65
|
+
const summary = escapeMarkdownTable(ev.episode.summary);
|
|
66
|
+
const flags = ev.localEvaluation.flags.map(escapeMarkdownTable).join(', ');
|
|
67
|
+
const adjRationale = ev.strongModelAdjudication
|
|
68
|
+
? escapeMarkdownTable(ev.strongModelAdjudication.rationale ?? '')
|
|
69
|
+
: '';
|
|
70
|
+
lines.push(`### ${ev.episode.episodeId} — ${ev.finalLabel.toUpperCase()}`);
|
|
71
|
+
lines.push('');
|
|
72
|
+
lines.push(`- Source: ${escapeMarkdownTable(ev.episode.source)}`);
|
|
73
|
+
lines.push(`- Pain Score: ${ev.episode.score}`);
|
|
74
|
+
lines.push(`- Severity: ${escapeMarkdownTable(ev.episode.severity)}`);
|
|
75
|
+
lines.push(`- Summary: ${summary}`);
|
|
76
|
+
lines.push(`- Local Score: ${ev.localEvaluation.totalScore}/14 (MVP: ${ev.localEvaluation.mvpMet ? 'met' : 'not met'})`);
|
|
77
|
+
if (ev.localEvaluation.flags.length > 0) {
|
|
78
|
+
lines.push(`- Flags: ${flags}`);
|
|
79
|
+
}
|
|
80
|
+
if (ev.strongModelAdjudication) {
|
|
81
|
+
const adj = ev.strongModelAdjudication;
|
|
82
|
+
lines.push(`- Adjudication: ${adj.adjudicationStatus} (model: ${escapeMarkdownTable(adj.model)})`);
|
|
83
|
+
if (adjRationale)
|
|
84
|
+
lines.push(`- Adjudication Rationale: ${adjRationale}`);
|
|
85
|
+
if (adj.confirmedMvpMet !== null)
|
|
86
|
+
lines.push(`- Confirmed MVP: ${adj.confirmedMvpMet ? 'met' : 'not met'}`);
|
|
87
|
+
if (adj.nextAction)
|
|
88
|
+
lines.push(`- Next Action: ${escapeMarkdownTable(adj.nextAction)}`);
|
|
89
|
+
}
|
|
90
|
+
lines.push('');
|
|
91
|
+
lines.push(mdTable(ev));
|
|
92
|
+
lines.push('');
|
|
93
|
+
lines.push('---');
|
|
94
|
+
lines.push('');
|
|
95
|
+
}
|
|
96
|
+
// Known limitations
|
|
97
|
+
lines.push('## Known Limitations');
|
|
98
|
+
lines.push('');
|
|
99
|
+
for (const lim of report.knownLimitations) {
|
|
100
|
+
lines.push(`- ${escapeMarkdownTable(lim)}`);
|
|
101
|
+
}
|
|
102
|
+
lines.push('');
|
|
103
|
+
return lines.join('\n');
|
|
104
|
+
}
|
|
105
|
+
// ── HTML Report ────────────────────────────────────────────────────
|
|
106
|
+
export function generateHtmlReport(report) {
|
|
107
|
+
const s = report.summary;
|
|
108
|
+
const localPassPct = s.totalEpisodes > 0 ? ((s.localPassCount / s.totalEpisodes) * 100).toFixed(0) : '0';
|
|
109
|
+
const episodeCards = report.evaluations.map(ev => {
|
|
110
|
+
const statusClass = ev.finalLabel === 'pass' ? 'pass' : ev.finalLabel === 'fail' ? 'fail' : 'review';
|
|
111
|
+
const local = ev.localEvaluation;
|
|
112
|
+
const adj = ev.strongModelAdjudication;
|
|
113
|
+
const scoreBar = DIMS.map(d => {
|
|
114
|
+
const pct = (local.dimensionScores[d] / 2) * 100;
|
|
115
|
+
const color = local.dimensionScores[d] === 2 ? '#22c55e' : local.dimensionScores[d] === 1 ? '#eab308' : '#ef4444';
|
|
116
|
+
return `<div class="dim-score"><span class="dim-label">${d}</span><div class="bar-bg"><div class="bar-fill" style="width:${pct}%;background:${color}"></div></div><span class="dim-val">${local.dimensionScores[d]}/2</span></div>`;
|
|
117
|
+
}).join('');
|
|
118
|
+
const safeSummary = escapeHtml(ev.episode.summary);
|
|
119
|
+
const safeSource = escapeHtml(ev.episode.source);
|
|
120
|
+
const safeFlags = local.flags.map(escapeHtml).join(', ');
|
|
121
|
+
const safeAdjRationale = adj ? escapeHtml(adj.rationale ?? '') : '';
|
|
122
|
+
const safeNextAction = adj?.nextAction ? escapeHtml(adj.nextAction) : '';
|
|
123
|
+
return `
|
|
124
|
+
<div class="card ${statusClass}">
|
|
125
|
+
<div class="card-header">
|
|
126
|
+
<span class="ep-id">${escapeHtml(ev.episode.episodeId)}</span>
|
|
127
|
+
<span class="badge ${statusClass}">${escapeHtml(ev.finalLabel.toUpperCase())}</span>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="card-body">
|
|
130
|
+
<p><strong>Source:</strong> ${safeSource} | <strong>Score:</strong> ${ev.episode.score} | <strong>Local:</strong> ${local.totalScore}/14</p>
|
|
131
|
+
<p class="summary">${safeSummary}</p>
|
|
132
|
+
${local.flags.length > 0 ? `<p class="flags">⚠️ ${safeFlags}</p>` : ''}
|
|
133
|
+
${adj ? `<p class="adj"><strong>Adjudication:</strong> ${escapeHtml(adj.adjudicationStatus)} — ${safeAdjRationale.substring(0, 100)}</p>` : '<p class="adj"><strong>Adjudication:</strong> skipped (local-only assessment)</p>'}
|
|
134
|
+
${safeNextAction ? `<p class="adj"><strong>Next Action:</strong> ${safeNextAction}</p>` : ''}
|
|
135
|
+
<div class="score-bars">${scoreBar}</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>`;
|
|
138
|
+
}).join('\n');
|
|
139
|
+
return `<!DOCTYPE html>
|
|
140
|
+
<html lang="en">
|
|
141
|
+
<head>
|
|
142
|
+
<meta charset="UTF-8">
|
|
143
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
144
|
+
<title>PD Quality Scorecard</title>
|
|
145
|
+
<style>
|
|
146
|
+
body { font-family: system-ui, -apple-system, sans-serif; max-width: 900px; margin: 2rem auto; padding: 0 1rem; background: #0f172a; color: #e2e8f0; }
|
|
147
|
+
h1 { color: #f8fafc; }
|
|
148
|
+
h2 { color: #94a3b8; border-bottom: 1px solid #334155; padding-bottom: 0.5rem; }
|
|
149
|
+
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; margin: 1rem 0; }
|
|
150
|
+
.stat { background: #1e293b; padding: 1rem; border-radius: 8px; text-align: center; }
|
|
151
|
+
.stat-val { font-size: 2rem; font-weight: bold; color: #38bdf8; }
|
|
152
|
+
.stat-label { font-size: 0.8rem; color: #94a3b8; }
|
|
153
|
+
.card { background: #1e293b; border-radius: 8px; margin: 1rem 0; border-left: 4px solid #64748b; overflow: hidden; }
|
|
154
|
+
.card.pass { border-left-color: #22c55e; }
|
|
155
|
+
.card.fail { border-left-color: #ef4444; }
|
|
156
|
+
.card.review { border-left-color: #eab308; }
|
|
157
|
+
.card-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; background: #334155; }
|
|
158
|
+
.badge { padding: 0.2rem 0.6rem; border-radius: 4px; font-size: 0.75rem; font-weight: bold; }
|
|
159
|
+
.badge.pass { background: #22c55e33; color: #22c55e; }
|
|
160
|
+
.badge.fail { background: #ef444433; color: #ef4444; }
|
|
161
|
+
.badge.review { background: #eab30833; color: #eab308; }
|
|
162
|
+
.card-body { padding: 1rem; }
|
|
163
|
+
.summary { color: #cbd5e1; font-size: 0.9rem; }
|
|
164
|
+
.flags { color: #f97316; font-size: 0.85rem; }
|
|
165
|
+
.adj { color: #94a3b8; font-size: 0.85rem; }
|
|
166
|
+
.dim-score { display: flex; align-items: center; gap: 0.5rem; margin: 0.3rem 0; }
|
|
167
|
+
.dim-label { width: 2rem; font-size: 0.8rem; color: #94a3b8; }
|
|
168
|
+
.bar-bg { flex: 1; height: 8px; background: #334155; border-radius: 4px; }
|
|
169
|
+
.bar-fill { height: 100%; border-radius: 4px; transition: width 0.3s; }
|
|
170
|
+
.dim-val { width: 2.5rem; font-size: 0.8rem; color: #e2e8f0; }
|
|
171
|
+
.limitations { background: #1e293b; padding: 1rem; border-radius: 8px; }
|
|
172
|
+
.limitations li { color: #94a3b8; margin: 0.3rem 0; }
|
|
173
|
+
</style>
|
|
174
|
+
</head>
|
|
175
|
+
<body>
|
|
176
|
+
<h1>🧬 PD Quality Scorecard</h1>
|
|
177
|
+
<p>Generated: ${escapeHtml(report.generatedAt)}</p>
|
|
178
|
+
|
|
179
|
+
<h2>Summary</h2>
|
|
180
|
+
<div class="stats">
|
|
181
|
+
<div class="stat"><div class="stat-val">${s.totalEpisodes}</div><div class="stat-label">Episodes</div></div>
|
|
182
|
+
<div class="stat"><div class="stat-val">${localPassPct}%</div><div class="stat-label">Local Pass Rate</div></div>
|
|
183
|
+
<div class="stat"><div class="stat-val">${s.strongModelReviewedCount}</div><div class="stat-label">Strong Model Reviewed</div></div>
|
|
184
|
+
<div class="stat"><div class="stat-val">${s.averageLocalScore.toFixed(1)}</div><div class="stat-label">Avg Score /14</div></div>
|
|
185
|
+
<div class="stat"><div class="stat-val">${s.mvpThresholdMetCount}</div><div class="stat-label">MVP Met</div></div>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<p><strong>Config:</strong> Local: ${escapeHtml(report.localEvaluatorConfig.model)} | Strong: ${escapeHtml(report.strongModelConfig.model ?? 'skipped')}</p>
|
|
189
|
+
|
|
190
|
+
<h2>Episode Evaluations</h2>
|
|
191
|
+
${episodeCards}
|
|
192
|
+
|
|
193
|
+
<h2>Known Limitations</h2>
|
|
194
|
+
<ul class="limitations">
|
|
195
|
+
${report.knownLimitations.map(l => `<li>${escapeHtml(l)}</li>`).join('\n')}
|
|
196
|
+
</ul>
|
|
197
|
+
</body>
|
|
198
|
+
</html>`;
|
|
199
|
+
}
|
|
200
|
+
// ── JSON Report (pass-through) ─────────────────────────────────────
|
|
201
|
+
export function generateJsonReport(report) {
|
|
202
|
+
return JSON.stringify(report, null, 2);
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=report-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-generator.js","sourceRoot":"","sources":["../../src/quality-scorecard/report-generator.ts"],"names":[],"mappings":"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"}
|