@dzhechkov/harness-core 0.8.36 → 0.8.37
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/.dz-manifest.json +195 -75
- package/README.md +235 -8
- package/dist/agentdb-index.d.ts +87 -7
- package/dist/agentdb-index.d.ts.map +1 -1
- package/dist/agentdb-index.js +416 -57
- package/dist/agentdb-index.js.map +1 -1
- package/dist/apply-leg.d.ts +19 -1
- package/dist/apply-leg.d.ts.map +1 -1
- package/dist/apply-leg.js +187 -36
- package/dist/apply-leg.js.map +1 -1
- package/dist/codex-rollouts.d.ts +118 -0
- package/dist/codex-rollouts.d.ts.map +1 -0
- package/dist/codex-rollouts.js +297 -0
- package/dist/codex-rollouts.js.map +1 -0
- package/dist/cost-ledger.d.ts +56 -4
- package/dist/cost-ledger.d.ts.map +1 -1
- package/dist/cost-ledger.js +176 -20
- package/dist/cost-ledger.js.map +1 -1
- package/dist/cross-family-control.d.ts +345 -0
- package/dist/cross-family-control.d.ts.map +1 -0
- package/dist/cross-family-control.js +802 -0
- package/dist/cross-family-control.js.map +1 -0
- package/dist/debt-ratchet.d.ts +53 -0
- package/dist/debt-ratchet.d.ts.map +1 -0
- package/dist/debt-ratchet.js +107 -0
- package/dist/debt-ratchet.js.map +1 -0
- package/dist/embedding-config.d.ts +42 -0
- package/dist/embedding-config.d.ts.map +1 -1
- package/dist/embedding-config.js +106 -10
- package/dist/embedding-config.js.map +1 -1
- package/dist/feature-adr-checkpoints.d.ts +6 -0
- package/dist/feature-adr-checkpoints.d.ts.map +1 -1
- package/dist/feature-adr-checkpoints.js +29 -0
- package/dist/feature-adr-checkpoints.js.map +1 -1
- package/dist/feature-adr-decision-recall.d.ts +2 -2
- package/dist/feature-adr-decision-recall.d.ts.map +1 -1
- package/dist/feature-adr-decision-recall.js +5 -3
- package/dist/feature-adr-decision-recall.js.map +1 -1
- package/dist/feature-adr-envelope.d.ts +96 -0
- package/dist/feature-adr-envelope.d.ts.map +1 -0
- package/dist/feature-adr-envelope.js +183 -0
- package/dist/feature-adr-envelope.js.map +1 -0
- package/dist/feature-adr-routing.d.ts +64 -0
- package/dist/feature-adr-routing.d.ts.map +1 -1
- package/dist/feature-adr-routing.js +122 -2
- package/dist/feature-adr-routing.js.map +1 -1
- package/dist/feature-adr-stage-canon.d.ts +79 -0
- package/dist/feature-adr-stage-canon.d.ts.map +1 -0
- package/dist/feature-adr-stage-canon.js +117 -0
- package/dist/feature-adr-stage-canon.js.map +1 -0
- package/dist/index.d.ts +19 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/loop-blobs.generated.js +4 -4
- package/dist/loop-blobs.generated.js.map +1 -1
- package/dist/mutation-gate.d.ts +51 -0
- package/dist/mutation-gate.d.ts.map +1 -1
- package/dist/mutation-gate.js +295 -0
- package/dist/mutation-gate.js.map +1 -1
- package/dist/qe-bridge.d.ts.map +1 -1
- package/dist/qe-bridge.js +4 -2
- package/dist/qe-bridge.js.map +1 -1
- package/dist/qe-findings.d.ts +107 -0
- package/dist/qe-findings.d.ts.map +1 -0
- package/dist/qe-findings.js +417 -0
- package/dist/qe-findings.js.map +1 -0
- package/dist/recap.d.ts +1 -1
- package/dist/recap.d.ts.map +1 -1
- package/dist/recap.js +4 -2
- package/dist/recap.js.map +1 -1
- package/dist/round.d.ts +74 -1
- package/dist/round.d.ts.map +1 -1
- package/dist/round.js +112 -4
- package/dist/round.js.map +1 -1
- package/dist/run-records.d.ts +60 -0
- package/dist/run-records.d.ts.map +1 -1
- package/dist/run-records.js +244 -2
- package/dist/run-records.js.map +1 -1
- package/dist/score.d.ts +44 -1
- package/dist/score.d.ts.map +1 -1
- package/dist/score.js +78 -5
- package/dist/score.js.map +1 -1
- package/package.json +1 -1
- package/sbom.json +374 -74
- package/src/agentdb-index.ts +423 -60
- package/src/apply-leg.ts +187 -36
- package/src/codex-rollouts.ts +374 -0
- package/src/cost-ledger.ts +232 -24
- package/src/cross-family-control.ts +960 -0
- package/src/debt-ratchet.ts +143 -0
- package/src/embedding-config.ts +131 -10
- package/src/feature-adr-checkpoints.ts +29 -0
- package/src/feature-adr-decision-recall.ts +6 -4
- package/src/feature-adr-envelope.ts +242 -0
- package/src/feature-adr-routing.ts +139 -2
- package/src/feature-adr-stage-canon.ts +141 -0
- package/src/index.ts +60 -6
- package/src/loop-blobs.generated.ts +4 -4
- package/src/mutation-gate.ts +316 -0
- package/src/qe-bridge.ts +4 -2
- package/src/qe-findings.ts +463 -0
- package/src/recap.ts +10 -3
- package/src/round.ts +165 -6
- package/src/run-records.ts +282 -2
- package/src/score.ts +115 -6
package/dist/run-records.js
CHANGED
|
@@ -12,7 +12,94 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Pure: payload in, verdict out. The CLI owns paths, the append, the read-back and the exit code.
|
|
14
14
|
*/
|
|
15
|
+
import { matchCodexRollouts } from './codex-rollouts.js';
|
|
15
16
|
import { redactTrainingPayload } from './feature-adr-checkpoints.js';
|
|
17
|
+
import { validateExperimentEnvelope } from './feature-adr-envelope.js';
|
|
18
|
+
/** Bare Claude model names the pipeline actually emits with no `claude:` prefix (`coder: 'sonnet'`,
|
|
19
|
+
* `'opus'`, `'fable'`, real values observed in `.dz/feature-adr/run-cost-ledger.jsonl`). */
|
|
20
|
+
const BARE_CLAUDE_NAMES = new Set(['sonnet', 'opus', 'haiku', 'fable']);
|
|
21
|
+
/** id/effort alphabet a model spec component may use (lead delta after Codex r2, new MEDIUM #3). */
|
|
22
|
+
const SPEC_PART = /^[A-Za-z0-9._-]+$/;
|
|
23
|
+
/**
|
|
24
|
+
* Parse an executor spec — the shapes actually recorded in `coder`/`reviewer` fields
|
|
25
|
+
* (`codex:gpt-5.6-sol:high`, `claude:sonnet`, bare `sonnet`/`opus`, bare `codex`, bare `claude`) —
|
|
26
|
+
* into `{family, model, effort}`. Pure, never throws.
|
|
27
|
+
*
|
|
28
|
+
* Returns `null` (never a guess) for anything that cannot be resolved to exactly ONE model:
|
|
29
|
+
* - a bare `'codex'` or `'claude'` (family named, no model at all);
|
|
30
|
+
* - an annotated/aggregate field such as `'claude:sonnet x2'` or `'qe-bridge:claude x2 + lead'` (real
|
|
31
|
+
* values this ledger carries for a MULTI-reviewer round) — any embedded whitespace means the field
|
|
32
|
+
* names more than one resolvable spec, and picking one would misattribute to the others;
|
|
33
|
+
* - a bare model id with no family marker that is not one of the known bare Claude names (e.g. a full
|
|
34
|
+
* `'claude-sonnet-5'` — that shape is handled by the OLDER vendor-prefix path in {@link priceLookup}
|
|
35
|
+
* for backward compatibility, not by this parser).
|
|
36
|
+
*/
|
|
37
|
+
export function parseModelSpec(spec) {
|
|
38
|
+
if (typeof spec !== 'string')
|
|
39
|
+
return null;
|
|
40
|
+
const trimmed = spec.trim();
|
|
41
|
+
if (trimmed === '' || /\s/.test(trimmed))
|
|
42
|
+
return null;
|
|
43
|
+
const parts = trimmed.split(':');
|
|
44
|
+
const head = parts[0] ?? '';
|
|
45
|
+
if (head === 'codex') {
|
|
46
|
+
const model = parts[1];
|
|
47
|
+
if (model === undefined || model === '')
|
|
48
|
+
return null; // bare 'codex' — no reliable model
|
|
49
|
+
// Lead delta after Codex r2 (new MEDIUM #3): exactly 2 or 3 non-empty components, id alphabet
|
|
50
|
+
// only — `codex:gpt-5.6-sol:high:garbage` is a corrupt/aggregate spec, never a reliable model.
|
|
51
|
+
if (parts.length > 3 || !SPEC_PART.test(model) || (parts.length === 3 && (parts[2] === '' || !SPEC_PART.test(parts[2]))))
|
|
52
|
+
return null;
|
|
53
|
+
const effort = parts[2] ?? null;
|
|
54
|
+
return { family: 'codex', model, effort: effort === '' ? null : effort };
|
|
55
|
+
}
|
|
56
|
+
if (head === 'claude') {
|
|
57
|
+
const model = parts[1];
|
|
58
|
+
if (model === undefined || model === '')
|
|
59
|
+
return null; // bare 'claude' — no reliable model
|
|
60
|
+
return { family: 'claude', model, effort: null };
|
|
61
|
+
}
|
|
62
|
+
if (parts.length === 1 && BARE_CLAUDE_NAMES.has(head)) {
|
|
63
|
+
return { family: 'claude', model: head, effort: null };
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
function isCodexFamily(v) {
|
|
68
|
+
return typeof v === 'string' && /codex/i.test(v);
|
|
69
|
+
}
|
|
70
|
+
function isRecord(v) {
|
|
71
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
72
|
+
}
|
|
73
|
+
/** Longest-prefix match against the CALLER'S OWN table (never `cost-scoring.ts`'s internal
|
|
74
|
+
* constant) — the whole point of a price SNAPSHOT is that it answers only from what the caller
|
|
75
|
+
* handed in at write time, mirroring `pricingFor`'s matching rule without importing it.
|
|
76
|
+
*
|
|
77
|
+
* measurement-integrity fix-round-1/F7 (Codex r1 HIGH #7): the OLD version stripped only a
|
|
78
|
+
* `vendor/`-shaped prefix, so the REAL recorded shape `codex:gpt-5.6-sol:high` (or `claude:sonnet`)
|
|
79
|
+
* never matched anything and always landed in `prices.unknown[]`. This now runs the id through the
|
|
80
|
+
* SAME {@link parseModelSpec} FR-4's matcher uses, then reconstructs the normalized id the way
|
|
81
|
+
* `cost-scoring.ts`'s `pricingFor`/`hasKnownPricing` key their table (`claude-<model>` for the
|
|
82
|
+
* Claude family; the bare model for Codex — its ids carry no vendor prefix). A spec this parser
|
|
83
|
+
* cannot resolve falls back to the OLD vendor-prefix strip, so an already-working bare id
|
|
84
|
+
* (`claude-sonnet-5`, `gpt-4o`) keeps matching exactly as before (NFR-1). */
|
|
85
|
+
function priceLookup(modelId, table) {
|
|
86
|
+
if (typeof modelId !== 'string' || modelId.length === 0)
|
|
87
|
+
return null;
|
|
88
|
+
const parsed = parseModelSpec(modelId);
|
|
89
|
+
const id = parsed !== null
|
|
90
|
+
? (parsed.family === 'claude' ? `claude-${parsed.model}` : parsed.model).toLowerCase()
|
|
91
|
+
: modelId.toLowerCase().replace(/^[a-z0-9-]+\//, '');
|
|
92
|
+
let best = null;
|
|
93
|
+
let bestLen = 0;
|
|
94
|
+
for (const [key, price] of Object.entries(table)) {
|
|
95
|
+
const k = key.toLowerCase();
|
|
96
|
+
if (id.startsWith(k) && k.length > bestLen) {
|
|
97
|
+
best = price;
|
|
98
|
+
bestLen = k.length;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return best;
|
|
102
|
+
}
|
|
16
103
|
/** A serialised record line above this is refused rather than truncated (acid case A2). */
|
|
17
104
|
export const RECORD_MAX_LINE_CHARS = 24_000;
|
|
18
105
|
/** Fields every ledger row must carry before it is worth writing down. */
|
|
@@ -28,7 +115,7 @@ const noop = (verdict, reason) => ({
|
|
|
28
115
|
blocking: false,
|
|
29
116
|
line: null,
|
|
30
117
|
});
|
|
31
|
-
function shapeMismatch(kind, payload) {
|
|
118
|
+
function shapeMismatch(kind, payload, autoFlag) {
|
|
32
119
|
// AM-1 FIRST, before the required-field sweep. A ledger row offered as a training pair fails BOTH
|
|
33
120
|
// checks, and the wrong-kind reason is the one that tells the caller what actually happened —
|
|
34
121
|
// "missing field `output`" sends them looking for a field they never meant to send.
|
|
@@ -41,6 +128,40 @@ function shapeMismatch(kind, payload) {
|
|
|
41
128
|
if (kind === 'training-pair' && 'tokens' in payload && !('input' in payload)) {
|
|
42
129
|
return 'this payload looks like a ledger row (`tokens` without `input`), not a training pair';
|
|
43
130
|
}
|
|
131
|
+
// experiment-envelope FR-5 / ADR-001 D2: `auto:true` marks a pipeline-written row, and the pipeline
|
|
132
|
+
// is obligated to carry the envelope built once after the Step-0 router — a row missing it is
|
|
133
|
+
// useless for learning and would silently corrupt the sample (the "warn but write" alternative was
|
|
134
|
+
// rejected in the ADR: a warning nobody reads left `tokens=null` unnoticed for years). A MANUAL row
|
|
135
|
+
// (no `auto`) stays compatible: no envelope required, but one that IS present is still validated —
|
|
136
|
+
// never trusted just because a human typed it.
|
|
137
|
+
//
|
|
138
|
+
// fix-round-1/F2 (cross-family review, HIGH #2): the PAYLOAD's own `auto` field used to be the
|
|
139
|
+
// ONLY signal — an automatic producer that forgot it, or sent `"true"`/`false`, was silently
|
|
140
|
+
// accepted as a manual row and skipped the envelope requirement entirely. `autoFlag` is the CLI's
|
|
141
|
+
// own trusted `--auto` argument (never JSON a caller could typo): it is a SECOND, independent
|
|
142
|
+
// trust source, unioned with the payload field rather than replacing it — nothing that used to be
|
|
143
|
+
// gated stops being gated, and a `--auto`-dispatched caller is now gated even if its hand-built
|
|
144
|
+
// payload forgot the field. Independently of either source, a PRESENT `auto` field is checked for
|
|
145
|
+
// shape: only the literal `true` is a legal value — anything else (a string, `false`, a number) is
|
|
146
|
+
// refused outright, because a field whose only sane value is `true` holding something else is a
|
|
147
|
+
// caller bug worth surfacing, not silently downgrading to "manual".
|
|
148
|
+
if (kind === 'ledger') {
|
|
149
|
+
const rawAuto = payload['auto'];
|
|
150
|
+
if (rawAuto !== undefined && rawAuto !== true) {
|
|
151
|
+
return 'a ledger record\'s `auto` field must be `true` or absent';
|
|
152
|
+
}
|
|
153
|
+
const envelope = payload['envelope'];
|
|
154
|
+
const envelopePresent = envelope !== undefined && envelope !== null;
|
|
155
|
+
const isAuto = autoFlag === true || rawAuto === true;
|
|
156
|
+
if (isAuto && !envelopePresent) {
|
|
157
|
+
return 'an auto ledger row must carry `envelope` (experiment-envelope FR-5)';
|
|
158
|
+
}
|
|
159
|
+
if (envelopePresent) {
|
|
160
|
+
const v = validateExperimentEnvelope(envelope);
|
|
161
|
+
if (!v.ok)
|
|
162
|
+
return `envelope invalid — ${v.reason}`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
44
165
|
const required = kind === 'ledger' ? LEDGER_REQUIRED : PAIR_REQUIRED;
|
|
45
166
|
for (const field of required) {
|
|
46
167
|
const v = payload[field];
|
|
@@ -90,7 +211,7 @@ export function decideRecordWrite(input) {
|
|
|
90
211
|
// BEFORE the shape check, the line cap and the serialisation, so nothing downstream — the file,
|
|
91
212
|
// the read-back, the refusal texts — ever sees a byte of the profile block.
|
|
92
213
|
const obj = (kind === 'training-pair' ? redactTrainingPayload(payload) : payload);
|
|
93
|
-
const mismatch = shapeMismatch(kind, obj);
|
|
214
|
+
const mismatch = shapeMismatch(kind, obj, input.auto === true);
|
|
94
215
|
if (mismatch !== null)
|
|
95
216
|
return refuse(mismatch);
|
|
96
217
|
// The record is filed under `--stage`, and the payload carries its own. A disagreement means the
|
|
@@ -117,6 +238,12 @@ export function decideRecordWrite(input) {
|
|
|
117
238
|
// inside an already-serialised document — text surgery on a structured value, and the exact place
|
|
118
239
|
// a payload containing that literal token could corrupt itself.
|
|
119
240
|
const stamped = { ...obj };
|
|
241
|
+
// fix-round-1/F2: the CLI's own `--auto` flag is authoritative — when set, the written row MUST
|
|
242
|
+
// carry `auto:true` too (not just gate on it transiently), so every downstream reader of the
|
|
243
|
+
// PERSISTED line keeps seeing the same signal `shapeMismatch` already gated on above. A no-op when
|
|
244
|
+
// the payload already said `auto:true` (shapeMismatch already refused any OTHER value).
|
|
245
|
+
if (kind === 'ledger' && input.auto === true)
|
|
246
|
+
stamped['auto'] = true;
|
|
120
247
|
const isGap = (v) => v === null || v === undefined || (typeof v === 'string' && v.trim() === '');
|
|
121
248
|
if (input.timestamp != null && input.timestamp !== '') {
|
|
122
249
|
// An EMPTY STRING is a gap, not a value. Stamping only over null/undefined let
|
|
@@ -207,6 +334,121 @@ export function decideRecordWrite(input) {
|
|
|
207
334
|
stamped['minutesSource'] = minutesSource;
|
|
208
335
|
}
|
|
209
336
|
}
|
|
337
|
+
// measurement-integrity FR-5 (rollout enrichment) + FR-6 (price snapshot). Both are ADDITIVE and
|
|
338
|
+
// OPT-IN on `input.enrich` — a caller that never passes it gets byte-identical output to before
|
|
339
|
+
// this feature (NFR-1).
|
|
340
|
+
if (kind === 'ledger' && input.enrich !== undefined) {
|
|
341
|
+
const enrich = input.enrich;
|
|
342
|
+
// FR-5: only a codex-family coder/reviewer with `tokens: null` is a candidate — a Claude row, or
|
|
343
|
+
// one that already has a token figure, is left untouched. The loose `/codex/i` check below only
|
|
344
|
+
// decides whether this row is WORTH TRYING at all.
|
|
345
|
+
const tokensIsNull = stamped['tokens'] === null;
|
|
346
|
+
const looksCodexFamily = isCodexFamily(stamped['coder']) || isCodexFamily(stamped['reviewer']);
|
|
347
|
+
if (tokensIsNull && looksCodexFamily) {
|
|
348
|
+
// measurement-integrity fix-round-1/F4 (Codex r1 HIGH #4): the matcher REQUIRES a reliable
|
|
349
|
+
// model, parsed the same way FR-7's price lookup parses one — never `/codex/i` alone. If
|
|
350
|
+
// `coder`/`reviewer` do not resolve to exactly ONE codex model between them (a bare `'codex'`
|
|
351
|
+
// with no model at all, or the two fields naming DIFFERENT codex models), the matcher is never
|
|
352
|
+
// even called with an unreliable/omitted model filter — a lone rollout in the window would
|
|
353
|
+
// otherwise be accepted as `'one'` on time+cwd alone and its tokens misattributed to the wrong
|
|
354
|
+
// model's stage.
|
|
355
|
+
const codexModels = new Set([parseModelSpec(stamped['coder']), parseModelSpec(stamped['reviewer'])]
|
|
356
|
+
.filter((s) => s !== null && s.family === 'codex')
|
|
357
|
+
.map((s) => s.model));
|
|
358
|
+
if (codexModels.size !== 1) {
|
|
359
|
+
stamped['tokensSource'] = 'codex-rollout:no-model';
|
|
360
|
+
}
|
|
361
|
+
else if (enrich.window !== undefined) {
|
|
362
|
+
const model = [...codexModels][0];
|
|
363
|
+
const match = matchCodexRollouts(enrich.rollouts ?? [], {
|
|
364
|
+
from: enrich.window.from,
|
|
365
|
+
to: enrich.window.to,
|
|
366
|
+
model,
|
|
367
|
+
...(enrich.cwd !== undefined ? { cwd: enrich.cwd } : {}),
|
|
368
|
+
});
|
|
369
|
+
if (match.status === 'one') {
|
|
370
|
+
stamped['tokens'] = match.rollout.totals.total;
|
|
371
|
+
const startMs = match.rollout.startedAt !== null ? Date.parse(match.rollout.startedAt) : NaN;
|
|
372
|
+
const endMs = match.rollout.endedAt !== null ? Date.parse(match.rollout.endedAt) : NaN;
|
|
373
|
+
// measurement-integrity fix-round-1/F6 (Codex r1 HIGH #6): fill-ONLY-null — an existing
|
|
374
|
+
// `minutes` figure (a manually recorded one, say) must never be silently overwritten by a
|
|
375
|
+
// derived rollout duration.
|
|
376
|
+
if (stamped['minutes'] === null && Number.isFinite(startMs) && Number.isFinite(endMs) && endMs >= startMs) {
|
|
377
|
+
stamped['minutes'] = Math.round(((endMs - startMs) / 60000) * 10) / 10;
|
|
378
|
+
}
|
|
379
|
+
stamped['tokensSource'] = 'codex-rollout';
|
|
380
|
+
stamped['rolloutId'] = match.rollout.id;
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
// `none` or `ambiguous` — NFR-3: an explicit status, never a guessed number.
|
|
384
|
+
stamped['tokensSource'] = `codex-rollout:${match.status}`;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
// Eligible in principle (codex family, one reliable model, tokens null) but no window was
|
|
389
|
+
// supplied — AC-4's "old row without a window": no enrichment is even attempted, and that
|
|
390
|
+
// fact is itself recorded rather than left silently absent.
|
|
391
|
+
stamped['tokensSource'] = 'unavailable';
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// FR-6: the price snapshot, for every model this row names — independent of the FR-5 branch
|
|
395
|
+
// above (a Claude row gets priced too; only tokens enrichment is codex-specific).
|
|
396
|
+
if (enrich.prices !== undefined) {
|
|
397
|
+
const modelIds = new Set();
|
|
398
|
+
for (const v of [stamped['coder'], stamped['reviewer']]) {
|
|
399
|
+
if (typeof v === 'string' && v.trim() !== '')
|
|
400
|
+
modelIds.add(v.trim());
|
|
401
|
+
}
|
|
402
|
+
const envelope = stamped['envelope'];
|
|
403
|
+
if (isRecord(envelope)) {
|
|
404
|
+
const chosen = envelope['chosen'];
|
|
405
|
+
if (isRecord(chosen)) {
|
|
406
|
+
const stages = chosen['stages'];
|
|
407
|
+
if (isRecord(stages)) {
|
|
408
|
+
for (const v of Object.values(stages)) {
|
|
409
|
+
if (typeof v === 'string' && v.trim() !== '')
|
|
410
|
+
modelIds.add(v.trim());
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const table = {};
|
|
416
|
+
const unknown = [];
|
|
417
|
+
for (const modelId of modelIds) {
|
|
418
|
+
const price = priceLookup(modelId, enrich.prices);
|
|
419
|
+
if (price === null)
|
|
420
|
+
unknown.push(modelId);
|
|
421
|
+
else
|
|
422
|
+
table[modelId] = { prompt: price.prompt, completion: price.completion, cachedInput: price.cachedInput, cacheCreation: price.cacheCreation };
|
|
423
|
+
}
|
|
424
|
+
const computedPrices = {
|
|
425
|
+
snapshotAt: input.timestamp ?? null,
|
|
426
|
+
table,
|
|
427
|
+
...(unknown.length > 0 ? { unknown } : {}),
|
|
428
|
+
};
|
|
429
|
+
// measurement-integrity fix-round-1/F6 (Codex r1 HIGH #6): fill-ONLY-null for `prices` too — an
|
|
430
|
+
// existing snapshot (a previous write already priced this row) is never unconditionally
|
|
431
|
+
// replaced. Equal → left alone (idempotent re-enrichment, common on a retried write). Different
|
|
432
|
+
// → a named `pricesConflict`, never a silent re-price (ADR-001 D4 forbids re-pricing after the
|
|
433
|
+
// fact — a DIFFERING recomputation is exactly that, so it is surfaced, not applied).
|
|
434
|
+
const existingPrices = stamped['prices'];
|
|
435
|
+
if (existingPrices === undefined || existingPrices === null) {
|
|
436
|
+
stamped['prices'] = computedPrices;
|
|
437
|
+
}
|
|
438
|
+
else if (isRecord(existingPrices) && isRecord(existingPrices['table']) && (existingPrices['unknown'] === undefined || Array.isArray(existingPrices['unknown']))) {
|
|
439
|
+
// Lead delta after Codex r2 (new MEDIUM #4): compare the WHOLE snapshot canonically (table +
|
|
440
|
+
// sorted unknown), not the table alone.
|
|
441
|
+
const canon = (t, u) => JSON.stringify({ table: t, unknown: Array.isArray(u) ? [...u].map(String).sort() : [] });
|
|
442
|
+
if (canon(existingPrices['table'], existingPrices['unknown']) !== canon(table, unknown)) {
|
|
443
|
+
stamped['pricesConflict'] = { existing: existingPrices, recomputed: computedPrices };
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
// A malformed existing snapshot (no table / bad unknown) is a CONFLICT, never silently trusted.
|
|
448
|
+
stamped['pricesConflict'] = { existing: existingPrices, recomputed: computedPrices, reason: 'existing prices snapshot is malformed' };
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
210
452
|
let line;
|
|
211
453
|
try {
|
|
212
454
|
line = JSON.stringify(stamped);
|
package/dist/run-records.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-records.js","sourceRoot":"","sources":["../src/run-records.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run-records.js","sourceRoot":"","sources":["../src/run-records.ts"],"names":[],"mappings":"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"}
|
package/dist/score.d.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*
|
|
20
20
|
* PURE: the CLI reads the artifact files; this module only classifies.
|
|
21
21
|
*/
|
|
22
|
+
import { type QeFindingsRefusedRow, type QeFindingsSummary } from './qe-findings.js';
|
|
22
23
|
export type DisciplineVerdict = 'pass' | 'partial' | 'absent';
|
|
23
24
|
export interface DisciplineScore {
|
|
24
25
|
readonly id: string;
|
|
@@ -40,10 +41,32 @@ export interface RunScorecard {
|
|
|
40
41
|
* stay distinguishable.
|
|
41
42
|
*/
|
|
42
43
|
readonly mutationEvidence?: MutationEvidence;
|
|
44
|
+
/**
|
|
45
|
+
* qe-findings-record FR-4: where `qeGrade` came from — a machine-written `QE-VERDICT:` line, the
|
|
46
|
+
* pre-existing prose scan, or neither. ADDITIVE for the same reason as `mutationEvidence`: every
|
|
47
|
+
* scorecard built before this field existed still satisfies `RunScorecard`.
|
|
48
|
+
*/
|
|
49
|
+
readonly gradeSource?: GradeSource;
|
|
50
|
+
/**
|
|
51
|
+
* qe-findings-record FR-4: the report's Findings ledger, when one exists. `absent` for the 406
|
|
52
|
+
* pre-existing reports that carry neither the table nor the heading (NFR-1) — never omitted, for
|
|
53
|
+
* the same "gate never ran vs a field an older scorer never wrote" reason `mutationEvidence` gives.
|
|
54
|
+
*/
|
|
55
|
+
readonly findings?: QeFindingsScoreView;
|
|
43
56
|
readonly passed: number;
|
|
44
57
|
readonly total: number;
|
|
45
58
|
readonly summary: string;
|
|
46
59
|
}
|
|
60
|
+
/** A lighter projection of `QeFindingsResult` for the scorecard — summary + refused + hollow, never
|
|
61
|
+
* the full row list (that stays in `parseQeFindings`'s own return value for a caller that wants it). */
|
|
62
|
+
export type QeFindingsScoreView = {
|
|
63
|
+
readonly status: 'absent';
|
|
64
|
+
} | {
|
|
65
|
+
readonly status: 'present';
|
|
66
|
+
readonly hollow: boolean;
|
|
67
|
+
readonly summary: QeFindingsSummary;
|
|
68
|
+
readonly refused: readonly QeFindingsRefusedRow[];
|
|
69
|
+
};
|
|
47
70
|
/** The artifact texts of one run, keyed by RELATIVE path under `features/<slug>/`. */
|
|
48
71
|
/**
|
|
49
72
|
* The exact heading Step 5 asks for, and the exact heading the check looks for — ONE constant, so
|
|
@@ -100,13 +123,28 @@ export interface MutationEvidence {
|
|
|
100
123
|
readonly evidence: string;
|
|
101
124
|
}
|
|
102
125
|
export declare function readMutationEvidence(text: string): MutationEvidence;
|
|
103
|
-
|
|
126
|
+
/**
|
|
127
|
+
* fix-round-1 (codex-r1-verdict finding 2): `'invalid'` is a report that ATTEMPTED a machine verdict
|
|
128
|
+
* (a line starting `QE-VERDICT`, any case/spacing) and got the grammar wrong — `QE-VERDICT: B – final`
|
|
129
|
+
* (en dash + trailing prose), wrong case, no colon, a grade outside A-D. That is a DIFFERENT fact from
|
|
130
|
+
* `'none'` (no attempt at all, legacy prose scan still applies): a malformed attempt must never fall
|
|
131
|
+
* back to guessing a grade from prose — the malformed line is itself evidence the report is unreliable
|
|
132
|
+
* here, and guessing past it would silently launder that unreliability into a confident number.
|
|
133
|
+
*/
|
|
134
|
+
export type GradeReadStatus = 'unique' | 'ambiguous' | 'none' | 'invalid';
|
|
135
|
+
/**
|
|
136
|
+
* qe-findings-record (ADR-001 D1): where the grade came from. `'verdict-line'` — a machine-written
|
|
137
|
+
* `QE-VERDICT:` line, the source of truth when present. `'prose'` — the pre-existing GRADE_RE scan,
|
|
138
|
+
* unchanged, used only when NO verdict line exists. `'none'` — neither surface names a grade.
|
|
139
|
+
*/
|
|
140
|
+
export type GradeSource = 'verdict-line' | 'prose' | 'none';
|
|
104
141
|
export interface GradeReading {
|
|
105
142
|
readonly status: GradeReadStatus;
|
|
106
143
|
/** The grade, ONLY when the report names one unambiguously. */
|
|
107
144
|
readonly grade: string | null;
|
|
108
145
|
/** Every distinct grade found, normalised — what makes an `ambiguous` verdict inspectable. */
|
|
109
146
|
readonly found: readonly string[];
|
|
147
|
+
readonly source: GradeSource;
|
|
110
148
|
}
|
|
111
149
|
/**
|
|
112
150
|
* Read the review grade a report states — and refuse to guess when it states more than one.
|
|
@@ -123,6 +161,11 @@ export interface GradeReading {
|
|
|
123
161
|
export declare function readQeGrade(qeText: string): GradeReading;
|
|
124
162
|
export declare function extractQeGrade(qeText: string): string | null;
|
|
125
163
|
export declare function scoreRun(slug: string, artifacts: RunArtifacts): RunScorecard;
|
|
164
|
+
/** qe-findings-record FR-4: the one-line summary `dz score` prints for a report's Findings ledger —
|
|
165
|
+
* "findings: 3 HIGH / 2 MEDIUM; 1 refused (line 84: severity "Major" not in dictionary)". Ordered by
|
|
166
|
+
* QE_SEVERITIES (BLOCKER first) so the worst finding always reads first. `null` when there is no
|
|
167
|
+
* table at all — the common case, which earns no noise (same rule as mutationEvidence above). */
|
|
168
|
+
export declare function renderFindingsLine(findings: QeFindingsScoreView | undefined): string | null;
|
|
126
169
|
export declare function renderScorecard(card: RunScorecard): string;
|
|
127
170
|
/** The append-only projection of one immutable `score-<qeHash>.json` receipt. */
|
|
128
171
|
export interface ScoreAggregateRow {
|
package/dist/score.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../src/score.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../src/score.ts"],"names":[],"mappings":"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"}
|
package/dist/score.js
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* PURE: the CLI reads the artifact files; this module only classifies.
|
|
21
21
|
*/
|
|
22
22
|
import { amendmentIdsIn } from './amendment-trace.js';
|
|
23
|
+
import { QE_SEVERITIES, findInvalidQeVerdictLines, parseQeFindings, readQeVerdictLines } from './qe-findings.js';
|
|
23
24
|
/** The artifact texts of one run, keyed by RELATIVE path under `features/<slug>/`. */
|
|
24
25
|
/**
|
|
25
26
|
* The exact heading Step 5 asks for, and the exact heading the check looks for — ONE constant, so
|
|
@@ -258,6 +259,42 @@ function normaliseGradeSign(grade) {
|
|
|
258
259
|
* report is ambiguous, which is a fact about the report, not a missing number.
|
|
259
260
|
*/
|
|
260
261
|
export function readQeGrade(qeText) {
|
|
262
|
+
// ADR-001 D1: a machine-written verdict line is the source of truth WHEN it exists — checked
|
|
263
|
+
// first, and the prose scan below never runs when it does. Exactly one -> unique; more than one
|
|
264
|
+
// -> ambiguous ("две строки — ambiguous, никогда «последняя побеждает»", even if both name the
|
|
265
|
+
// SAME grade — two lines is a fact about the report, not a number to reconcile); zero -> the
|
|
266
|
+
// prose scan runs exactly as it always has (NFR-1: 406 pre-existing reports are unaffected) —
|
|
267
|
+
// UNLESS a malformed attempt exists (fix-round-1 finding 2, checked next): the report is `invalid`
|
|
268
|
+
// and the prose fallback is refused, never silently reached.
|
|
269
|
+
const verdictLines = readQeVerdictLines(qeText);
|
|
270
|
+
// Lead delta after Codex r2 (new HIGH #1): a malformed declaration next to a valid one is NOT a
|
|
271
|
+
// unique verdict — `QE-VERDICT: A` + `qe-verdict: D` used to read as unique A. Invalid lines are
|
|
272
|
+
// checked FIRST, whatever the count of valid ones.
|
|
273
|
+
const invalidFirst = findInvalidQeVerdictLines(qeText);
|
|
274
|
+
if (invalidFirst.length > 0) {
|
|
275
|
+
const reasons = invalidFirst.map((l) => `line ${l.line}: ${JSON.stringify(l.text.trim())} does not match "QE-VERDICT: <A|B|C|D><+|-> "`);
|
|
276
|
+
return { status: 'invalid', grade: null, found: [...verdictLines, ...reasons], source: 'verdict-line' };
|
|
277
|
+
}
|
|
278
|
+
if (verdictLines.length === 1) {
|
|
279
|
+
return { status: 'unique', grade: verdictLines[0], found: verdictLines, source: 'verdict-line' };
|
|
280
|
+
}
|
|
281
|
+
if (verdictLines.length > 1) {
|
|
282
|
+
const distinct = [];
|
|
283
|
+
for (const g of verdictLines)
|
|
284
|
+
if (!distinct.includes(g))
|
|
285
|
+
distinct.push(g);
|
|
286
|
+
return { status: 'ambiguous', grade: null, found: distinct, source: 'verdict-line' };
|
|
287
|
+
}
|
|
288
|
+
// fix-round-1 finding 2: zero GRAMMATICALLY VALID verdict lines is not yet "no attempt" — a line
|
|
289
|
+
// that clearly opens a verdict declaration but botches the grammar (wrong dash, wrong case, no
|
|
290
|
+
// colon, a grade outside A-D) is `invalid`, and the legacy prose scan below is FORBIDDEN for it.
|
|
291
|
+
// The reason lives inside `found` (GradeReading keeps the same 4-field shape for every status).
|
|
292
|
+
// Lead delta after Codex r2 (#2 PARTIAL): the prose fallback is for LEGACY reports only. A report
|
|
293
|
+
// that already carries the new-format ledger heading but no verdict line is a NEW-format report
|
|
294
|
+
// missing its verdict — `invalid`, never a prose guess.
|
|
295
|
+
if (/^## Findings ledger\s*$/m.test(qeText)) {
|
|
296
|
+
return { status: 'invalid', grade: null, found: ['new-format report (has "## Findings ledger") without a QE-VERDICT line'], source: 'verdict-line' };
|
|
297
|
+
}
|
|
261
298
|
const found = [];
|
|
262
299
|
const lines = qeText.split('\n');
|
|
263
300
|
// Line offsets once, so each match maps to ITS line for the negation screen (67d7883d: the
|
|
@@ -291,10 +328,10 @@ export function readQeGrade(qeText) {
|
|
|
291
328
|
found.push(g);
|
|
292
329
|
}
|
|
293
330
|
if (found.length === 0)
|
|
294
|
-
return { status: 'none', grade: null, found: [] };
|
|
331
|
+
return { status: 'none', grade: null, found: [], source: 'none' };
|
|
295
332
|
if (found.length === 1)
|
|
296
|
-
return { status: 'unique', grade: found[0], found };
|
|
297
|
-
return { status: 'ambiguous', grade: null, found };
|
|
333
|
+
return { status: 'unique', grade: found[0], found, source: 'prose' };
|
|
334
|
+
return { status: 'ambiguous', grade: null, found, source: 'prose' };
|
|
298
335
|
}
|
|
299
336
|
export function extractQeGrade(qeText) {
|
|
300
337
|
return readQeGrade(qeText).grade;
|
|
@@ -379,7 +416,12 @@ export function scoreRun(slug, artifacts) {
|
|
|
379
416
|
? 'no discrimination/§42/mutation-proof evidence in any artifact'
|
|
380
417
|
: mutationEvidence.evidence)));
|
|
381
418
|
// 3. Cross-model QE — an independent family reviewed it, and a grade exists.
|
|
382
|
-
const
|
|
419
|
+
const gradeReading = readQeGrade(qeText);
|
|
420
|
+
const grade = gradeReading.grade;
|
|
421
|
+
const findingsParsed = parseQeFindings(qeText);
|
|
422
|
+
const findings = findingsParsed.status === 'absent'
|
|
423
|
+
? { status: 'absent' }
|
|
424
|
+
: { status: 'present', hollow: findingsParsed.hollow, summary: findingsParsed.summary, refused: findingsParsed.refused };
|
|
383
425
|
if (qeText === '') {
|
|
384
426
|
add('cross-model-qe', 'independent cross-model review with a grade', 'absent', 'no 08_qe_report.md artifact');
|
|
385
427
|
}
|
|
@@ -451,9 +493,35 @@ export function scoreRun(slug, artifacts) {
|
|
|
451
493
|
const summary = `${passed}/${total} disciplines fully evidenced` +
|
|
452
494
|
(grade !== null ? ` · QE grade ${grade}` : ' · no QE grade') +
|
|
453
495
|
(worst.length > 0 ? ` · absent: ${worst.join(', ')}` : '');
|
|
454
|
-
return { slug, disciplines, qeGrade: grade, mutationEvidence, passed, total, summary };
|
|
496
|
+
return { slug, disciplines, qeGrade: grade, gradeSource: gradeReading.source, findings, mutationEvidence, passed, total, summary };
|
|
455
497
|
}
|
|
456
498
|
const MARK = { pass: '✓', partial: '◐', absent: '✗' };
|
|
499
|
+
/** qe-findings-record FR-4: the one-line summary `dz score` prints for a report's Findings ledger —
|
|
500
|
+
* "findings: 3 HIGH / 2 MEDIUM; 1 refused (line 84: severity "Major" not in dictionary)". Ordered by
|
|
501
|
+
* QE_SEVERITIES (BLOCKER first) so the worst finding always reads first. `null` when there is no
|
|
502
|
+
* table at all — the common case, which earns no noise (same rule as mutationEvidence above). */
|
|
503
|
+
export function renderFindingsLine(findings) {
|
|
504
|
+
if (findings === undefined || findings.status === 'absent')
|
|
505
|
+
return null;
|
|
506
|
+
// fix-round-1 finding 6: hollow used to short-circuit BEFORE the refused check, so a report whose
|
|
507
|
+
// real ledger table (with CRITICAL rows) was refused as duplicate/outside-section alongside an
|
|
508
|
+
// empty accepted table read as pure "EMPTY" — the refused rows vanished from the printed line, not
|
|
509
|
+
// merely from the tally. Both facts are ALWAYS reported together now; neither hides the other.
|
|
510
|
+
const refusedSuffix = (() => {
|
|
511
|
+
if (findings.refused.length === 0)
|
|
512
|
+
return '';
|
|
513
|
+
const first = findings.refused[0];
|
|
514
|
+
const more = findings.refused.length > 1 ? `, +${findings.refused.length - 1} more` : '';
|
|
515
|
+
return `; ${findings.refused.length} refused (line ${first.line}: ${first.reason})${more}`;
|
|
516
|
+
})();
|
|
517
|
+
if (findings.hollow) {
|
|
518
|
+
return `findings: table present but EMPTY (hollow) — worse than no table at all${refusedSuffix}`;
|
|
519
|
+
}
|
|
520
|
+
const bySev = findings.summary.bySeverity;
|
|
521
|
+
const parts = QE_SEVERITIES.filter((s) => (bySev[s] ?? 0) > 0).map((s) => `${bySev[s]} ${s}`);
|
|
522
|
+
const head = parts.length > 0 ? parts.join(' / ') : 'no rows';
|
|
523
|
+
return `findings: ${head}${refusedSuffix}`;
|
|
524
|
+
}
|
|
457
525
|
export function renderScorecard(card) {
|
|
458
526
|
const out = [];
|
|
459
527
|
out.push(`dz score — ${card.slug} (process scorecard; descriptive-only, never a gate)`);
|
|
@@ -471,6 +539,11 @@ export function renderScorecard(card) {
|
|
|
471
539
|
out.push('');
|
|
472
540
|
out.push(` ${card.mutationEvidence.evidence}`);
|
|
473
541
|
}
|
|
542
|
+
const findingsLine = renderFindingsLine(card.findings);
|
|
543
|
+
if (findingsLine !== null) {
|
|
544
|
+
out.push('');
|
|
545
|
+
out.push(` ${findingsLine}${card.gradeSource !== undefined && card.gradeSource !== 'none' ? ` (grade source: ${card.gradeSource})` : ''}`);
|
|
546
|
+
}
|
|
474
547
|
out.push('');
|
|
475
548
|
out.push(` ${card.summary}`);
|
|
476
549
|
return out.join('\n');
|