@jmtrin/opencode-kevin 1.2.0 → 1.3.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/plugin/index.d.ts +4 -3
- package/dist/plugin/index.js +122 -113
- package/dist/plugin/native.d.ts +2 -2
- package/dist/plugin/native.js +2 -2
- package/package.json +56 -68
- package/LICENSE +0 -21
- package/README.md +0 -605
- package/dist/migrations/001_initial.sql +0 -92
- package/dist/migrations/002_indexes.sql +0 -14
- package/dist/migrations/003_v02_signal.sql +0 -58
- package/dist/migrations/004_v03_knowledge.sql +0 -138
- package/dist/migrations/005_v04_signal.sql +0 -57
- package/dist/migrations/006_v05_glassbox.sql +0 -118
- package/dist/migrations/007_v06_pull.sql +0 -145
- package/dist/migrations/008_v07_truth.sql +0 -124
- package/dist/migrations/009_v08_team.sql +0 -100
- package/dist/migrations/010_v09_native.sql +0 -78
- package/dist/migrations/011_v10_proven.sql +0 -69
- package/dist/migrations/012_v11_drift.sql +0 -24
- package/dist/plugin/Archiver.d.ts +0 -42
- package/dist/plugin/Archiver.js +0 -83
- package/dist/plugin/ArtifactWriter.d.ts +0 -93
- package/dist/plugin/ArtifactWriter.js +0 -291
- package/dist/plugin/CausalChain.d.ts +0 -22
- package/dist/plugin/CausalChain.js +0 -197
- package/dist/plugin/ChatBridge.d.ts +0 -41
- package/dist/plugin/ChatBridge.js +0 -103
- package/dist/plugin/ConflictDetector.d.ts +0 -35
- package/dist/plugin/ConflictDetector.js +0 -260
- package/dist/plugin/ContextInjector.d.ts +0 -222
- package/dist/plugin/ContextInjector.js +0 -533
- package/dist/plugin/ConventionMiner.d.ts +0 -35
- package/dist/plugin/ConventionMiner.js +0 -242
- package/dist/plugin/Curator.d.ts +0 -116
- package/dist/plugin/Curator.js +0 -324
- package/dist/plugin/DashboardHtml.d.ts +0 -5
- package/dist/plugin/DashboardHtml.js +0 -180
- package/dist/plugin/Feedback.d.ts +0 -67
- package/dist/plugin/Feedback.js +0 -120
- package/dist/plugin/HookLiveness.d.ts +0 -88
- package/dist/plugin/HookLiveness.js +0 -322
- package/dist/plugin/InjectionLedger.d.ts +0 -98
- package/dist/plugin/InjectionLedger.js +0 -295
- package/dist/plugin/LessonFixer.d.ts +0 -44
- package/dist/plugin/LessonFixer.js +0 -45
- package/dist/plugin/Materializer.d.ts +0 -83
- package/dist/plugin/Materializer.js +0 -181
- package/dist/plugin/MemoryService.d.ts +0 -360
- package/dist/plugin/MemoryService.js +0 -1242
- package/dist/plugin/Migrate.d.ts +0 -17
- package/dist/plugin/Migrate.js +0 -271
- package/dist/plugin/PatternMiner.d.ts +0 -49
- package/dist/plugin/PatternMiner.js +0 -132
- package/dist/plugin/QualityGate.d.ts +0 -124
- package/dist/plugin/QualityGate.js +0 -119
- package/dist/plugin/Reflector.d.ts +0 -91
- package/dist/plugin/Reflector.js +0 -307
- package/dist/plugin/RepoIdentity.d.ts +0 -124
- package/dist/plugin/RepoIdentity.js +0 -300
- package/dist/plugin/RepoTruth.d.ts +0 -80
- package/dist/plugin/RepoTruth.js +0 -599
- package/dist/plugin/Retrospective.d.ts +0 -17
- package/dist/plugin/Retrospective.js +0 -216
- package/dist/plugin/SharedLayer.d.ts +0 -159
- package/dist/plugin/SharedLayer.js +0 -462
- package/dist/plugin/Store.d.ts +0 -29
- package/dist/plugin/Store.js +0 -50
- package/dist/plugin/ToolCallObserver.d.ts +0 -32
- package/dist/plugin/ToolCallObserver.js +0 -201
- package/dist/plugin/TuiActions.d.ts +0 -43
- package/dist/plugin/TuiActions.js +0 -181
- package/dist/plugin/TuiSnapshots.d.ts +0 -24
- package/dist/plugin/TuiSnapshots.js +0 -158
- package/dist/plugin/columns.d.ts +0 -11
- package/dist/plugin/columns.js +0 -54
- package/dist/plugin/confidence.d.ts +0 -8
- package/dist/plugin/confidence.js +0 -34
- package/dist/plugin/contract.d.ts +0 -54
- package/dist/plugin/contract.js +0 -386
- package/dist/plugin/diff.d.ts +0 -8
- package/dist/plugin/diff.js +0 -182
- package/dist/plugin/escape.d.ts +0 -39
- package/dist/plugin/escape.js +0 -60
- package/dist/plugin/fingerprint.d.ts +0 -27
- package/dist/plugin/fingerprint.js +0 -73
- package/dist/plugin/inferability.d.ts +0 -32
- package/dist/plugin/inferability.js +0 -88
- package/dist/plugin/kevin_approve.d.ts +0 -34
- package/dist/plugin/kevin_approve.js +0 -52
- package/dist/plugin/kevin_audit.d.ts +0 -229
- package/dist/plugin/kevin_audit.js +0 -631
- package/dist/plugin/kevin_bench.d.ts +0 -10
- package/dist/plugin/kevin_bench.js +0 -82
- package/dist/plugin/kevin_conflicts.d.ts +0 -9
- package/dist/plugin/kevin_conflicts.js +0 -50
- package/dist/plugin/kevin_contract.d.ts +0 -8
- package/dist/plugin/kevin_contract.js +0 -59
- package/dist/plugin/kevin_doctor.d.ts +0 -62
- package/dist/plugin/kevin_doctor.js +0 -196
- package/dist/plugin/kevin_facts.d.ts +0 -42
- package/dist/plugin/kevin_facts.js +0 -36
- package/dist/plugin/kevin_forget.d.ts +0 -33
- package/dist/plugin/kevin_forget.js +0 -260
- package/dist/plugin/kevin_native.d.ts +0 -29
- package/dist/plugin/kevin_native.js +0 -79
- package/dist/plugin/kevin_propose.d.ts +0 -23
- package/dist/plugin/kevin_propose.js +0 -14
- package/dist/plugin/kevin_publish.d.ts +0 -38
- package/dist/plugin/kevin_publish.js +0 -18
- package/dist/plugin/kevin_why.d.ts +0 -23
- package/dist/plugin/kevin_why.js +0 -111
- package/dist/plugin/memory-format.d.ts +0 -20
- package/dist/plugin/memory-format.js +0 -59
- package/dist/plugin/metrics.d.ts +0 -97
- package/dist/plugin/metrics.js +0 -288
- package/dist/plugin/okf-export.d.ts +0 -3
- package/dist/plugin/okf-export.js +0 -134
- package/dist/plugin/okf-import.d.ts +0 -76
- package/dist/plugin/okf-import.js +0 -271
- package/dist/plugin/okf.d.ts +0 -107
- package/dist/plugin/okf.js +0 -303
- package/dist/plugin/perf.d.ts +0 -35
- package/dist/plugin/perf.js +0 -174
- package/dist/plugin/query-tokenizer.d.ts +0 -13
- package/dist/plugin/query-tokenizer.js +0 -133
- package/dist/plugin/redact.d.ts +0 -2
- package/dist/plugin/redact.js +0 -18
- package/dist/plugin/replay-types.d.ts +0 -69
- package/dist/plugin/replay-types.js +0 -156
- package/dist/plugin/replay.d.ts +0 -36
- package/dist/plugin/replay.js +0 -202
- package/dist/plugin/sqlite-adapter.d.ts +0 -12
- package/dist/plugin/sqlite-adapter.js +0 -81
- package/dist/plugin/time-ms.d.ts +0 -1
- package/dist/plugin/time-ms.js +0 -16
- package/dist/plugin/tui-types.d.ts +0 -59
- package/dist/plugin/tui-types.js +0 -4
- package/dist/plugin/tui.d.ts +0 -18
- package/dist/plugin/tui.js +0 -198
- package/dist/plugin/uuid.d.ts +0 -1
- package/dist/plugin/uuid.js +0 -50
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { uuidv7 } from "./uuid.js";
|
|
5
|
-
// v0.6.0 (K6-004 / plan §8.16) — exported so tests can assert that every
|
|
6
|
-
// METRIC_KEYS entry has a label by iterating the keys (not by counting).
|
|
7
|
-
export const METRIC_KEY_LABELS = {
|
|
8
|
-
tokens_injected_pre_prompt: "Tokens inyectados (pre-prompt)",
|
|
9
|
-
tokens_injected_compacting: "Tokens inyectados (compacting)",
|
|
10
|
-
reflections_throttled: "Reflexiones throttled",
|
|
11
|
-
duplicate_suppressions: "Supresiones por dedup",
|
|
12
|
-
tool_calls_deduped: "Tool calls deduped",
|
|
13
|
-
patterns_mined: "Patrones minados",
|
|
14
|
-
// BUG-014 — v0.4.0 keys (K4-006/K4-008/K4-025) had no Spanish labels,
|
|
15
|
-
// so the "## Métricas" section printed raw keys for them.
|
|
16
|
-
injections_total: "Inyecciones totales",
|
|
17
|
-
injections_effective: "Inyecciones efectivas",
|
|
18
|
-
injections_ineffective: "Inyecciones ineficaces",
|
|
19
|
-
patterns_promoted_new: "Patrones promovidos (nuevos)",
|
|
20
|
-
patterns_causal: "Patrones causales",
|
|
21
|
-
causal_links: "Enlaces causales",
|
|
22
|
-
memories_superseded: "Memorias superadas",
|
|
23
|
-
// v0.5.0 (K5-004 / plan §8.3) — the K5 metric keys need their own
|
|
24
|
-
// Spanish labels; the e2e BUG-014 regression test forbids raw-key
|
|
25
|
-
// fallback for any key in METRIC_KEYS.
|
|
26
|
-
injections_inconclusive: "Inyecciones sin conclusión",
|
|
27
|
-
injections_blocked_seen: "Inyecciones bloqueadas (ya vistas)",
|
|
28
|
-
injections_blocked_weak: "Inyecciones bloqueadas (débiles)",
|
|
29
|
-
injections_blocked_recurrence: "Inyecciones bloqueadas (recurrentes)",
|
|
30
|
-
injections_blocked_stale: "Inyecciones bloqueadas (obsoletas)",
|
|
31
|
-
injections_blocked_ignored: "Inyecciones bloqueadas (ignoradas)",
|
|
32
|
-
feedback_positive_total: "Feedback positivo total",
|
|
33
|
-
feedback_negative_total: "Feedback negativo total",
|
|
34
|
-
memories_archived: "Memorias archivadas",
|
|
35
|
-
// v0.6.0 (K6-004 / plan §8.16) — the K6 metric keys need their own
|
|
36
|
-
// Spanish labels; the audit regression forbids raw-key fallback for any
|
|
37
|
-
// key in METRIC_KEYS.
|
|
38
|
-
proposals_created: "Propuestas de curación creadas",
|
|
39
|
-
proposals_approved: "Propuestas aprobadas",
|
|
40
|
-
proposals_rejected: "Propuestas rechazadas",
|
|
41
|
-
artifact_writes_total: "Escrituras de artefacto (escritas)",
|
|
42
|
-
artifact_writes_noop: "Escrituras de artefacto (sin cambios)",
|
|
43
|
-
injections_blocked_confidence: "Inyecciones bloqueadas (confianza baja)",
|
|
44
|
-
// v0.7.0 (K7-004 / plan §8.3) — the K7 metric keys need their own
|
|
45
|
-
// Spanish labels; the audit regression forbids raw-key fallback for any
|
|
46
|
-
// key in METRIC_KEYS.
|
|
47
|
-
repo_facts_scanned: "Hechos del repositorio escaneados",
|
|
48
|
-
memories_contradicted: "Memorias contradichas",
|
|
49
|
-
conventions_mined: "Convenciones minadas",
|
|
50
|
-
conflicts_detected: "Conflictos detectados",
|
|
51
|
-
error_lessons_suppressed: "Lecciones de error suprimidas",
|
|
52
|
-
// v0.8.0 (K8-003 / plan §8.16) — the K8 metric keys need their own
|
|
53
|
-
// Spanish labels; the audit regression forbids raw-key fallback for any
|
|
54
|
-
// key in METRIC_KEYS.
|
|
55
|
-
shared_entries_total: "Entradas compartidas (totales)",
|
|
56
|
-
shared_entries_imported: "Entradas compartidas importadas",
|
|
57
|
-
shared_entries_exported: "Entradas compartidas exportadas",
|
|
58
|
-
okf_merge_folds: "Fusiones OKF (folds)",
|
|
59
|
-
rekey_events: "Re-keys de repositorio",
|
|
60
|
-
injections_from_shared: "Inyecciones desde la capa compartida",
|
|
61
|
-
// v0.9.0 (K9-003 / plan §8.16) — the K9 metric keys need their own
|
|
62
|
-
// Spanish labels; the audit regression forbids raw-key fallback for any
|
|
63
|
-
// key in METRIC_KEYS.
|
|
64
|
-
hook_fires_total: "Disparos de hooks (totales)",
|
|
65
|
-
hook_errors_total: "Errores de hooks",
|
|
66
|
-
hooks_dead_total: "Hooks muertos",
|
|
67
|
-
injections_suppressed_dead_hook: "Inyecciones suprimidas (hook muerto)",
|
|
68
|
-
native_registrations_total: "Registros nativos (totales)",
|
|
69
|
-
native_registration_failures: "Fallos de registro nativo",
|
|
70
|
-
// v1.0.0 (K10-005 / plan §6) — the six keys seeded by migration 011 section 3.
|
|
71
|
-
perf_samples_recorded: "Muestras de rendimiento registradas",
|
|
72
|
-
perf_budget_breaches: "Brechas de presupuesto de rendimiento",
|
|
73
|
-
dispose_fires_total: "Disparos de dispose (totales)",
|
|
74
|
-
dispose_misses_total: "Misses de dispose",
|
|
75
|
-
contract_digest_changes: "Cambios de digest de contrato",
|
|
76
|
-
bench_runs_total: "Ejecuciones de benchmark (totales)",
|
|
77
|
-
// v1.1.0 (K11-001 / plan §4) — drift metrics; labels required by BUG-014 regression.
|
|
78
|
-
bench_regression_failures: "Fallos de regresion de benchmark",
|
|
79
|
-
forget_requests_total: "Solicitudes de olvido totales",
|
|
80
|
-
forget_tombstones_published: "Tombstones publicados por olvido",
|
|
81
|
-
// v1.2.0 (K12-001 / plan §4) — surface metrics; labels required by BUG-014 regression.
|
|
82
|
-
tui_snapshots_flushed: "Snapshots TUI generados",
|
|
83
|
-
tui_actions_invoked: "Acciones TUI invocadas",
|
|
84
|
-
};
|
|
85
|
-
function originLabel(origin) {
|
|
86
|
-
if (origin === "reflector")
|
|
87
|
-
return "reflector";
|
|
88
|
-
if (origin === "pattern")
|
|
89
|
-
return "pattern";
|
|
90
|
-
if (origin === "retrospective")
|
|
91
|
-
return "retrospective";
|
|
92
|
-
return "agent";
|
|
93
|
-
}
|
|
94
|
-
export class Retrospective {
|
|
95
|
-
store;
|
|
96
|
-
memoryService;
|
|
97
|
-
retrospectivesDir;
|
|
98
|
-
metrics;
|
|
99
|
-
constructor(store, memoryService, options, metrics) {
|
|
100
|
-
this.store = store;
|
|
101
|
-
this.memoryService = memoryService;
|
|
102
|
-
this.retrospectivesDir =
|
|
103
|
-
options?.dir ?? join(homedir(), ".opencode-kevin", "retrospectives");
|
|
104
|
-
this.metrics = metrics ?? null;
|
|
105
|
-
}
|
|
106
|
-
async generate(sessionId) {
|
|
107
|
-
const existing = this.store
|
|
108
|
-
.prepare("SELECT file_path FROM retrospectives WHERE session_id = ?")
|
|
109
|
-
.get(sessionId);
|
|
110
|
-
if (existing?.file_path)
|
|
111
|
-
return existing.file_path;
|
|
112
|
-
const counts = this.store
|
|
113
|
-
.prepare(`SELECT
|
|
114
|
-
SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) AS success_count,
|
|
115
|
-
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) AS failure_count,
|
|
116
|
-
COUNT(*) AS total
|
|
117
|
-
FROM tool_calls WHERE session_id = ?`)
|
|
118
|
-
.get(sessionId);
|
|
119
|
-
const successCount = counts?.success_count ?? 0;
|
|
120
|
-
const failureCount = counts?.failure_count ?? 0;
|
|
121
|
-
const total = counts?.total ?? 0;
|
|
122
|
-
if (failureCount === 0)
|
|
123
|
-
return null;
|
|
124
|
-
const failedTools = this.store
|
|
125
|
-
.prepare(`SELECT tool, args_summary, error_type
|
|
126
|
-
FROM tool_calls
|
|
127
|
-
WHERE session_id = ? AND success = 0
|
|
128
|
-
ORDER BY ts ASC`)
|
|
129
|
-
.all(sessionId);
|
|
130
|
-
const lessons = this.store
|
|
131
|
-
.prepare(`SELECT id, content, origin, fingerprint, project_id
|
|
132
|
-
FROM memories
|
|
133
|
-
WHERE type = 'error' AND source_session = ?
|
|
134
|
-
ORDER BY created_at ASC`)
|
|
135
|
-
.all(sessionId);
|
|
136
|
-
const falsePositives = this.collectFalsePositives(sessionId, lessons);
|
|
137
|
-
const metricsSnapshot = this.metrics?.snapshot() ?? null;
|
|
138
|
-
const md = this.buildMarkdown(sessionId, total, successCount, failureCount, failedTools, lessons, falsePositives, metricsSnapshot);
|
|
139
|
-
mkdirSync(this.retrospectivesDir, { recursive: true });
|
|
140
|
-
const filePath = join(this.retrospectivesDir, `${sessionId}.md`);
|
|
141
|
-
writeFileSync(filePath, md, "utf8");
|
|
142
|
-
const id = uuidv7();
|
|
143
|
-
this.store
|
|
144
|
-
.prepare(`INSERT OR IGNORE INTO retrospectives
|
|
145
|
-
(id, session_id, ts, failure_count, success_count, lessons_count, file_path, metadata)
|
|
146
|
-
VALUES (?, ?, datetime('now'), ?, ?, ?, ?, ?)`)
|
|
147
|
-
.run(id, sessionId, failureCount, successCount, lessons.length, filePath, null);
|
|
148
|
-
return filePath;
|
|
149
|
-
}
|
|
150
|
-
collectFalsePositives(_sessionId, lessons) {
|
|
151
|
-
const reflectorLessons = lessons.filter((l) => l.origin === "reflector" && l.fingerprint !== null);
|
|
152
|
-
if (reflectorLessons.length === 0)
|
|
153
|
-
return [];
|
|
154
|
-
const result = [];
|
|
155
|
-
for (const lesson of reflectorLessons) {
|
|
156
|
-
const fp = lesson.fingerprint;
|
|
157
|
-
const row = this.store
|
|
158
|
-
.prepare(`SELECT COUNT(*) AS c FROM tool_calls
|
|
159
|
-
WHERE COALESCE(error_fingerprint, fingerprint) = ?
|
|
160
|
-
AND success = 0
|
|
161
|
-
AND (project_id IS ? OR (project_id IS NULL AND ? IS NULL))`)
|
|
162
|
-
.get(fp, lesson.project_id, lesson.project_id);
|
|
163
|
-
const recurrenceCount = row?.c ?? 0;
|
|
164
|
-
if (recurrenceCount > 0) {
|
|
165
|
-
result.push({
|
|
166
|
-
id: lesson.id,
|
|
167
|
-
content: lesson.content,
|
|
168
|
-
fingerprint: fp,
|
|
169
|
-
project_id: lesson.project_id,
|
|
170
|
-
recurrence_count: recurrenceCount,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
|
-
buildMarkdown(sessionId, total, successCount, failureCount, failedTools, lessons, falsePositives, metricsSnapshot) {
|
|
177
|
-
const lines = [];
|
|
178
|
-
lines.push(`# Retrospective — Session ${sessionId}`);
|
|
179
|
-
lines.push("");
|
|
180
|
-
lines.push("## Resumen");
|
|
181
|
-
lines.push(`- Tool calls: ${total} (${successCount} ok, ${failureCount} failed)`);
|
|
182
|
-
lines.push("");
|
|
183
|
-
lines.push("## Tools que fallaron");
|
|
184
|
-
for (const ft of failedTools) {
|
|
185
|
-
const et = ft.error_type ?? "unknown";
|
|
186
|
-
const summary = ft.args_summary ?? "";
|
|
187
|
-
lines.push(`- ${ft.tool} (${et}): ${summary}`);
|
|
188
|
-
}
|
|
189
|
-
lines.push("");
|
|
190
|
-
lines.push("## Lecciones generadas");
|
|
191
|
-
for (const lesson of lessons) {
|
|
192
|
-
const label = originLabel(lesson.origin);
|
|
193
|
-
lines.push(`- [${label}] ${lesson.content}`);
|
|
194
|
-
}
|
|
195
|
-
lines.push("");
|
|
196
|
-
lines.push("## False-positive recap");
|
|
197
|
-
if (falsePositives.length === 0) {
|
|
198
|
-
lines.push("- Ninguna lección reflector-sourceada recurrrió en tool_calls.");
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
for (const fp of falsePositives) {
|
|
202
|
-
lines.push(`- [reflector] ${fp.content} (fingerprint ${fp.fingerprint}, recurrencias: ${fp.recurrence_count})`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
lines.push("");
|
|
206
|
-
if (metricsSnapshot !== null) {
|
|
207
|
-
lines.push("## Métricas");
|
|
208
|
-
for (const [key, value] of Object.entries(metricsSnapshot)) {
|
|
209
|
-
const label = METRIC_KEY_LABELS[key] ?? key;
|
|
210
|
-
lines.push(`- ${label}: ${value}`);
|
|
211
|
-
}
|
|
212
|
-
lines.push("");
|
|
213
|
-
}
|
|
214
|
-
return lines.join("\n");
|
|
215
|
-
}
|
|
216
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import type { ArtifactWriter, WriteOutcome, WritePlan, WriteRequest } from "./ArtifactWriter.js";
|
|
2
|
-
import { type ParseResult } from "./okf.js";
|
|
3
|
-
export interface ImportReport {
|
|
4
|
-
path: string;
|
|
5
|
-
/** null when the file does not exist. */
|
|
6
|
-
fileHash: string | null;
|
|
7
|
-
parsed: number;
|
|
8
|
-
folded: number;
|
|
9
|
-
rejected: number;
|
|
10
|
-
/** rows inserted or updated in shared_entries. */
|
|
11
|
-
imported: number;
|
|
12
|
-
/** shared memories retired by an incoming tombstone. */
|
|
13
|
-
tombstoned: number;
|
|
14
|
-
/** true when fileHash matches the last okf_imports row. */
|
|
15
|
-
skipped: boolean;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* A planned (or applied) export (K8-020 / plan §5.5). The refusal is
|
|
19
|
-
* carried by the write plan itself — `outcome: "refused"` with both
|
|
20
|
-
* hashes audited — so a refused plan is indistinguishable from a
|
|
21
|
-
* written one until `outcome` is read.
|
|
22
|
-
*/
|
|
23
|
-
export interface ExportPlan {
|
|
24
|
-
path: string;
|
|
25
|
-
/** The whole-mode write request; applying re-plans through the single write funnel. */
|
|
26
|
-
request: WriteRequest;
|
|
27
|
-
/** The pure preview from planning time — diff and outcome, nothing written. */
|
|
28
|
-
write: WritePlan;
|
|
29
|
-
/** Entry ids in the merged corpus absent from the current file. */
|
|
30
|
-
entriesAdded: number;
|
|
31
|
-
/** Set by applyExport: the outcome of the actual write. */
|
|
32
|
-
applied?: WriteOutcome;
|
|
33
|
-
}
|
|
34
|
-
export declare class SharedLayer {
|
|
35
|
-
private readonly store;
|
|
36
|
-
private readonly repoId;
|
|
37
|
-
private readonly projectId;
|
|
38
|
-
private readonly version;
|
|
39
|
-
private readonly writer;
|
|
40
|
-
constructor(deps: {
|
|
41
|
-
store: StoreLike;
|
|
42
|
-
repoId: string;
|
|
43
|
-
projectId: string;
|
|
44
|
-
version: string;
|
|
45
|
-
writer: ArtifactWriter;
|
|
46
|
-
});
|
|
47
|
-
/**
|
|
48
|
-
* The single whole-file (mode `whole`) construction site in
|
|
49
|
-
* SharedLayer (K8-019 / K8-020, D8-08, asserted by
|
|
50
|
-
* tests/unit/single_write_path.test.ts): the OKF file is written
|
|
51
|
-
* through the ArtifactWriter's write funnel like every other file
|
|
52
|
-
* Kevin owns — there is no second write path.
|
|
53
|
-
*/
|
|
54
|
-
private wholeRequest;
|
|
55
|
-
/**
|
|
56
|
-
* Pure export planner (K8-020 / plan §5.5): reads the current file
|
|
57
|
-
* and merges the given local memories' projections into the corpus,
|
|
58
|
-
* producing a {@link WritePlan} — but writes nothing. Refusals are
|
|
59
|
-
* audited like any other write: `after === before`, both hashes
|
|
60
|
-
* recorded (D6-04). The refusal ladder, in the order the code
|
|
61
|
-
* evaluates it — file-side refusals first (not_okf, version_ahead,
|
|
62
|
-
* repo_mismatch), then candidate-side refusals in the loop order
|
|
63
|
-
* (line_too_long, below_floor, not_curated, unknown_entry), then
|
|
64
|
-
* too_many_entries and finally parse_damaged.
|
|
65
|
-
*/
|
|
66
|
-
planExport(memoryIds: string[], path: string): ExportPlan;
|
|
67
|
-
/**
|
|
68
|
-
* Tombstone-append planner (K8-020 / D8-09): emits one `tombstone`
|
|
69
|
-
* line per entry id, never deletes a line. The identifying triple is
|
|
70
|
-
* reconstructed from the local projection (a memory with
|
|
71
|
-
* `shared_entry_id`) so the line still passes parse's
|
|
72
|
-
* tamper-evident entry_id check; an id with no local projection is
|
|
73
|
-
* refused rather than emitting an invalid line.
|
|
74
|
-
*/
|
|
75
|
-
planTombstone(entryIds: string[], path: string): ExportPlan;
|
|
76
|
-
/**
|
|
77
|
-
* v0.8.0 (BUG-003) — heal a stale `#repo` header after a rekey.
|
|
78
|
-
* Rekey changes the scope the file is written under; a stale first
|
|
79
|
-
* line would make every later planExport/planTombstone refuse with
|
|
80
|
-
* repo_mismatch forever. Only the header line is replaced; the entry
|
|
81
|
-
* bytes, line endings and trailing newline are preserved. The write
|
|
82
|
-
* goes through the single funnel (D8-08). Returns true when the
|
|
83
|
-
* header was rewritten. Never throws: a missing or unreadable file
|
|
84
|
-
* is nothing to heal.
|
|
85
|
-
*/
|
|
86
|
-
healHeader(path: string, newRepoId: string): boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Apply a previously planned export: the write goes through the
|
|
89
|
-
* single write funnel (re-planning against the file's current state),
|
|
90
|
-
* and the outcome is recorded on the returned plan (K8-020).
|
|
91
|
-
*/
|
|
92
|
-
applyExport(plan: ExportPlan): ExportPlan;
|
|
93
|
-
/** Refusal plans are audited with both hashes (after === before). */
|
|
94
|
-
private refused;
|
|
95
|
-
/**
|
|
96
|
-
* Convert the requested local memories into OKF candidates and run
|
|
97
|
-
* the candidate-side refusals — line_too_long, below_floor,
|
|
98
|
-
* not_curated — in plan §5.5 order.
|
|
99
|
-
*/
|
|
100
|
-
private candidateEntries;
|
|
101
|
-
private setting;
|
|
102
|
-
private readWithFlag;
|
|
103
|
-
/**
|
|
104
|
-
* Read and parse the shared file. Total: a missing or unreadable
|
|
105
|
-
* file yields an empty ParseResult, never a throw (D8-14).
|
|
106
|
-
*/
|
|
107
|
-
read(path: string): ParseResult;
|
|
108
|
-
/**
|
|
109
|
-
* Idempotent and cheap to call (K8-016 / plan §5.5): hash the file
|
|
110
|
-
* first and return `{ skipped: true }` when the hash matches the
|
|
111
|
-
* most recent `okf_imports` row for this repo_id — the session.idle
|
|
112
|
-
* path costs one readFileSync plus one hash on an unchanged
|
|
113
|
-
* repository. A missing file is not an error: it returns
|
|
114
|
-
* `fileHash: null`, `parsed: 0`, and still writes an audit row.
|
|
115
|
-
*/
|
|
116
|
-
import(path: string): ImportReport;
|
|
117
|
-
private writeImportRow;
|
|
118
|
-
/**
|
|
119
|
-
* Project every imported entry into memories (K8-017 / plan §5.5,
|
|
120
|
-
* D8-10): a shared memory IS a memory, so getRelevant(), rankScore(),
|
|
121
|
-
* the five gates, truth_penalty, ConflictDetector and every audit
|
|
122
|
-
* rollup keep working unchanged.
|
|
123
|
-
*
|
|
124
|
-
* - assert entries: inserted once, never updated — re-importing an
|
|
125
|
-
* unchanged file must not create duplicates, bump evidence_count or
|
|
126
|
-
* move updated_at. `fingerprint` is deliberately left NULL: it is a
|
|
127
|
-
* different identity dimension (plan §3.3) and conflating it with
|
|
128
|
-
* `shared_entry_id` would make the v0.4.0 supersede path fire on
|
|
129
|
-
* unrelated entries (K8-017 acceptance).
|
|
130
|
-
* - tombstone entries: the ONE place in this codebase where the shared
|
|
131
|
-
* layer may write memories.status. This is NOT a v0.7.0 Principle 24
|
|
132
|
-
* violation: that principle forbids *contradiction* — a fuzzy
|
|
133
|
-
* inference — from writing status, and a tombstone is the opposite:
|
|
134
|
-
* an explicit, committed, human-reviewed decision that arrived
|
|
135
|
-
* through a pull request (D8-09, plan §5.5).
|
|
136
|
-
*
|
|
137
|
-
* Returns the number of memories archived by tombstones.
|
|
138
|
-
*/
|
|
139
|
-
private projectEntries;
|
|
140
|
-
/**
|
|
141
|
-
* Upsert every entry into shared_entries keyed on (repo_id,
|
|
142
|
-
* entry_id) — the UNIQUE index from migration 009 makes this an
|
|
143
|
-
* upsert rather than an append. `confidence` is the DERIVED value
|
|
144
|
-
* (deriveConfidence), never a transported float (plan §5.3).
|
|
145
|
-
* Returns the number of rows inserted or updated.
|
|
146
|
-
*/
|
|
147
|
-
private upsertEntries;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* The Store surface SharedLayer needs. Kept structural so tests can
|
|
151
|
-
* use the real Store without importing plugin internals.
|
|
152
|
-
*/
|
|
153
|
-
export interface StoreLike {
|
|
154
|
-
prepare(sql: string): {
|
|
155
|
-
get(...params: unknown[]): unknown;
|
|
156
|
-
all(...params: unknown[]): unknown[];
|
|
157
|
-
run(...params: unknown[]): void;
|
|
158
|
-
};
|
|
159
|
-
}
|