@dzhechkov/harness-core 0.3.142 → 0.3.144
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 +49 -25
- package/README.md +2 -1
- package/dist/backlog.d.ts +97 -1
- package/dist/backlog.d.ts.map +1 -1
- package/dist/backlog.js +214 -31
- package/dist/backlog.js.map +1 -1
- package/dist/compounding.d.ts +22 -0
- package/dist/compounding.d.ts.map +1 -1
- package/dist/compounding.js +29 -10
- package/dist/compounding.js.map +1 -1
- package/dist/epoch-replay.d.ts +399 -0
- package/dist/epoch-replay.d.ts.map +1 -0
- package/dist/epoch-replay.js +695 -0
- package/dist/epoch-replay.js.map +1 -0
- package/dist/guard.d.ts +44 -0
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +144 -1
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/sbom.json +84 -24
- package/src/backlog.ts +282 -27
- package/src/compounding.ts +45 -8
- package/src/epoch-replay.ts +955 -0
- package/src/guard.ts +151 -1
- package/src/index.ts +52 -0
package/src/compounding.ts
CHANGED
|
@@ -106,6 +106,47 @@ export interface UsageEvent {
|
|
|
106
106
|
readonly queryTruncated?: boolean;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
export interface ReplayInstance {
|
|
110
|
+
/** Stable per-PROMPT key — one prompt is one instance, however many lessons it injected. */
|
|
111
|
+
readonly id: string;
|
|
112
|
+
readonly query: string;
|
|
113
|
+
/** Exactly the lesson texts the apply leg injected for this prompt — the WARM arm's only delta. */
|
|
114
|
+
readonly lessons: readonly string[];
|
|
115
|
+
/**
|
|
116
|
+
* Pre-registered slice label (e.g. `task` / `conversational`). `null` until a human assigns it —
|
|
117
|
+
* nothing here invents a classification, because a class assigned AFTER outcomes are known is
|
|
118
|
+
* not a pre-registration.
|
|
119
|
+
*/
|
|
120
|
+
readonly class: string | null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The ONE definition of "a replayable pair": the readiness gate below COUNTS these and
|
|
125
|
+
* `dz epoch-replay --emit` EMITS these. A second copy would let readiness say 12 while the runner
|
|
126
|
+
* emits 9, silently — the drift class this repo keeps catching.
|
|
127
|
+
*
|
|
128
|
+
* Rules: a prompt with no query cannot be replayed; a TRUNCATED query is a prefix, not the prompt;
|
|
129
|
+
* one prompt = one instance (the hook writes one row per injected hit, up to 3 per prompt).
|
|
130
|
+
*/
|
|
131
|
+
export function replayableInstances(
|
|
132
|
+
usage: readonly UsageEvent[],
|
|
133
|
+
lessonText: ReadonlyMap<string, string> = new Map(),
|
|
134
|
+
): ReplayInstance[] {
|
|
135
|
+
const byKey = new Map<string, { query: string; lessons: string[] }>();
|
|
136
|
+
for (const u of usage) {
|
|
137
|
+
if (typeof u.query !== 'string' || u.query.trim() === '') continue;
|
|
138
|
+
if (u.queryTruncated === true) continue; // a prefix is not the prompt
|
|
139
|
+
const key = u.eventId ?? `${u.runId ?? ''}|${u.ts}|${u.query}`;
|
|
140
|
+
const entry = byKey.get(key) ?? { query: u.query, lessons: [] };
|
|
141
|
+
const text = lessonText.get(u.dzId);
|
|
142
|
+
if (typeof text === 'string' && text.trim() !== '' && !entry.lessons.includes(text)) {
|
|
143
|
+
entry.lessons.push(text);
|
|
144
|
+
}
|
|
145
|
+
byKey.set(key, entry);
|
|
146
|
+
}
|
|
147
|
+
return [...byKey.entries()].map(([id, e]) => ({ id, query: e.query, lessons: e.lessons, class: null }));
|
|
148
|
+
}
|
|
149
|
+
|
|
109
150
|
export interface GuardEvent {
|
|
110
151
|
readonly ts: string;
|
|
111
152
|
readonly verdict: string;
|
|
@@ -238,14 +279,10 @@ export function assembleCompoundingReport(facts: CompoundingFacts): CompoundingR
|
|
|
238
279
|
|
|
239
280
|
// 3. Replay readiness — cold-vs-warm needs (query -> injected lesson) pairs. They were never
|
|
240
281
|
// recorded before 2026-07-28, so this gate REPORTS accrual instead of faking a verdict.
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// one prompt = one pair, however many hits it injected
|
|
246
|
-
replayKeys.add(u.eventId ?? `${u.runId ?? ''}|${u.ts}|${u.query}`);
|
|
247
|
-
}
|
|
248
|
-
const replayablePairs = replayKeys.size;
|
|
282
|
+
// The rule ("no query / truncated query / one prompt = one pair") has exactly ONE definition,
|
|
283
|
+
// in epoch-replay.ts, and the RUNNER emits precisely what this gate counts — a second copy
|
|
284
|
+
// would let readiness say 12 while the runner emits 9, silently.
|
|
285
|
+
const replayablePairs = replayableInstances(usage).length;
|
|
249
286
|
const replay: ReplayReadiness = {
|
|
250
287
|
replayablePairs,
|
|
251
288
|
minNeeded: MIN_SAMPLES_PER_ARM,
|