@jmtrin/opencode-kevin 0.5.0 → 0.7.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/README.md +268 -122
- package/dist/migrations/001_initial.sql +91 -91
- package/dist/migrations/003_v02_signal.sql +57 -57
- package/dist/migrations/004_v03_knowledge.sql +138 -138
- package/dist/migrations/005_v04_signal.sql +57 -57
- package/dist/migrations/006_v05_glassbox.sql +118 -118
- package/dist/migrations/007_v06_pull.sql +145 -0
- package/dist/migrations/008_v07_truth.sql +124 -0
- package/dist/plugin/Archiver.js +4 -3
- package/dist/plugin/Archiver.js.map +1 -1
- package/dist/plugin/ArtifactWriter.d.ts +50 -0
- package/dist/plugin/ArtifactWriter.js +240 -0
- package/dist/plugin/ArtifactWriter.js.map +1 -0
- package/dist/plugin/ConflictDetector.d.ts +35 -0
- package/dist/plugin/ConflictDetector.js +283 -0
- package/dist/plugin/ConflictDetector.js.map +1 -0
- package/dist/plugin/ContextInjector.d.ts +15 -0
- package/dist/plugin/ContextInjector.js +46 -11
- package/dist/plugin/ContextInjector.js.map +1 -1
- package/dist/plugin/ConventionMiner.d.ts +35 -0
- package/dist/plugin/ConventionMiner.js +243 -0
- package/dist/plugin/ConventionMiner.js.map +1 -0
- package/dist/plugin/Curator.d.ts +96 -0
- package/dist/plugin/Curator.js +283 -0
- package/dist/plugin/Curator.js.map +1 -0
- package/dist/plugin/Feedback.js +4 -3
- package/dist/plugin/Feedback.js.map +1 -1
- package/dist/plugin/Materializer.d.ts +59 -0
- package/dist/plugin/Materializer.js +237 -0
- package/dist/plugin/Materializer.js.map +1 -0
- package/dist/plugin/MemoryService.d.ts +37 -0
- package/dist/plugin/MemoryService.js +241 -20
- package/dist/plugin/MemoryService.js.map +1 -1
- package/dist/plugin/Migrate.js +51 -2
- package/dist/plugin/Migrate.js.map +1 -1
- package/dist/plugin/QualityGate.d.ts +15 -1
- package/dist/plugin/QualityGate.js +12 -0
- package/dist/plugin/QualityGate.js.map +1 -1
- package/dist/plugin/Reflector.js +13 -0
- package/dist/plugin/Reflector.js.map +1 -1
- package/dist/plugin/RepoTruth.d.ts +80 -0
- package/dist/plugin/RepoTruth.js +600 -0
- package/dist/plugin/RepoTruth.js.map +1 -0
- package/dist/plugin/Retrospective.d.ts +1 -0
- package/dist/plugin/Retrospective.js +20 -1
- package/dist/plugin/Retrospective.js.map +1 -1
- package/dist/plugin/capabilities.d.ts +15 -0
- package/dist/plugin/capabilities.js +42 -0
- package/dist/plugin/capabilities.js.map +1 -0
- package/dist/plugin/diff.d.ts +8 -0
- package/dist/plugin/diff.js +183 -0
- package/dist/plugin/diff.js.map +1 -0
- package/dist/plugin/index.d.ts +8 -1
- package/dist/plugin/index.js +354 -2
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/inferability.d.ts +32 -0
- package/dist/plugin/inferability.js +89 -0
- package/dist/plugin/inferability.js.map +1 -0
- package/dist/plugin/kevin_approve.d.ts +34 -0
- package/dist/plugin/kevin_approve.js +50 -0
- package/dist/plugin/kevin_approve.js.map +1 -0
- package/dist/plugin/kevin_audit.d.ts +87 -1
- package/dist/plugin/kevin_audit.js +190 -3
- package/dist/plugin/kevin_audit.js.map +1 -1
- package/dist/plugin/kevin_conflicts.d.ts +9 -0
- package/dist/plugin/kevin_conflicts.js +51 -0
- package/dist/plugin/kevin_conflicts.js.map +1 -0
- package/dist/plugin/kevin_facts.d.ts +42 -0
- package/dist/plugin/kevin_facts.js +37 -0
- package/dist/plugin/kevin_facts.js.map +1 -0
- package/dist/plugin/kevin_propose.d.ts +23 -0
- package/dist/plugin/kevin_propose.js +15 -0
- package/dist/plugin/kevin_propose.js.map +1 -0
- package/dist/plugin/kevin_publish.d.ts +38 -0
- package/dist/plugin/kevin_publish.js +19 -0
- package/dist/plugin/kevin_publish.js.map +1 -0
- package/dist/plugin/metrics.d.ts +12 -1
- package/dist/plugin/metrics.js +49 -0
- package/dist/plugin/metrics.js.map +1 -1
- package/dist/plugin/replay-types.d.ts +8 -8
- package/dist/plugin/replay.js +10 -0
- package/dist/plugin/replay.js.map +1 -1
- package/migrations/001_initial.sql +91 -91
- package/migrations/003_v02_signal.sql +57 -57
- package/migrations/004_v03_knowledge.sql +138 -138
- package/migrations/005_v04_signal.sql +57 -57
- package/migrations/006_v05_glassbox.sql +118 -118
- package/migrations/007_v06_pull.sql +145 -0
- package/migrations/008_v07_truth.sql +124 -0
- package/package.json +3 -2
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* K6-010 — v0.6.0 pull — deterministic error-knowledge classifier (plan §5.3).
|
|
3
|
+
*
|
|
4
|
+
* Pure module: no DB, no clock, no filesystem, no RNG. Fully unit-testable in
|
|
5
|
+
* isolation, and therefore fully unit-tested.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The `Reflector` dispatch surface of §3.4, restated as data: error codes whose
|
|
9
|
+
* payload IS the knowledge — no project-specific interpretation required.
|
|
10
|
+
*/
|
|
11
|
+
export const SELF_DESCRIBING_CODES = new Set([
|
|
12
|
+
"TS2304",
|
|
13
|
+
"TS2307",
|
|
14
|
+
"TS2322",
|
|
15
|
+
"TS2339",
|
|
16
|
+
"TS2305",
|
|
17
|
+
"TS2552",
|
|
18
|
+
"TS2740",
|
|
19
|
+
"TS6133",
|
|
20
|
+
"TS18047",
|
|
21
|
+
"E0433",
|
|
22
|
+
"E0432",
|
|
23
|
+
"command_not_found",
|
|
24
|
+
]);
|
|
25
|
+
/**
|
|
26
|
+
* Rule 4 detector — deliberately conservative. Errs toward `non_inferable`,
|
|
27
|
+
* because a false `inferable` silently withholds real knowledge from curation
|
|
28
|
+
* forever, while a false `non_inferable` costs one line a human rejects.
|
|
29
|
+
*/
|
|
30
|
+
const NPM_RUN_RE = /\b(?:npm|pnpm|yarn|bun)(?:\s+(?:run|exec))?\s+[\w@:/-]+/;
|
|
31
|
+
const RELATIVE_PATH_RE = /\.{1,2}\/[\w./@-]+/;
|
|
32
|
+
const FLAG_RE = /(?:^|\s)--[\w-]+/;
|
|
33
|
+
const FILE_EXT_RE = /\b[\w./@-]+\.[a-zA-Z][a-zA-Z0-9]{0,7}\b/;
|
|
34
|
+
function namesProjectSpecific(content) {
|
|
35
|
+
return (NPM_RUN_RE.test(content) ||
|
|
36
|
+
RELATIVE_PATH_RE.test(content) ||
|
|
37
|
+
FLAG_RE.test(content) ||
|
|
38
|
+
FILE_EXT_RE.test(content));
|
|
39
|
+
}
|
|
40
|
+
function dispatchCode(metadata) {
|
|
41
|
+
if (metadata === null || typeof metadata !== "object")
|
|
42
|
+
return null;
|
|
43
|
+
const dispatch = metadata.dispatch;
|
|
44
|
+
if (dispatch === null || typeof dispatch !== "object")
|
|
45
|
+
return null;
|
|
46
|
+
const code = dispatch.code;
|
|
47
|
+
return typeof code === "string" && code.length > 0 ? code : null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rules from plan §5.3, evaluated in order — the ordering is the specification:
|
|
51
|
+
*
|
|
52
|
+
* 1. `type` ∈ decision / rule / solution → `non_inferable`
|
|
53
|
+
* 2. `type` = pattern → `non_inferable`
|
|
54
|
+
* 3. `type` = error and `metadata.dispatch.code` ∈ SELF_DESCRIBING_CODES → `inferable`
|
|
55
|
+
* 4. `type` = error and content names a project-specific path, script or flag → `non_inferable`
|
|
56
|
+
* 5. otherwise → `unknown`
|
|
57
|
+
*
|
|
58
|
+
* Rule 4 beats rule 3: a TS2304 is inferable, but "TS2304 on
|
|
59
|
+
* `./scripts/gen-routes.ts` because the generator must run before tsc" is not —
|
|
60
|
+
* the project-specific script name is the payload, not the code. Rule 3's
|
|
61
|
+
* condition (code membership) is evaluated first for the bare case; rule 4
|
|
62
|
+
* catches what rule 3 does not.
|
|
63
|
+
*/
|
|
64
|
+
export function classify(memory) {
|
|
65
|
+
// Rule 1 — authored knowledge is never re-derived.
|
|
66
|
+
if (memory.type === "decision" ||
|
|
67
|
+
memory.type === "rule" ||
|
|
68
|
+
memory.type === "solution") {
|
|
69
|
+
return "non_inferable";
|
|
70
|
+
}
|
|
71
|
+
// Rule 2 — a mined sequence is project-specific by construction.
|
|
72
|
+
if (memory.type === "pattern") {
|
|
73
|
+
return "non_inferable";
|
|
74
|
+
}
|
|
75
|
+
if (memory.type === "error") {
|
|
76
|
+
const code = dispatchCode(memory.metadata);
|
|
77
|
+
// Rule 4 — content naming a project-specific path, script or flag.
|
|
78
|
+
if (namesProjectSpecific(memory.content)) {
|
|
79
|
+
return "non_inferable";
|
|
80
|
+
}
|
|
81
|
+
// Rule 3 — a bare self-describing code is inferable.
|
|
82
|
+
if (code !== null && SELF_DESCRIBING_CODES.has(code)) {
|
|
83
|
+
return "inferable";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Rule 5.
|
|
87
|
+
return "unknown";
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=inferability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inferability.js","sourceRoot":"","sources":["../../plugin/inferability.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAwB,IAAI,GAAG,CAAC;IACjE,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,OAAO;IACP,mBAAmB;CACnB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,GAAG,yDAAyD,CAAC;AAC7E,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAC9C,MAAM,OAAO,GAAG,kBAAkB,CAAC;AACnC,MAAM,WAAW,GAAG,yCAAyC,CAAC;AAE9D,SAAS,oBAAoB,CAAC,OAAe;IAC5C,OAAO,CACN,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;QACxB,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QACrB,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CACzB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,QAAiB;IACtC,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,QAAQ,GAAI,QAAmC,CAAC,QAAQ,CAAC;IAC/D,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,IAAI,GAAI,QAA+B,CAAC,IAAI,CAAC;IACnD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ,CAAC,MAIxB;IACA,mDAAmD;IACnD,IACC,MAAM,CAAC,IAAI,KAAK,UAAU;QAC1B,MAAM,CAAC,IAAI,KAAK,MAAM;QACtB,MAAM,CAAC,IAAI,KAAK,UAAU,EACzB,CAAC;QACF,OAAO,eAAe,CAAC;IACxB,CAAC;IACD,iEAAiE;IACjE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,eAAe,CAAC;IACxB,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3C,mEAAmE;QACnE,IAAI,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,OAAO,eAAe,CAAC;QACxB,CAAC;QACD,qDAAqD;QACrD,IAAI,IAAI,KAAK,IAAI,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,OAAO,WAAW,CAAC;QACpB,CAAC;IACF,CAAC;IACD,UAAU;IACV,OAAO,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ArtifactWriter } from "./ArtifactWriter.js";
|
|
2
|
+
import type { Curator, ProposalStatus } from "./Curator.js";
|
|
3
|
+
import type { MemoryService } from "./MemoryService.js";
|
|
4
|
+
import type { Store } from "./Store.js";
|
|
5
|
+
import type { Metrics } from "./metrics.js";
|
|
6
|
+
/**
|
|
7
|
+
* K6-014 — v0.6.0 pull — `kevin_approve` tool logic.
|
|
8
|
+
*
|
|
9
|
+
* The ONLY code path in the entire plugin that may call
|
|
10
|
+
* `ArtifactWriter`'s apply method (D6-01; enforced by
|
|
11
|
+
* tests/unit/single_write_path.test.ts).
|
|
12
|
+
*
|
|
13
|
+
* There is deliberately no "trusted mode" and no flag that skips the human:
|
|
14
|
+
* the approval gate is the release's entire safety model.
|
|
15
|
+
*/
|
|
16
|
+
export interface ApproveArgs {
|
|
17
|
+
readonly proposalId: string;
|
|
18
|
+
readonly decision: "approve" | "reject";
|
|
19
|
+
}
|
|
20
|
+
export type ApproveResult = {
|
|
21
|
+
readonly proposalId: string;
|
|
22
|
+
readonly status: "rejected";
|
|
23
|
+
} | {
|
|
24
|
+
readonly proposalId: string;
|
|
25
|
+
readonly status: "applied";
|
|
26
|
+
readonly outcome: string;
|
|
27
|
+
readonly curated: number;
|
|
28
|
+
} | {
|
|
29
|
+
readonly error: "not_found" | "not_pending";
|
|
30
|
+
readonly proposalId: string;
|
|
31
|
+
readonly status?: ProposalStatus;
|
|
32
|
+
readonly message: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function kevinApprove(store: Store, memoryService: MemoryService, curator: Curator, writer: ArtifactWriter, metrics: Metrics | null, args: ApproveArgs): ApproveResult;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export function kevinApprove(store, memoryService, curator, writer, metrics, args) {
|
|
2
|
+
const row = store
|
|
3
|
+
.prepare(`SELECT id, kind, target_path, proposed_text, memory_id, status
|
|
4
|
+
FROM curation_proposals WHERE id = ?`)
|
|
5
|
+
.get(args.proposalId);
|
|
6
|
+
if (!row) {
|
|
7
|
+
return {
|
|
8
|
+
error: "not_found",
|
|
9
|
+
proposalId: args.proposalId,
|
|
10
|
+
message: `No proposal with id "${args.proposalId}".`,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (row.status !== "pending") {
|
|
14
|
+
return {
|
|
15
|
+
error: "not_pending",
|
|
16
|
+
proposalId: args.proposalId,
|
|
17
|
+
status: row.status,
|
|
18
|
+
message: `Proposal "${args.proposalId}" is ${row.status}, not pending.`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (args.decision === "reject") {
|
|
22
|
+
curator.transition(args.proposalId, "reject");
|
|
23
|
+
metrics?.incr("proposals_rejected", 1);
|
|
24
|
+
return { proposalId: args.proposalId, status: "rejected" };
|
|
25
|
+
}
|
|
26
|
+
// approve → apply → applied (plan §5.5). The proposed_text is re-planned
|
|
27
|
+
// at approval time against the file as it is now; apply() is atomic and
|
|
28
|
+
// audits every outcome including noop. The disk write happens BEFORE the
|
|
29
|
+
// state transitions: if apply() throws (e.g. a filesystem error), the
|
|
30
|
+
// proposal is still 'pending' and the human can retry or reject — a
|
|
31
|
+
// row stuck in 'approved' with no file written would be a dead end,
|
|
32
|
+
// since kevin_approve only accepts pending rows.
|
|
33
|
+
const plan = writer.plan(row.target_path, row.proposed_text);
|
|
34
|
+
const outcome = writer.apply(plan, args.proposalId);
|
|
35
|
+
curator.transition(args.proposalId, "approve");
|
|
36
|
+
curator.transition(args.proposalId, "apply");
|
|
37
|
+
const memoryIds = row.memory_id.split(",").filter((s) => s.length > 0);
|
|
38
|
+
const curated = memoryService.markCurated(memoryIds, sqliteNow());
|
|
39
|
+
metrics?.incr("proposals_approved", 1);
|
|
40
|
+
return {
|
|
41
|
+
proposalId: args.proposalId,
|
|
42
|
+
status: "applied",
|
|
43
|
+
outcome,
|
|
44
|
+
curated,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function sqliteNow() {
|
|
48
|
+
return new Date().toISOString().slice(0, 19).replace("T", " ");
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=kevin_approve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kevin_approve.js","sourceRoot":"","sources":["../../plugin/kevin_approve.ts"],"names":[],"mappings":"AAiDA,MAAM,UAAU,YAAY,CAC3B,KAAY,EACZ,aAA4B,EAC5B,OAAgB,EAChB,MAAsB,EACtB,OAAuB,EACvB,IAAiB;IAEjB,MAAM,GAAG,GAAG,KAAK;SACf,OAAO,CACP;yCACsC,CACtC;SACA,GAAG,CAAC,IAAI,CAAC,UAAU,CAA4B,CAAC;IAClD,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;YACN,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,wBAAwB,IAAI,CAAC,UAAU,IAAI;SACpD,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;YACN,KAAK,EAAE,aAAa;YACpB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,aAAa,IAAI,CAAC,UAAU,QAAQ,GAAG,CAAC,MAAM,gBAAgB;SACvE,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;QACvC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC5D,CAAC;IAED,yEAAyE;IACzE,wEAAwE;IACxE,yEAAyE;IACzE,sEAAsE;IACtE,oEAAoE;IACpE,oEAAoE;IACpE,iDAAiD;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC/C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAClE,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;IACvC,OAAO;QACN,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,SAAS;QACjB,OAAO;QACP,OAAO;KACP,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IACjB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Store } from "./Store.js";
|
|
2
|
+
import type { Capabilities } from "./capabilities.js";
|
|
2
3
|
import type { Metrics } from "./metrics.js";
|
|
3
4
|
/**
|
|
4
5
|
* v0.5.0 (K5-016 / plan §5.7) — `kevin_audit`.
|
|
@@ -12,6 +13,19 @@ import type { Metrics } from "./metrics.js";
|
|
|
12
13
|
* Pre-006 databases degrade gracefully: any block that fails (missing column
|
|
13
14
|
* or table) falls back to its zero value and the report is flagged
|
|
14
15
|
* `"partial": true` instead of throwing.
|
|
16
|
+
*
|
|
17
|
+
* v0.6.0 (K6-023 / plan §5.8) — the `channels` and `curation` blocks are the
|
|
18
|
+
* release's own scoreboard. On a pre-007 database they are **omitted** (not
|
|
19
|
+
* zero-valued) and `"partial": true` is set: a report that cannot answer
|
|
20
|
+
* "do the pull channels beat push?" must say so rather than suggest it can.
|
|
21
|
+
*
|
|
22
|
+
* v0.7.0 (K7-019 / plan §5.3, K7-006) — the `truth` block is project-scoped:
|
|
23
|
+
* facts scanned, penalized memory count and the truncation flag for the
|
|
24
|
+
* current project. It is omitted (and `"partial": true` set) on a pre-008
|
|
25
|
+
* database, exactly like the conflicts block. `facts_scanned` counts every
|
|
26
|
+
* `repo_facts` row for the project — the same COUNT(*) semantics as the
|
|
27
|
+
* `repo_facts_scanned` metric — while `truncated` reports the scan cap
|
|
28
|
+
* separately, mirroring `kevin_facts`.
|
|
15
29
|
*/
|
|
16
30
|
export interface AuditReport {
|
|
17
31
|
memories: {
|
|
@@ -44,6 +58,78 @@ export interface AuditReport {
|
|
|
44
58
|
compacting: number;
|
|
45
59
|
};
|
|
46
60
|
settings: Record<string, string>;
|
|
61
|
+
conflicts?: {
|
|
62
|
+
by_kind: Record<string, number>;
|
|
63
|
+
by_status: Record<string, number>;
|
|
64
|
+
};
|
|
65
|
+
truth?: TruthReport;
|
|
66
|
+
mix?: {
|
|
67
|
+
injected_by_type: Record<string, number>;
|
|
68
|
+
injected_total: number;
|
|
69
|
+
non_error_injected: number;
|
|
70
|
+
non_error_share: number;
|
|
71
|
+
precision_error: number;
|
|
72
|
+
precision_non_error: number;
|
|
73
|
+
meets_exit_criterion: boolean;
|
|
74
|
+
reason?: "immature_db";
|
|
75
|
+
};
|
|
76
|
+
channels?: ChannelReport;
|
|
77
|
+
curation?: CurationReport;
|
|
47
78
|
partial: boolean;
|
|
48
79
|
}
|
|
49
|
-
|
|
80
|
+
/**
|
|
81
|
+
* v0.6.0 (K6-023 / plan §5.8) — three-channel comparison on the same axes.
|
|
82
|
+
* `skill_emission` / `reference_emission` distinguish the three states a
|
|
83
|
+
* channel can be in: "unavailable" (v1 host, no domain on the plugin input),
|
|
84
|
+
* "off" (capable host, setting '0'), "on" (capable host, setting '1').
|
|
85
|
+
* Collapsing "unavailable" and "off" would make "my host is too old"
|
|
86
|
+
* indistinguishable from "I turned it off".
|
|
87
|
+
*/
|
|
88
|
+
export type EmissionState = "on" | "off" | "unavailable";
|
|
89
|
+
export interface ChannelReport {
|
|
90
|
+
push: {
|
|
91
|
+
tokens_pre_prompt: number;
|
|
92
|
+
tokens_compacting: number;
|
|
93
|
+
injections_total: number;
|
|
94
|
+
precision_rate: number;
|
|
95
|
+
coverage_rate: number;
|
|
96
|
+
budget_tokens: number;
|
|
97
|
+
};
|
|
98
|
+
pull: {
|
|
99
|
+
proposals_created: number;
|
|
100
|
+
proposals_approved: number;
|
|
101
|
+
proposals_rejected: number;
|
|
102
|
+
artifact_writes_total: number;
|
|
103
|
+
artifact_writes_noop: number;
|
|
104
|
+
references_registered: number;
|
|
105
|
+
skills_registered: number;
|
|
106
|
+
skill_emission: EmissionState;
|
|
107
|
+
reference_emission: EmissionState;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export interface CurationReport {
|
|
111
|
+
eligible: number;
|
|
112
|
+
curated: number;
|
|
113
|
+
inferable: number;
|
|
114
|
+
non_inferable: number;
|
|
115
|
+
unknown: number;
|
|
116
|
+
proposals_by_status: Record<string, number>;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* v0.7.0 (K7-019 / plan §5.3) — the Project Truth block. The same shape
|
|
120
|
+
* `kevin_facts` exposes: `facts_scanned` counts every repo_facts row for the
|
|
121
|
+
* project (COUNT(*) semantics, matching the `repo_facts_scanned` metric),
|
|
122
|
+
* `penalized_memories` counts memories with `truth_penalty > 0`, and
|
|
123
|
+
* `truncated` reports the 500-fact scan cap from the `_truncated` marker row.
|
|
124
|
+
*/
|
|
125
|
+
export interface TruthReport {
|
|
126
|
+
facts_scanned: number;
|
|
127
|
+
penalized_memories: number;
|
|
128
|
+
truncated: {
|
|
129
|
+
is_truncated: true;
|
|
130
|
+
count: number;
|
|
131
|
+
} | {
|
|
132
|
+
is_truncated: false;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export declare function buildAudit(store: Store, metrics: Metrics, capabilities?: Capabilities, projectId?: string): AuditReport;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { effectivePrePromptCap } from "./ContextInjector.js";
|
|
2
|
+
const ALL_FALSE_CAPABILITIES = {
|
|
3
|
+
skills: false,
|
|
4
|
+
references: false,
|
|
5
|
+
apiVersion: null,
|
|
6
|
+
};
|
|
1
7
|
function groupCounts(store, column) {
|
|
2
8
|
const rows = store
|
|
3
9
|
.prepare(`SELECT ${column} AS k, COUNT(*) AS n FROM memories GROUP BY ${column}`)
|
|
@@ -8,11 +14,11 @@ function groupCounts(store, column) {
|
|
|
8
14
|
}
|
|
9
15
|
return out;
|
|
10
16
|
}
|
|
11
|
-
function scalar(store, sql) {
|
|
12
|
-
const row = store.prepare(sql).get();
|
|
17
|
+
function scalar(store, sql, ...params) {
|
|
18
|
+
const row = store.prepare(sql).get(...params);
|
|
13
19
|
return row.n ?? 0;
|
|
14
20
|
}
|
|
15
|
-
export function buildAudit(store, metrics) {
|
|
21
|
+
export function buildAudit(store, metrics, capabilities = ALL_FALSE_CAPABILITIES, projectId) {
|
|
16
22
|
let partial = false;
|
|
17
23
|
// Memories block: `total` + the three GROUP BYs are pre-006 safe; the
|
|
18
24
|
// lifecycle counters need the 006 columns and fall back separately.
|
|
@@ -128,6 +134,182 @@ export function buildAudit(store, metrics) {
|
|
|
128
134
|
catch {
|
|
129
135
|
partial = true;
|
|
130
136
|
}
|
|
137
|
+
// v0.6.0 (K6-023 / plan §5.8) — channels + curation. Both blocks are
|
|
138
|
+
// gated on migration 007's schema: on a pre-007 database they are
|
|
139
|
+
// OMITTED (not zero-valued) and `partial` is set, so the release's
|
|
140
|
+
// scoreboard is never presented as computed when it cannot be.
|
|
141
|
+
let channels;
|
|
142
|
+
let curation;
|
|
143
|
+
let conflicts;
|
|
144
|
+
let mix;
|
|
145
|
+
let hasSchema007 = false;
|
|
146
|
+
try {
|
|
147
|
+
store.prepare("SELECT 1 FROM curation_proposals LIMIT 1").get();
|
|
148
|
+
hasSchema007 = true;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
hasSchema007 = false;
|
|
152
|
+
}
|
|
153
|
+
if (hasSchema007) {
|
|
154
|
+
try {
|
|
155
|
+
const emission = (capable, key) => {
|
|
156
|
+
if (!capable)
|
|
157
|
+
return "unavailable";
|
|
158
|
+
return settings[key] === "1" ? "on" : "off";
|
|
159
|
+
};
|
|
160
|
+
const registered = (key) => {
|
|
161
|
+
const row = store
|
|
162
|
+
.prepare("SELECT value FROM kevin_metrics WHERE key = ?")
|
|
163
|
+
.get(key);
|
|
164
|
+
return row?.value ?? 0;
|
|
165
|
+
};
|
|
166
|
+
channels = {
|
|
167
|
+
push: {
|
|
168
|
+
tokens_pre_prompt: metrics.get("tokens_injected_pre_prompt"),
|
|
169
|
+
tokens_compacting: metrics.get("tokens_injected_compacting"),
|
|
170
|
+
injections_total: metrics.get("injections_total"),
|
|
171
|
+
precision_rate: metrics.precisionRate(),
|
|
172
|
+
coverage_rate: metrics.coverageRate(),
|
|
173
|
+
// The EFFECTIVE cap (K6-021 clamp semantics), not the raw
|
|
174
|
+
// setting: the channel comparison must use the budget the
|
|
175
|
+
// push channel actually charges against.
|
|
176
|
+
budget_tokens: effectivePrePromptCap(settings.pre_prompt_budget_tokens),
|
|
177
|
+
},
|
|
178
|
+
pull: {
|
|
179
|
+
proposals_created: metrics.get("proposals_created"),
|
|
180
|
+
// "approved" is the human decision: approved + applied.
|
|
181
|
+
proposals_approved: metrics.get("proposals_approved"),
|
|
182
|
+
proposals_rejected: metrics.get("proposals_rejected"),
|
|
183
|
+
artifact_writes_total: metrics.get("artifact_writes_total"),
|
|
184
|
+
artifact_writes_noop: metrics.get("artifact_writes_noop"),
|
|
185
|
+
references_registered: registered("references_registered"),
|
|
186
|
+
skills_registered: registered("skills_registered"),
|
|
187
|
+
skill_emission: emission(capabilities.skills, "skill_emission_enabled"),
|
|
188
|
+
reference_emission: emission(capabilities.references, "reference_emission_enabled"),
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
partial = true;
|
|
194
|
+
channels = undefined;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const proposalRows = store
|
|
198
|
+
.prepare("SELECT status, COUNT(*) AS n FROM curation_proposals GROUP BY status")
|
|
199
|
+
.all();
|
|
200
|
+
const byStatus = {};
|
|
201
|
+
for (const r of proposalRows) {
|
|
202
|
+
byStatus[r.status] = r.n;
|
|
203
|
+
}
|
|
204
|
+
curation = {
|
|
205
|
+
// The Curator predicate is `inferable != 1` (plan §5.5): an
|
|
206
|
+
// unclassified (NULL) memory must not be silently withheld.
|
|
207
|
+
eligible: scalar(store, "SELECT COUNT(*) AS n FROM memories WHERE inferable IS NOT 1"),
|
|
208
|
+
curated: scalar(store, "SELECT COUNT(*) AS n FROM memories WHERE curated = 1"),
|
|
209
|
+
inferable: scalar(store, "SELECT COUNT(*) AS n FROM memories WHERE inferable = 1"),
|
|
210
|
+
non_inferable: scalar(store, "SELECT COUNT(*) AS n FROM memories WHERE inferable = 0"),
|
|
211
|
+
unknown: scalar(store, "SELECT COUNT(*) AS n FROM memories WHERE inferable IS NULL"),
|
|
212
|
+
proposals_by_status: byStatus,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
partial = true;
|
|
217
|
+
curation = undefined;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
partial = true;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const rows = store
|
|
225
|
+
.prepare("SELECT kind, status, COUNT(*) AS n FROM memory_conflicts GROUP BY kind, status")
|
|
226
|
+
.all();
|
|
227
|
+
const byKind = {};
|
|
228
|
+
const byStatus = {};
|
|
229
|
+
for (const row of rows) {
|
|
230
|
+
byKind[row.kind] = (byKind[row.kind] ?? 0) + row.n;
|
|
231
|
+
byStatus[row.status] = (byStatus[row.status] ?? 0) + row.n;
|
|
232
|
+
}
|
|
233
|
+
conflicts = { by_kind: byKind, by_status: byStatus };
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
partial = true;
|
|
237
|
+
}
|
|
238
|
+
// v0.7.0 (K7-019 / plan §5.3, K7-006) — the `truth` block is
|
|
239
|
+
// project-scoped. On a pre-008 database the repo_facts query throws, so
|
|
240
|
+
// the block is omitted and `partial` set — a report that cannot answer
|
|
241
|
+
// "how many facts does this project have?" must say so.
|
|
242
|
+
let truth;
|
|
243
|
+
if (projectId) {
|
|
244
|
+
try {
|
|
245
|
+
const truncatedRow = store
|
|
246
|
+
.prepare("SELECT value FROM repo_facts WHERE project_id = ? AND key_path = '_truncated'")
|
|
247
|
+
.get(projectId);
|
|
248
|
+
truth = {
|
|
249
|
+
facts_scanned: scalar(store, "SELECT COUNT(*) AS n FROM repo_facts WHERE project_id = ?", projectId),
|
|
250
|
+
penalized_memories: scalar(store, "SELECT COUNT(*) AS n FROM memories WHERE project_id = ? AND truth_penalty > 0", projectId),
|
|
251
|
+
truncated: truncatedRow
|
|
252
|
+
? { is_truncated: true, count: Number(truncatedRow.value) || 0 }
|
|
253
|
+
: { is_truncated: false },
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
partial = true;
|
|
258
|
+
truth = undefined;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
const typeRows = store
|
|
263
|
+
.prepare(`SELECT m.type, COUNT(*) AS n
|
|
264
|
+
FROM kevin_injections i JOIN memories m ON m.id = i.memory_id
|
|
265
|
+
GROUP BY m.type`)
|
|
266
|
+
.all();
|
|
267
|
+
const injectedByType = {
|
|
268
|
+
error: 0,
|
|
269
|
+
rule: 0,
|
|
270
|
+
decision: 0,
|
|
271
|
+
pattern: 0,
|
|
272
|
+
solution: 0,
|
|
273
|
+
context: 0,
|
|
274
|
+
};
|
|
275
|
+
for (const row of typeRows)
|
|
276
|
+
injectedByType[row.type] = row.n;
|
|
277
|
+
const total = typeRows.reduce((sum, row) => sum + row.n, 0);
|
|
278
|
+
const nonError = total - (injectedByType.error ?? 0);
|
|
279
|
+
const precisionFor = (isError) => {
|
|
280
|
+
const row = store
|
|
281
|
+
.prepare(`SELECT
|
|
282
|
+
SUM(CASE WHEN i.outcome = 'effective' THEN 1 ELSE 0 END) AS effective,
|
|
283
|
+
SUM(CASE WHEN i.outcome = 'ineffective' THEN 1 ELSE 0 END) AS ineffective
|
|
284
|
+
FROM kevin_injections i JOIN memories m ON m.id = i.memory_id
|
|
285
|
+
WHERE ${isError ? "m.type = 'error'" : "m.type <> 'error'"}`)
|
|
286
|
+
.get();
|
|
287
|
+
const effective = row.effective ?? 0;
|
|
288
|
+
const measured = effective + (row.ineffective ?? 0);
|
|
289
|
+
return measured > 0 ? effective / measured : 0;
|
|
290
|
+
};
|
|
291
|
+
const precisionError = precisionFor(true);
|
|
292
|
+
const precisionNonError = precisionFor(false);
|
|
293
|
+
const memoryCount = scalar(store, "SELECT COUNT(*) AS n FROM memories");
|
|
294
|
+
const settled = scalar(store, "SELECT COUNT(*) AS n FROM kevin_injections WHERE outcome IN ('effective','ineffective')");
|
|
295
|
+
const mature = memoryCount >= 100 && settled >= 50;
|
|
296
|
+
const meets = mature &&
|
|
297
|
+
nonError / Math.max(total, 1) >= 0.5 &&
|
|
298
|
+
precisionNonError > precisionError;
|
|
299
|
+
mix = {
|
|
300
|
+
injected_by_type: injectedByType,
|
|
301
|
+
injected_total: total,
|
|
302
|
+
non_error_injected: nonError,
|
|
303
|
+
non_error_share: total > 0 ? nonError / total : 0,
|
|
304
|
+
precision_error: precisionError,
|
|
305
|
+
precision_non_error: precisionNonError,
|
|
306
|
+
meets_exit_criterion: meets,
|
|
307
|
+
...(mature ? {} : { reason: "immature_db" }),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
partial = true;
|
|
312
|
+
}
|
|
131
313
|
return {
|
|
132
314
|
memories,
|
|
133
315
|
injections,
|
|
@@ -135,6 +317,11 @@ export function buildAudit(store, metrics) {
|
|
|
135
317
|
feedback,
|
|
136
318
|
tokens,
|
|
137
319
|
settings,
|
|
320
|
+
conflicts,
|
|
321
|
+
truth,
|
|
322
|
+
mix,
|
|
323
|
+
channels,
|
|
324
|
+
curation,
|
|
138
325
|
partial,
|
|
139
326
|
};
|
|
140
327
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kevin_audit.js","sourceRoot":"","sources":["../../plugin/kevin_audit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kevin_audit.js","sourceRoot":"","sources":["../../plugin/kevin_audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ConflictDetector } from "./ConflictDetector.js";
|
|
2
|
+
import type { Store } from "./Store.js";
|
|
3
|
+
export interface KevinConflictsDeps {
|
|
4
|
+
store: Store;
|
|
5
|
+
detector: ConflictDetector;
|
|
6
|
+
projectId: string;
|
|
7
|
+
}
|
|
8
|
+
export type ConflictAction = "list" | "acknowledge" | "resolve";
|
|
9
|
+
export declare function executeKevinConflicts(deps: KevinConflictsDeps, action: ConflictAction, id?: string, keep?: string, requestedStatus?: "open" | "acknowledged" | "resolved"): Record<string, unknown>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export function executeKevinConflicts(deps, action, id, keep, requestedStatus) {
|
|
2
|
+
if (action === "acknowledge") {
|
|
3
|
+
if (!id)
|
|
4
|
+
return { error: "missing_id" };
|
|
5
|
+
// Mirror resolve()'s honesty: acknowledging a nonexistent or foreign id
|
|
6
|
+
// must not be reported as a success.
|
|
7
|
+
const row = deps.store
|
|
8
|
+
.prepare("SELECT id FROM memory_conflicts WHERE id = ? AND project_id = ?")
|
|
9
|
+
.get(id, deps.projectId);
|
|
10
|
+
if (!row)
|
|
11
|
+
return { error: "not_found", id };
|
|
12
|
+
deps.detector.acknowledge(id);
|
|
13
|
+
return { id, status: "acknowledged" };
|
|
14
|
+
}
|
|
15
|
+
if (action === "resolve") {
|
|
16
|
+
if (!id || !keep)
|
|
17
|
+
return { error: "missing_id_or_keep" };
|
|
18
|
+
const row = deps.store
|
|
19
|
+
.prepare("SELECT memory_a, memory_b FROM memory_conflicts WHERE id = ? AND project_id = ?")
|
|
20
|
+
.get(id, deps.projectId);
|
|
21
|
+
if (!row)
|
|
22
|
+
return { error: "not_found", id };
|
|
23
|
+
if (keep !== row.memory_a && keep !== row.memory_b) {
|
|
24
|
+
return { error: "invalid_keep", id, keep };
|
|
25
|
+
}
|
|
26
|
+
deps.detector.resolve(id, keep);
|
|
27
|
+
return {
|
|
28
|
+
id,
|
|
29
|
+
status: "resolved",
|
|
30
|
+
kept: keep,
|
|
31
|
+
other: keep === row.memory_a ? row.memory_b : row.memory_a,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const status = requestedStatus ?? "open";
|
|
35
|
+
const rows = deps.store
|
|
36
|
+
.prepare(`SELECT id, kind, memory_a, memory_b, fact_id, detail, status, detected_at
|
|
37
|
+
FROM memory_conflicts WHERE project_id = ? AND status = ?
|
|
38
|
+
ORDER BY detected_at, id`)
|
|
39
|
+
.all(deps.projectId, status);
|
|
40
|
+
const counts = deps.store
|
|
41
|
+
.prepare(`SELECT status, COUNT(*) AS n FROM memory_conflicts
|
|
42
|
+
WHERE project_id = ? GROUP BY status`)
|
|
43
|
+
.all(deps.projectId);
|
|
44
|
+
return {
|
|
45
|
+
open: counts.find((row) => row.status === "open")?.n ?? 0,
|
|
46
|
+
acknowledged: counts.find((row) => row.status === "acknowledged")?.n ?? 0,
|
|
47
|
+
resolved: counts.find((row) => row.status === "resolved")?.n ?? 0,
|
|
48
|
+
conflicts: rows,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=kevin_conflicts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kevin_conflicts.js","sourceRoot":"","sources":["../../plugin/kevin_conflicts.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,qBAAqB,CACpC,IAAwB,EACxB,MAAsB,EACtB,EAAW,EACX,IAAa,EACb,eAAsD;IAEtD,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC9B,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QACxC,wEAAwE;QACxE,qCAAqC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK;aACpB,OAAO,CACP,iEAAiE,CACjE;aACA,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACvC,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK;aACpB,OAAO,CACP,iFAAiF,CACjF;aACA,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAEZ,CAAC;QACb,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QAC5C,IAAI,IAAI,KAAK,GAAG,CAAC,QAAQ,IAAI,IAAI,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC;YACpD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChC,OAAO;YACN,EAAE;YACF,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ;SAC1D,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,IAAI,MAAM,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK;SACrB,OAAO,CACP;;6BAE0B,CAC1B;SACA,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAmC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK;SACvB,OAAO,CACP;yCACsC,CACtC;SACA,GAAG,CAAC,IAAI,CAAC,SAAS,CAAoC,CAAC;IACzD,OAAO;QACN,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;QACzD,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC;QACzE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC;QACjE,SAAS,EAAE,IAAI;KACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { MemoryService } from "./MemoryService.js";
|
|
2
|
+
import type { RepoTruth } from "./RepoTruth.js";
|
|
3
|
+
import type { Store } from "./Store.js";
|
|
4
|
+
/**
|
|
5
|
+
* v0.7.0 (K7-009 / plan §5.7) — `kevin_facts`.
|
|
6
|
+
*
|
|
7
|
+
* The user-facing answer to "why did Kevin stop suggesting that?". Lists the
|
|
8
|
+
* repository facts the current project was scanned for and every memory that
|
|
9
|
+
* was de-ranked by a contradiction, with its `truth_penalty`, `contradicted_at`
|
|
10
|
+
* and the human-readable reasons. Pure read apart from the optional re-scan. No
|
|
11
|
+
* LLM, no network, no hot-path cost.
|
|
12
|
+
*/
|
|
13
|
+
export interface KevinFactsDeps {
|
|
14
|
+
store: Store;
|
|
15
|
+
memoryService: MemoryService;
|
|
16
|
+
repoTruth: RepoTruth;
|
|
17
|
+
projectId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface PenalizedMemory {
|
|
20
|
+
id: string;
|
|
21
|
+
type: string;
|
|
22
|
+
truth_penalty: number;
|
|
23
|
+
contradicted_at: string | null;
|
|
24
|
+
reasons: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface KevinFactsResult {
|
|
27
|
+
project_id: string;
|
|
28
|
+
scanned_at: string | null;
|
|
29
|
+
truncated: {
|
|
30
|
+
is_truncated: true;
|
|
31
|
+
count: number;
|
|
32
|
+
} | {
|
|
33
|
+
is_truncated: false;
|
|
34
|
+
};
|
|
35
|
+
facts: {
|
|
36
|
+
file: string;
|
|
37
|
+
key_path: string;
|
|
38
|
+
value: string;
|
|
39
|
+
}[];
|
|
40
|
+
penalized: PenalizedMemory[];
|
|
41
|
+
}
|
|
42
|
+
export declare function buildKevinFacts(deps: KevinFactsDeps, refresh: boolean): KevinFactsResult;
|