agent-recall-core 3.4.35 → 3.4.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/dist/index.d.ts +7 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -8
- package/dist/index.js.map +1 -1
- package/dist/prompts/consolidation-prompt.d.ts +1 -1
- package/dist/prompts/consolidation-prompt.d.ts.map +1 -1
- package/dist/prompts/consolidation-prompt.js +1 -1
- package/dist/storage/ab-experiment.d.ts +184 -0
- package/dist/storage/ab-experiment.d.ts.map +1 -0
- package/dist/storage/ab-experiment.js +294 -0
- package/dist/storage/ab-experiment.js.map +1 -0
- package/dist/storage/classification.d.ts +7 -3
- package/dist/storage/classification.d.ts.map +1 -1
- package/dist/storage/classification.js +13 -9
- package/dist/storage/classification.js.map +1 -1
- package/dist/storage/corrections.d.ts +106 -2
- package/dist/storage/corrections.d.ts.map +1 -1
- package/dist/storage/corrections.js +197 -2
- package/dist/storage/corrections.js.map +1 -1
- package/dist/supabase/config.d.ts +18 -0
- package/dist/supabase/config.d.ts.map +1 -1
- package/dist/supabase/config.js +6 -0
- package/dist/supabase/config.js.map +1 -1
- package/dist/supabase/sync.d.ts +1 -1
- package/dist/supabase/sync.d.ts.map +1 -1
- package/dist/supabase/sync.js +55 -0
- package/dist/supabase/sync.js.map +1 -1
- package/dist/tools-logic/check-action.d.ts +31 -0
- package/dist/tools-logic/check-action.d.ts.map +1 -1
- package/dist/tools-logic/check-action.js +168 -1
- package/dist/tools-logic/check-action.js.map +1 -1
- package/dist/tools-logic/check.d.ts.map +1 -1
- package/dist/tools-logic/check.js +5 -0
- package/dist/tools-logic/check.js.map +1 -1
- package/dist/tools-logic/local-archive-backend.d.ts +33 -0
- package/dist/tools-logic/local-archive-backend.d.ts.map +1 -0
- package/dist/tools-logic/local-archive-backend.js +124 -0
- package/dist/tools-logic/local-archive-backend.js.map +1 -0
- package/dist/tools-logic/memory-backend.d.ts +74 -0
- package/dist/tools-logic/memory-backend.d.ts.map +1 -0
- package/dist/tools-logic/memory-backend.js +172 -0
- package/dist/tools-logic/memory-backend.js.map +1 -0
- package/dist/tools-logic/prior-builder.d.ts.map +1 -1
- package/dist/tools-logic/prior-builder.js +34 -1
- package/dist/tools-logic/prior-builder.js.map +1 -1
- package/dist/tools-logic/recognition-builder.d.ts +8 -2
- package/dist/tools-logic/recognition-builder.d.ts.map +1 -1
- package/dist/tools-logic/recognition-builder.js +1 -1
- package/dist/tools-logic/recognition-builder.js.map +1 -1
- package/dist/tools-logic/session-end-reflect.js +1 -1
- package/dist/tools-logic/session-end-reflect.js.map +1 -1
- package/dist/tools-logic/session-end.d.ts +9 -0
- package/dist/tools-logic/session-end.d.ts.map +1 -1
- package/dist/tools-logic/session-end.js +242 -52
- package/dist/tools-logic/session-end.js.map +1 -1
- package/dist/tools-logic/session-start-lite.d.ts.map +1 -1
- package/dist/tools-logic/session-start-lite.js +1 -2
- package/dist/tools-logic/session-start-lite.js.map +1 -1
- package/dist/tools-logic/session-start.d.ts +37 -4
- package/dist/tools-logic/session-start.d.ts.map +1 -1
- package/dist/tools-logic/session-start.js +305 -81
- package/dist/tools-logic/session-start.js.map +1 -1
- package/dist/tools-logic/smart-remember.js +8 -9
- package/dist/tools-logic/smart-remember.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/vector/embedding.d.ts +8 -0
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +9 -1
- package/dist/vector/embedding.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ab-experiment.ts — A/B injection switch for the correction-uplift experiment.
|
|
3
|
+
*
|
|
4
|
+
* DESIGN RATIONALE (C4, 2026-07-03)
|
|
5
|
+
* ─────────────────────────────────
|
|
6
|
+
* GOAL: measure whether injecting corrections at session_start reduces the rate
|
|
7
|
+
* at which the same correction recurs. The manipulated variable is the
|
|
8
|
+
* FULL correction-derived surface of the session_start payload. Capture,
|
|
9
|
+
* journaling, and session_end outcome recording stay ON in both arms —
|
|
10
|
+
* we A/B the injection EFFECT, not the capture pipeline.
|
|
11
|
+
*
|
|
12
|
+
* OFF-arm semantics (orchestrator ruling 2026-07-03): "this agent has no
|
|
13
|
+
* correction memory today". ALL correction-derived surfaces are absent or
|
|
14
|
+
* empty in an OFF payload:
|
|
15
|
+
* corrections → [] · watch_for → [] · predicted_risks → absent ·
|
|
16
|
+
* blind_spots → [] · mirror_available → absent · alignment → null ·
|
|
17
|
+
* recognition.person → absent (tendencies derive from blind spots).
|
|
18
|
+
* Additionally NO "retrieved" outcomes are recorded in OFF sessions —
|
|
19
|
+
* recording retrieval for rules the agent never saw would corrupt the
|
|
20
|
+
* precision KPI and the experiment itself.
|
|
21
|
+
*
|
|
22
|
+
* Insights, rooms, and captures (journal lineage) are intentionally NOT
|
|
23
|
+
* manipulated in v1 and stay in BOTH arms: v1 measures corrections only.
|
|
24
|
+
* If the experiment detects uplift, a v2 can vary insights too. This
|
|
25
|
+
* choice is recorded here so it cannot be silently reversed.
|
|
26
|
+
*
|
|
27
|
+
* OPT-IN DEFAULT: the experiment is DISABLED by default (AR_AB_ENABLED is not
|
|
28
|
+
* set). All sessions get full injection as today. The experiment owner
|
|
29
|
+
* sets AR_AB_ENABLED=1 when ready to start accumulating data. This is a
|
|
30
|
+
* hard requirement: the OFF arm degrades real user sessions, so we never
|
|
31
|
+
* run it without explicit intent.
|
|
32
|
+
*
|
|
33
|
+
* ARM ASSIGNMENT (deterministic, not random):
|
|
34
|
+
* hash( project + local-date + session_ordinal ) mod 2
|
|
35
|
+
* → 0 = ON, 1 = OFF
|
|
36
|
+
* The session_ordinal is the count of existing _ab_arms.jsonl rows for this
|
|
37
|
+
* project (0-indexed). Combined with project+date, this produces a balanced,
|
|
38
|
+
* non-predictable-by-time-of-day alternating pattern. Math.random is banned
|
|
39
|
+
* (repo rule). The hash is SHA-256 truncated to the first 8 hex digits.
|
|
40
|
+
*
|
|
41
|
+
* ESCAPE HATCH: AR_AB_FORCE=on|off overrides arm assignment for demos or
|
|
42
|
+
* emergencies. Forced sessions are flagged { forced: true } in the ledger
|
|
43
|
+
* and EXCLUDED from the outcome comparison in ab-report.mjs.
|
|
44
|
+
* AR_AB_FORCE without AR_AB_ENABLED=1 is a LOUD no-op: one stderr warning,
|
|
45
|
+
* no arm, no ledger row, injection unchanged (warnForcedWithoutEnabled).
|
|
46
|
+
*
|
|
47
|
+
* LEDGER: append-only <project>/corrections/_ab_arms.jsonl — TWO row kinds:
|
|
48
|
+
* assignment row (written by assignArm, counters zeroed):
|
|
49
|
+
* { ts, project, arm, forced, session_key, injected_count: 0, payload_tokens: 0 }
|
|
50
|
+
* result row (written by logABResult after the payload is built):
|
|
51
|
+
* { ts, kind: "result", session_key, injected_count, payload_tokens }
|
|
52
|
+
* readABArms merges result rows onto their assignment rows by session_key.
|
|
53
|
+
* NOTHING is ever rewritten in place — the append-only invariant is physical,
|
|
54
|
+
* not just conventional, so two concurrent same-project sessions can never
|
|
55
|
+
* clobber each other's counter fill (each appends its own result row).
|
|
56
|
+
*
|
|
57
|
+
* PAYLOAD SIGNAL: session_start result carries ab_arm: "on"|"off" so the
|
|
58
|
+
* transcript records which arm the session ran. The terse formatter appends
|
|
59
|
+
* a quiet trailing marker rather than a banner — we must NOT prime the agent
|
|
60
|
+
* to behave differently depending on the arm (experimenter effect).
|
|
61
|
+
*/
|
|
62
|
+
import * as crypto from "node:crypto";
|
|
63
|
+
import * as fs from "node:fs";
|
|
64
|
+
import * as path from "node:path";
|
|
65
|
+
import { getRoot } from "../types.js";
|
|
66
|
+
// ── Path helper ───────────────────────────────────────────────────────────────
|
|
67
|
+
function abArmsPath(project) {
|
|
68
|
+
// Reuse the corrections dir path — share the directory for co-location.
|
|
69
|
+
const safe = (project || "unnamed")
|
|
70
|
+
.replace(/[^a-zA-Z0-9_\-]/g, "-")
|
|
71
|
+
.replace(/^-+|-+$/g, "")
|
|
72
|
+
.slice(0, 100) || "unnamed";
|
|
73
|
+
const root = getRoot();
|
|
74
|
+
const resolved = path.join(root, "projects", safe, "corrections");
|
|
75
|
+
const rootSep = root.endsWith(path.sep) ? root : root + path.sep;
|
|
76
|
+
if (!resolved.startsWith(rootSep)) {
|
|
77
|
+
throw new Error(`Invalid project (path escape): ${project}`);
|
|
78
|
+
}
|
|
79
|
+
return path.join(resolved, "_ab_arms.jsonl");
|
|
80
|
+
}
|
|
81
|
+
// ── Ordinal counter ───────────────────────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* Count existing ASSIGNMENT rows for this project (0-based ordinal for the
|
|
84
|
+
* next session). Result rows (kind:"result") are NOT counted — they are
|
|
85
|
+
* counter fills, not sessions. Returns 0 if the file does not exist or is
|
|
86
|
+
* unreadable. Never throws.
|
|
87
|
+
*/
|
|
88
|
+
function countExistingRows(project) {
|
|
89
|
+
try {
|
|
90
|
+
const p = abArmsPath(project);
|
|
91
|
+
if (!fs.existsSync(p))
|
|
92
|
+
return 0;
|
|
93
|
+
const raw = fs.readFileSync(p, "utf-8");
|
|
94
|
+
let count = 0;
|
|
95
|
+
for (const line of raw.split("\n")) {
|
|
96
|
+
const trimmed = line.trim();
|
|
97
|
+
if (!trimmed)
|
|
98
|
+
continue;
|
|
99
|
+
try {
|
|
100
|
+
const row = JSON.parse(trimmed);
|
|
101
|
+
if (row.kind !== "result")
|
|
102
|
+
count++;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Malformed line — count it as an assignment slot so ordinals stay
|
|
106
|
+
// monotonic (never reuse a possibly-taken ordinal).
|
|
107
|
+
count++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return count;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ── Deterministic arm assignment ──────────────────────────────────────────────
|
|
117
|
+
/**
|
|
118
|
+
* computeArm(project, localDate, ordinal) → "on" | "off"
|
|
119
|
+
*
|
|
120
|
+
* SHA-256( project + "|" + localDate + "|" + ordinal ) → first 8 hex digits
|
|
121
|
+
* as uint32, mod 2 → 0 = "on", 1 = "off".
|
|
122
|
+
*
|
|
123
|
+
* Properties:
|
|
124
|
+
* - Deterministic: same inputs always yield the same arm (safe to re-run).
|
|
125
|
+
* - Balanced: over 100 synthetic sessions, yields ~50 ON / 50 OFF.
|
|
126
|
+
* - Not time-predictable: ordinal + project, not clock-parity, controls arm.
|
|
127
|
+
* - Zero Math.random.
|
|
128
|
+
*
|
|
129
|
+
* Exported for unit tests (pure function, no side effects).
|
|
130
|
+
*/
|
|
131
|
+
export function computeArm(project, localDate, ordinal) {
|
|
132
|
+
const input = `${project}|${localDate}|${ordinal}`;
|
|
133
|
+
const hex = crypto.createHash("sha256").update(input).digest("hex");
|
|
134
|
+
// Use first 8 hex chars (32 bits) to get a uint32, then mod 2.
|
|
135
|
+
const uint32 = parseInt(hex.slice(0, 8), 16);
|
|
136
|
+
return uint32 % 2 === 0 ? "on" : "off";
|
|
137
|
+
}
|
|
138
|
+
// ── Experiment enabled check ──────────────────────────────────────────────────
|
|
139
|
+
/**
|
|
140
|
+
* isExperimentEnabled() → true only when AR_AB_ENABLED=1.
|
|
141
|
+
*
|
|
142
|
+
* Default: false — all sessions get full injection (no degradation without
|
|
143
|
+
* explicit opt-in). The experiment owner sets AR_AB_ENABLED=1 when ready to
|
|
144
|
+
* start accumulating discordant-pair data.
|
|
145
|
+
*/
|
|
146
|
+
export function isExperimentEnabled() {
|
|
147
|
+
return process.env["AR_AB_ENABLED"] === "1";
|
|
148
|
+
}
|
|
149
|
+
// ── Forced override ───────────────────────────────────────────────────────────
|
|
150
|
+
/**
|
|
151
|
+
* getForcedArm() → "on" | "off" | null
|
|
152
|
+
*
|
|
153
|
+
* Reads AR_AB_FORCE env var. Validated to "on" or "off"; any other value
|
|
154
|
+
* is silently ignored (null = no override). Forced sessions are flagged in
|
|
155
|
+
* the ledger and excluded from ab-report comparisons.
|
|
156
|
+
*/
|
|
157
|
+
export function getForcedArm() {
|
|
158
|
+
const v = process.env["AR_AB_FORCE"];
|
|
159
|
+
if (v === "on" || v === "off")
|
|
160
|
+
return v;
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* warnForcedWithoutEnabled() → true if it warned.
|
|
165
|
+
*
|
|
166
|
+
* Orchestrator ruling 2026-07-03: AR_AB_FORCE without AR_AB_ENABLED=1 is a
|
|
167
|
+
* LOUD no-op — one stderr warning, no arm assignment, no ledger row, injection
|
|
168
|
+
* unchanged. Called by session_start on the disabled path so a misconfigured
|
|
169
|
+
* demo/emergency override never fails silently.
|
|
170
|
+
*/
|
|
171
|
+
export function warnForcedWithoutEnabled() {
|
|
172
|
+
if (getForcedArm() !== null && !isExperimentEnabled()) {
|
|
173
|
+
process.stderr.write("AR_AB_FORCE is set but AR_AB_ENABLED=1 is not — force ignored, experiment disabled\n");
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* assignArm(project) → { arm, forced, session_key }
|
|
180
|
+
*
|
|
181
|
+
* Side effects:
|
|
182
|
+
* - Appends an incomplete ledger row to _ab_arms.jsonl (injected_count and
|
|
183
|
+
* payload_tokens are 0 at assignment time — they are filled by logABResult
|
|
184
|
+
* after session_start resolves its payload).
|
|
185
|
+
* - Creates the corrections directory if it does not exist.
|
|
186
|
+
*
|
|
187
|
+
* Never throws: if the ledger write fails, the assignment still returns a
|
|
188
|
+
* valid arm so session_start can proceed. Errors are swallowed silently —
|
|
189
|
+
* a ledger gap is better than a broken orientation.
|
|
190
|
+
*
|
|
191
|
+
* Called only when isExperimentEnabled() is true.
|
|
192
|
+
*/
|
|
193
|
+
export function assignArm(project) {
|
|
194
|
+
const forced = getForcedArm();
|
|
195
|
+
const localDate = new Date().toLocaleDateString("sv"); // YYYY-MM-DD, local TZ
|
|
196
|
+
const ordinal = countExistingRows(project);
|
|
197
|
+
const arm = forced ?? computeArm(project, localDate, ordinal);
|
|
198
|
+
const session_key = `${project}/${localDate}/${ordinal}`;
|
|
199
|
+
// Append ledger row (with zeroed counters; logABResult fills them later).
|
|
200
|
+
try {
|
|
201
|
+
const p = abArmsPath(project);
|
|
202
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
203
|
+
const row = {
|
|
204
|
+
ts: new Date().toISOString(),
|
|
205
|
+
project,
|
|
206
|
+
arm,
|
|
207
|
+
forced: forced !== null,
|
|
208
|
+
session_key,
|
|
209
|
+
injected_count: 0, // filled by logABResult
|
|
210
|
+
payload_tokens: 0, // filled by logABResult
|
|
211
|
+
};
|
|
212
|
+
fs.appendFileSync(p, JSON.stringify(row) + "\n", "utf-8");
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Ledger write failure must never break session_start.
|
|
216
|
+
}
|
|
217
|
+
return { arm, forced: forced !== null, session_key };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* logABResult(project, session_key, injected_count, payload_tokens)
|
|
221
|
+
*
|
|
222
|
+
* APPENDS a result row keyed by session_key — never rewrites the ledger.
|
|
223
|
+
* The previous in-place last-row rewrite had a race: two concurrent sessions
|
|
224
|
+
* of the same project could zero each other's counter fill (review CRITICAL,
|
|
225
|
+
* fixed per orchestrator ruling 2026-07-03). With append-only result rows,
|
|
226
|
+
* each session's fill lands regardless of interleaving; readABArms merges
|
|
227
|
+
* result rows onto assignment rows by session_key (last result wins).
|
|
228
|
+
*
|
|
229
|
+
* No-ops when the ledger file does not exist (no assignment ever happened —
|
|
230
|
+
* a result row without its assignment row would be an orphan). Never throws.
|
|
231
|
+
*/
|
|
232
|
+
export function logABResult(project, session_key, injected_count, payload_tokens) {
|
|
233
|
+
try {
|
|
234
|
+
const p = abArmsPath(project);
|
|
235
|
+
if (!fs.existsSync(p))
|
|
236
|
+
return;
|
|
237
|
+
const row = {
|
|
238
|
+
ts: new Date().toISOString(),
|
|
239
|
+
kind: "result",
|
|
240
|
+
session_key,
|
|
241
|
+
injected_count,
|
|
242
|
+
payload_tokens,
|
|
243
|
+
};
|
|
244
|
+
fs.appendFileSync(p, JSON.stringify(row) + "\n", "utf-8");
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// Silent — never break session_start.
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// ── Read ledger (for ab-report.mjs) ──────────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* readABArms(project) → ABLedgerRow[]
|
|
253
|
+
*
|
|
254
|
+
* Reads _ab_arms.jsonl for a project and MERGES result rows onto their
|
|
255
|
+
* assignment rows by session_key (last result row wins when duplicates exist).
|
|
256
|
+
* Returns assignment rows only — result rows are counter fills, not sessions.
|
|
257
|
+
* Malformed lines are silently skipped (never throws). Returns [] when the
|
|
258
|
+
* file does not exist.
|
|
259
|
+
*/
|
|
260
|
+
export function readABArms(project) {
|
|
261
|
+
try {
|
|
262
|
+
const p = abArmsPath(project);
|
|
263
|
+
if (!fs.existsSync(p))
|
|
264
|
+
return [];
|
|
265
|
+
const raw = fs.readFileSync(p, "utf-8");
|
|
266
|
+
const assignments = [];
|
|
267
|
+
const results = new Map(); // session_key → last result row
|
|
268
|
+
for (const line of raw.split("\n")) {
|
|
269
|
+
const trimmed = line.trim();
|
|
270
|
+
if (!trimmed)
|
|
271
|
+
continue;
|
|
272
|
+
try {
|
|
273
|
+
const row = JSON.parse(trimmed);
|
|
274
|
+
if (row.kind === "result") {
|
|
275
|
+
results.set(row.session_key, row);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
assignments.push(row);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch { /* skip malformed */ }
|
|
282
|
+
}
|
|
283
|
+
return assignments.map((a) => {
|
|
284
|
+
const r = results.get(a.session_key);
|
|
285
|
+
return r
|
|
286
|
+
? { ...a, injected_count: r.injected_count, payload_tokens: r.payload_tokens }
|
|
287
|
+
: a;
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=ab-experiment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ab-experiment.js","sourceRoot":"","sources":["../../src/storage/ab-experiment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA4CtC,iFAAiF;AAEjF,SAAS,UAAU,CAAC,OAAe;IACjC,wEAAwE;IACxE,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;SAChC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;SAChC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;IAC9B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC;IACjE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAC/C,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAsB,CAAC;gBACrD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;oBAAE,KAAK,EAAE,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,mEAAmE;gBACnE,oDAAoD;gBACpD,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,SAAiB,EAAE,OAAe;IAC5E,MAAM,KAAK,GAAG,GAAG,OAAO,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,+DAA+D;IAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7C,OAAO,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AACzC,CAAC;AAED,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,GAAG,CAAC;AAC9C,CAAC;AAED,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB;IACtC,IAAI,YAAY,EAAE,KAAK,IAAI,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sFAAsF,CACvF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAUD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,uBAAuB;IAC9E,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAQ,MAAM,IAAI,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,GAAG,OAAO,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;IAEzD,0EAA0E;IAC1E,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,GAAG,GAAgB;YACvB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,OAAO;YACP,GAAG;YACH,MAAM,EAAE,MAAM,KAAK,IAAI;YACvB,WAAW;YACX,cAAc,EAAE,CAAC,EAAG,wBAAwB;YAC5C,cAAc,EAAE,CAAC,EAAG,wBAAwB;SAC7C,CAAC;QACF,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,EAAE,WAAW,EAAE,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,WAAmB,EACnB,cAAsB,EACtB,cAAsB;IAEtB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO;QAC9B,MAAM,GAAG,GAAgB;YACvB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,IAAI,EAAE,QAAQ;YACd,WAAW;YACX,cAAc;YACd,cAAc;SACf,CAAC;QACF,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,WAAW,GAAkB,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC,CAAC,gCAAgC;QAChF,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAoC,CAAC;gBACnE,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,GAA6B,CAAC,CAAC;gBAC9D,CAAC;qBAAM,CAAC;oBACN,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACrC,OAAO,CAAC;gBACN,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE;gBAC9E,CAAC,CAAC,CAAC,CAAC;QACR,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export type Tier = "personal" | "project";
|
|
2
2
|
/**
|
|
3
|
-
* The
|
|
4
|
-
* ("journal" | "palace" | "awareness" | "digest"). Awareness
|
|
5
|
-
* corrections-derived behavioral layer (Blind Spots), so it is
|
|
3
|
+
* The personal values reachable via the sync `store` union
|
|
4
|
+
* ("journal" | "palace" | "awareness" | "digest" | "corrections"). Awareness
|
|
5
|
+
* carries the corrections-derived behavioral layer (Blind Spots), so it is
|
|
6
|
+
* personal. `corrections` is also personal — it is a PERSONAL_PATH_MARKER
|
|
7
|
+
* (see below) and requires the double opt-in gate in supabase/sync.ts
|
|
8
|
+
* (sync_personal AND sync_corrections) before leaving the machine.
|
|
6
9
|
*
|
|
7
10
|
* NB (single-source guarantee): every member here MUST classifyStore() =>
|
|
8
11
|
* "personal" so the gate in supabase/sync.ts catches it. A unit test asserts
|
|
@@ -13,6 +16,7 @@ export declare const PERSONAL_STORES: ReadonlySet<string>;
|
|
|
13
16
|
* Classify a Supabase sync `store` (+ optional project) onto the privacy tier.
|
|
14
17
|
*
|
|
15
18
|
* - `awareness` store ⇒ personal (the behavioral layer leak we are gating).
|
|
19
|
+
* - `corrections` store ⇒ personal (PERSONAL_PATH_MARKER, double opt-in in sync.ts).
|
|
16
20
|
* - any write tagged with the `_global` project ⇒ personal (bootstrap writes
|
|
17
21
|
* palace under the `_global` sentinel).
|
|
18
22
|
* - everything else ⇒ project.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../../src/storage/classification.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;AAE1C
|
|
1
|
+
{"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../../src/storage/classification.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAAyC,CAAC;AAE1F;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,IAAI,CAIN;AAmBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -4,29 +4,33 @@
|
|
|
4
4
|
// personal-vs-project split. Pure, no IO.
|
|
5
5
|
//
|
|
6
6
|
// Two disjoint surfaces, by design:
|
|
7
|
-
// - classifyStore() covers the SYNC surface.
|
|
8
|
-
// palace writes) are
|
|
9
|
-
//
|
|
7
|
+
// - classifyStore() covers the SYNC surface. `awareness` and `corrections` (and
|
|
8
|
+
// `_global` palace writes) are personal through the Supabase `store` union.
|
|
9
|
+
// `corrections` requires the double opt-in (sync_personal AND sync_corrections)
|
|
10
|
+
// before it flows through syncToSupabase — it is not silently ignored.
|
|
10
11
|
// - classifyPath() covers the GIT/.gitignore surface — corrections,
|
|
11
|
-
// behavior-policies.json, the future `personal/` tier
|
|
12
|
-
// through syncToSupabase today.
|
|
12
|
+
// behavior-policies.json, the future `personal/` tier.
|
|
13
13
|
//
|
|
14
14
|
// Keeping these explicit means the moment someone adds a new personal artifact
|
|
15
15
|
// they register it HERE, and the sync gate + (future) .gitignore both honor it.
|
|
16
16
|
/**
|
|
17
|
-
* The
|
|
18
|
-
* ("journal" | "palace" | "awareness" | "digest"). Awareness
|
|
19
|
-
* corrections-derived behavioral layer (Blind Spots), so it is
|
|
17
|
+
* The personal values reachable via the sync `store` union
|
|
18
|
+
* ("journal" | "palace" | "awareness" | "digest" | "corrections"). Awareness
|
|
19
|
+
* carries the corrections-derived behavioral layer (Blind Spots), so it is
|
|
20
|
+
* personal. `corrections` is also personal — it is a PERSONAL_PATH_MARKER
|
|
21
|
+
* (see below) and requires the double opt-in gate in supabase/sync.ts
|
|
22
|
+
* (sync_personal AND sync_corrections) before leaving the machine.
|
|
20
23
|
*
|
|
21
24
|
* NB (single-source guarantee): every member here MUST classifyStore() =>
|
|
22
25
|
* "personal" so the gate in supabase/sync.ts catches it. A unit test asserts
|
|
23
26
|
* exactly that.
|
|
24
27
|
*/
|
|
25
|
-
export const PERSONAL_STORES = new Set(["awareness"]);
|
|
28
|
+
export const PERSONAL_STORES = new Set(["awareness", "corrections"]);
|
|
26
29
|
/**
|
|
27
30
|
* Classify a Supabase sync `store` (+ optional project) onto the privacy tier.
|
|
28
31
|
*
|
|
29
32
|
* - `awareness` store ⇒ personal (the behavioral layer leak we are gating).
|
|
33
|
+
* - `corrections` store ⇒ personal (PERSONAL_PATH_MARKER, double opt-in in sync.ts).
|
|
30
34
|
* - any write tagged with the `_global` project ⇒ personal (bootstrap writes
|
|
31
35
|
* palace under the `_global` sentinel).
|
|
32
36
|
* - everything else ⇒ project.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../../src/storage/classification.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,sEAAsE;AACtE,0CAA0C;AAC1C,EAAE;AACF,oCAAoC;AACpC
|
|
1
|
+
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../../src/storage/classification.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,sEAAsE;AACtE,0CAA0C;AAC1C,EAAE;AACF,oCAAoC;AACpC,kFAAkF;AAClF,gFAAgF;AAChF,oFAAoF;AACpF,2EAA2E;AAC3E,sEAAsE;AACtE,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAIhF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;AAE1F;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAyB,EACzB,IAA2B;IAE3B,IAAI,KAAK,KAAK,SAAS,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IACzE,IAAI,IAAI,EAAE,OAAO,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IACnD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,qBAAqB,GAAsB;IAC/C,eAAe;IACf,YAAY;IACZ,wBAAwB;IACxB,oBAAoB;IACpB,uEAAuE;IACvE,4EAA4E;IAC5E,2EAA2E;IAC3E,wBAAwB;IACxB,WAAW;CACZ,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,KAAK,MAAM,MAAM,IAAI,qBAAqB,EAAE,CAAC;QAC3C,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,UAAU,CAAC;IAClD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,KAAK,SAAS,CAAC;AAC5B,CAAC"}
|
|
@@ -4,6 +4,22 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Storage: ~/.agent-recall/projects/{project}/corrections/{date}-{slug}.json
|
|
6
6
|
*/
|
|
7
|
+
/**
|
|
8
|
+
* RD-1 (2026-07-13 workpacket §1, owner decisions 2026-07-14) — behavioral
|
|
9
|
+
* failure-class taxonomy for the cross-project recurrence join.
|
|
10
|
+
*
|
|
11
|
+
* Owner decisions (2026-07-14):
|
|
12
|
+
* - 9 values: the workpacket's 7 + `naming_violation`, which was the
|
|
13
|
+
* highest-phantom class in the 2026-07-14 taxonomy validation.
|
|
14
|
+
* - `failure_class` is AUTO-DERIVED AT CAPTURE (check.ts) via the keyword
|
|
15
|
+
* classifier in tools-logic/check-action.ts (tokenize/overlap grammar only —
|
|
16
|
+
* no new deps, no embeddings; the embedding-declined ruling stands).
|
|
17
|
+
* - Old records without the field are treated as `other` at READ time. The
|
|
18
|
+
* field is deliberately NOT defaulted in applyCorrectionDefaults — a default
|
|
19
|
+
* there would be persisted to disk by recordOutcome's read-modify-write and
|
|
20
|
+
* silently rewrite old files, which the owner ruled out.
|
|
21
|
+
*/
|
|
22
|
+
export type FailureClass = "wrong_ref" | "naming_violation" | "skipped_verify" | "scope_violation" | "model_dispatch" | "framing_error" | "confidential_leak" | "publish_gate" | "other";
|
|
7
23
|
export interface CorrectionRecord {
|
|
8
24
|
id: string;
|
|
9
25
|
date: string;
|
|
@@ -60,6 +76,12 @@ export interface CorrectionRecord {
|
|
|
60
76
|
superseded_by?: string;
|
|
61
77
|
merged_from?: string[];
|
|
62
78
|
stale?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* RD-1 — behavioral failure class (see FailureClass above). ADDITIVE +
|
|
81
|
+
* OPTIONAL: no capture-schema break. Stamped at capture time by check.ts;
|
|
82
|
+
* absent on pre-RD-1 records, which readers treat as "other" (never rewritten).
|
|
83
|
+
*/
|
|
84
|
+
failure_class?: FailureClass;
|
|
63
85
|
}
|
|
64
86
|
/**
|
|
65
87
|
* One discarded correction-candidate, appended to corrections/_rejected.jsonl
|
|
@@ -85,12 +107,36 @@ export interface CorrectionOutcome {
|
|
|
85
107
|
* the warning. "recurred" = same bug happened again.
|
|
86
108
|
* Wave 5 — "predicted" = predictCorrection fired this risk before the user
|
|
87
109
|
* corrected; "predict_hit" = that prediction later became a real recurrence.
|
|
110
|
+
*
|
|
111
|
+
* C3 (2026-07-03) — evidence-grounded verdict kinds:
|
|
112
|
+
* "triggered" = correction was consulted via check/check-action (authoritative
|
|
113
|
+
* trigger signal; sets up heeded/recurred classification at session-end)
|
|
114
|
+
* "not_triggered" = correction was NOT relevant this session (positive evidence of absence)
|
|
115
|
+
* "unknown" = no positive evidence for any verdict (NEW DEFAULT — replaces
|
|
116
|
+
* the pre-C3 default-heeded bias; see docs/proposals/c3-heed-instrumentation-design.md)
|
|
117
|
+
*
|
|
118
|
+
* Backward-compatibility: old readers that filter on the pre-C3 kind set skip
|
|
119
|
+
* these new kinds without error (confirmed: rmr-report.mjs, activity-feed.ts).
|
|
120
|
+
*/
|
|
121
|
+
kind: "retrieved" | "heeded" | "recurred" | "predicted" | "predict_hit" | "triggered" | "not_triggered" | "unknown";
|
|
122
|
+
/**
|
|
123
|
+
* SEMANTIC timestamp (ISO) — the day the outcome belongs to. The dream-audit
|
|
124
|
+
* path (C3b) deliberately backdates this to the audited day so day-bucketed
|
|
125
|
+
* readers (readOutcomesOnDate, listUnknownVerdicts, 1/day dedup) classify the
|
|
126
|
+
* verdict onto the session it describes.
|
|
88
127
|
*/
|
|
89
|
-
kind: "retrieved" | "heeded" | "recurred" | "predicted" | "predict_hit";
|
|
90
|
-
/** ISO timestamp */
|
|
91
128
|
at: string;
|
|
92
129
|
/** Free-text evidence — what made you decide. */
|
|
93
130
|
evidence?: string;
|
|
131
|
+
/**
|
|
132
|
+
* FORENSIC timestamp (ISO, C3b) — wall-clock time the event was physically
|
|
133
|
+
* appended. Set unconditionally by recordOutcome() on every call, never
|
|
134
|
+
* backdated. `at` (semantic) and `recorded_at` (forensic) diverge exactly
|
|
135
|
+
* when an event was recorded after the fact (e.g. the nightly dream audit).
|
|
136
|
+
* Optional for backward-compat: pre-C3b jsonl lines lack it; old readers
|
|
137
|
+
* ignore unknown fields.
|
|
138
|
+
*/
|
|
139
|
+
recorded_at?: string;
|
|
94
140
|
}
|
|
95
141
|
export interface CorrectionKPI {
|
|
96
142
|
project: string;
|
|
@@ -120,6 +166,19 @@ export interface CorrectionKPI {
|
|
|
120
166
|
rule: string;
|
|
121
167
|
last_seen: string;
|
|
122
168
|
}>;
|
|
169
|
+
/**
|
|
170
|
+
* C3 (2026-07-03) — evidence-grounded verdict coverage metrics.
|
|
171
|
+
* heed_rate = heeded / (heeded + recurred) — UNCHANGED formula, now evidence-grounded.
|
|
172
|
+
* verdict_coverage = (heeded + recurred + not_triggered) / retrieved_any (injected).
|
|
173
|
+
* "injected" = corrections with retrieved_count > 0 (ever retrieved).
|
|
174
|
+
* triggered_count = corrections with a "triggered" event in their outcomes.
|
|
175
|
+
* unknown_count = corrections with "unknown" outcome (no positive evidence).
|
|
176
|
+
* not_triggered_count = corrections confirmed NOT relevant in a session.
|
|
177
|
+
*/
|
|
178
|
+
verdict_coverage: number | null;
|
|
179
|
+
triggered_count: number;
|
|
180
|
+
unknown_count: number;
|
|
181
|
+
not_triggered_count: number;
|
|
123
182
|
}
|
|
124
183
|
/**
|
|
125
184
|
* Gate version stamp — bump whenever isLikelyRealCorrection's accept criteria
|
|
@@ -263,6 +322,15 @@ export declare function retractCorrection(project: string, id: string, reason?:
|
|
|
263
322
|
* Record an outcome event for a correction (retrieved / heeded / recurred).
|
|
264
323
|
* Appends to _outcomes.jsonl and also updates the correction JSON's counters
|
|
265
324
|
* + precision cache. Atomic per-write.
|
|
325
|
+
*
|
|
326
|
+
* C3b invariants:
|
|
327
|
+
* - `recorded_at` (forensic wall-clock timestamp) is stamped on EVERY event,
|
|
328
|
+
* unconditionally — callers cannot suppress or spoof it. The semantic `at`
|
|
329
|
+
* stays caller-controlled (the dream audit backdates it to the audited day).
|
|
330
|
+
* - `not_triggered` is ONLY producible via the dream-audit path: the evidence
|
|
331
|
+
* string MUST start with "dream-audit:". Any other producer throws. This is
|
|
332
|
+
* the core-level enforcement of the single-producer contract (the CLI's
|
|
333
|
+
* `ar outcomes record` is the one caller that adds the prefix).
|
|
266
334
|
*/
|
|
267
335
|
export declare function recordOutcome(outcome: CorrectionOutcome): void;
|
|
268
336
|
/**
|
|
@@ -328,8 +396,44 @@ export declare function readOutcomesBefore(project: string, isoCutoff: string):
|
|
|
328
396
|
* YYYY-MM-DD date; only its local-TZ day is used.
|
|
329
397
|
*/
|
|
330
398
|
export declare function readOutcomesOnDate(project: string, isoDate: string): Map<string, Set<CorrectionOutcome["kind"]>>;
|
|
399
|
+
/**
|
|
400
|
+
* Read all outcome events for a project from _outcomes.jsonl, bucketed by correction_id.
|
|
401
|
+
* Returns a Map: correction_id → Set of all outcome kinds ever recorded for that id.
|
|
402
|
+
* Never throws — returns an empty Map on any fs/parse error.
|
|
403
|
+
*
|
|
404
|
+
* Used by getCorrectionKPIs to compute C3 verdict-coverage metrics without
|
|
405
|
+
* duplicating the outcomes log parsing logic.
|
|
406
|
+
*/
|
|
407
|
+
export declare function readAllOutcomeKinds(project: string): Map<string, Set<CorrectionOutcome["kind"]>>;
|
|
408
|
+
/**
|
|
409
|
+
* C3b — Dream fallback audit: corrections retrieved on a given date whose
|
|
410
|
+
* verdict is still UNKNOWN (no heeded/recurred/not_triggered outcome).
|
|
411
|
+
*
|
|
412
|
+
* The dream job calls this to discover which corrections to audit overnight.
|
|
413
|
+
* A correction appears here when:
|
|
414
|
+
* - It was retrieved on `date` (has a `retrieved` outcome event on that day), AND
|
|
415
|
+
* - It has no heeded, recurred, or not_triggered outcome on that day.
|
|
416
|
+
*
|
|
417
|
+
* Returned records include the correction's journal file paths for that date
|
|
418
|
+
* so the dream agent can read context before recording a verdict.
|
|
419
|
+
*
|
|
420
|
+
* @param project - project slug
|
|
421
|
+
* @param date - YYYY-MM-DD local date to audit (default: yesterday)
|
|
422
|
+
*/
|
|
423
|
+
export interface UnknownVerdictCandidate {
|
|
424
|
+
id: string;
|
|
425
|
+
rule: string;
|
|
426
|
+
severity: "p0" | "p1";
|
|
427
|
+
tags: string[];
|
|
428
|
+
/** Local-TZ date on which the correction was retrieved (matches `date` param). */
|
|
429
|
+
retrieved_date: string;
|
|
430
|
+
/** Journal file paths for that date (may be empty if no journal written yet). */
|
|
431
|
+
journal_file_paths: string[];
|
|
432
|
+
}
|
|
433
|
+
export declare function listUnknownVerdicts(project: string, date?: string): UnknownVerdictCandidate[];
|
|
331
434
|
/**
|
|
332
435
|
* Aggregate KPIs over all corrections for a project — the "is this learning loop working?" view.
|
|
436
|
+
* C3 (2026-07-03): adds verdict_coverage, triggered_count, unknown_count, not_triggered_count.
|
|
333
437
|
*/
|
|
334
438
|
export declare function getCorrectionKPIs(project: string): CorrectionKPI;
|
|
335
439
|
export interface NoiseReview {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corrections.d.ts","sourceRoot":"","sources":["../../src/storage/corrections.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"corrections.d.ts","sourceRoot":"","sources":["../../src/storage/corrections.ts"],"names":[],"mappings":"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"}
|