@jmtrin/kevin-core 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/Archiver.d.ts +42 -0
- package/dist/Archiver.js +83 -0
- package/dist/ArtifactWriter.d.ts +93 -0
- package/dist/ArtifactWriter.js +291 -0
- package/dist/CausalChain.d.ts +22 -0
- package/dist/CausalChain.js +197 -0
- package/dist/ChatBridge.d.ts +41 -0
- package/dist/ChatBridge.js +103 -0
- package/dist/ConflictDetector.d.ts +35 -0
- package/dist/ConflictDetector.js +260 -0
- package/dist/ContextInjector.d.ts +222 -0
- package/dist/ContextInjector.js +533 -0
- package/dist/ConventionMiner.d.ts +35 -0
- package/dist/ConventionMiner.js +242 -0
- package/dist/Curator.d.ts +118 -0
- package/dist/Curator.js +326 -0
- package/dist/DashboardHtml.d.ts +5 -0
- package/dist/DashboardHtml.js +180 -0
- package/dist/Feedback.d.ts +67 -0
- package/dist/Feedback.js +120 -0
- package/dist/HookLiveness.d.ts +88 -0
- package/dist/HookLiveness.js +322 -0
- package/dist/InjectionLedger.d.ts +98 -0
- package/dist/InjectionLedger.js +295 -0
- package/dist/LessonFixer.d.ts +44 -0
- package/dist/LessonFixer.js +45 -0
- package/dist/Materializer.d.ts +84 -0
- package/dist/Materializer.js +181 -0
- package/dist/MemoryService.d.ts +360 -0
- package/dist/MemoryService.js +1242 -0
- package/dist/Migrate.d.ts +24 -0
- package/dist/Migrate.js +285 -0
- package/dist/PatternMiner.d.ts +49 -0
- package/dist/PatternMiner.js +132 -0
- package/dist/QualityGate.d.ts +124 -0
- package/dist/QualityGate.js +119 -0
- package/dist/Reflector.d.ts +91 -0
- package/dist/Reflector.js +307 -0
- package/dist/RepoIdentity.d.ts +124 -0
- package/dist/RepoIdentity.js +300 -0
- package/dist/RepoTruth.d.ts +80 -0
- package/dist/RepoTruth.js +599 -0
- package/dist/Retrospective.d.ts +18 -0
- package/dist/Retrospective.js +216 -0
- package/dist/SharedLayer.d.ts +159 -0
- package/dist/SharedLayer.js +462 -0
- package/dist/Store.d.ts +29 -0
- package/dist/Store.js +50 -0
- package/dist/ToolCallObserver.d.ts +32 -0
- package/dist/ToolCallObserver.js +201 -0
- package/dist/TuiActions.d.ts +43 -0
- package/dist/TuiActions.js +181 -0
- package/dist/TuiSnapshots.d.ts +24 -0
- package/dist/TuiSnapshots.js +159 -0
- package/dist/capabilities.d.ts +6 -0
- package/dist/capabilities.js +1 -0
- package/dist/columns.d.ts +11 -0
- package/dist/columns.js +54 -0
- package/dist/confidence.d.ts +8 -0
- package/dist/confidence.js +34 -0
- package/dist/contract.d.ts +68 -0
- package/dist/contract.js +430 -0
- package/dist/diff.d.ts +8 -0
- package/dist/diff.js +182 -0
- package/dist/env.d.ts +5 -0
- package/dist/env.js +12 -0
- package/dist/escape.d.ts +39 -0
- package/dist/escape.js +60 -0
- package/dist/fingerprint.d.ts +27 -0
- package/dist/fingerprint.js +73 -0
- package/dist/host.d.ts +18 -0
- package/dist/host.js +7 -0
- package/dist/idle-pipeline.d.ts +9 -0
- package/dist/idle-pipeline.js +44 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +109 -0
- package/dist/inferability.d.ts +32 -0
- package/dist/inferability.js +88 -0
- package/dist/kevin_approve.d.ts +34 -0
- package/dist/kevin_approve.js +52 -0
- package/dist/kevin_audit.d.ts +230 -0
- package/dist/kevin_audit.js +631 -0
- package/dist/kevin_bench.d.ts +11 -0
- package/dist/kevin_bench.js +83 -0
- package/dist/kevin_conflicts.d.ts +9 -0
- package/dist/kevin_conflicts.js +50 -0
- package/dist/kevin_contract.d.ts +8 -0
- package/dist/kevin_contract.js +59 -0
- package/dist/kevin_doctor.d.ts +63 -0
- package/dist/kevin_doctor.js +197 -0
- package/dist/kevin_facts.d.ts +42 -0
- package/dist/kevin_facts.js +36 -0
- package/dist/kevin_forget.d.ts +33 -0
- package/dist/kevin_forget.js +260 -0
- package/dist/kevin_native.d.ts +29 -0
- package/dist/kevin_native.js +79 -0
- package/dist/kevin_propose.d.ts +23 -0
- package/dist/kevin_propose.js +14 -0
- package/dist/kevin_publish.d.ts +38 -0
- package/dist/kevin_publish.js +18 -0
- package/dist/kevin_why.d.ts +23 -0
- package/dist/kevin_why.js +111 -0
- package/dist/memory-format.d.ts +20 -0
- package/dist/memory-format.js +59 -0
- package/dist/metrics.d.ts +97 -0
- package/dist/metrics.js +288 -0
- package/dist/migrations/001_initial.sql +92 -0
- package/dist/migrations/002_indexes.sql +14 -0
- package/dist/migrations/003_v02_signal.sql +58 -0
- package/dist/migrations/004_v03_knowledge.sql +138 -0
- package/dist/migrations/005_v04_signal.sql +57 -0
- package/dist/migrations/006_v05_glassbox.sql +118 -0
- package/dist/migrations/007_v06_pull.sql +145 -0
- package/dist/migrations/008_v07_truth.sql +124 -0
- package/dist/migrations/009_v08_team.sql +100 -0
- package/dist/migrations/010_v09_native.sql +78 -0
- package/dist/migrations/011_v10_proven.sql +69 -0
- package/dist/migrations/012_v11_drift.sql +24 -0
- package/dist/native.d.ts +23 -0
- package/dist/native.js +1 -0
- package/dist/okf-export.d.ts +3 -0
- package/dist/okf-export.js +134 -0
- package/dist/okf-import.d.ts +76 -0
- package/dist/okf-import.js +271 -0
- package/dist/okf.d.ts +107 -0
- package/dist/okf.js +303 -0
- package/dist/perf.d.ts +35 -0
- package/dist/perf.js +174 -0
- package/dist/query-tokenizer.d.ts +13 -0
- package/dist/query-tokenizer.js +133 -0
- package/dist/redact.d.ts +2 -0
- package/dist/redact.js +18 -0
- package/dist/replay-types.d.ts +69 -0
- package/dist/replay-types.js +156 -0
- package/dist/replay.d.ts +44 -0
- package/dist/replay.js +215 -0
- package/dist/sqlite-adapter.d.ts +12 -0
- package/dist/sqlite-adapter.js +78 -0
- package/dist/time-ms.d.ts +1 -0
- package/dist/time-ms.js +16 -0
- package/dist/tui-types.d.ts +59 -0
- package/dist/tui-types.js +4 -0
- package/dist/uuid.d.ts +1 -0
- package/dist/uuid.js +50 -0
- package/package.json +28 -0
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
export type Inferability = "inferable" | "non_inferable" | "unknown";
|
|
8
|
+
/**
|
|
9
|
+
* The `Reflector` dispatch surface of §3.4, restated as data: error codes whose
|
|
10
|
+
* payload IS the knowledge — no project-specific interpretation required.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SELF_DESCRIBING_CODES: ReadonlySet<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Rules from plan §5.3, evaluated in order — the ordering is the specification:
|
|
15
|
+
*
|
|
16
|
+
* 1. `type` ∈ decision / rule / solution → `non_inferable`
|
|
17
|
+
* 2. `type` = pattern → `non_inferable`
|
|
18
|
+
* 3. `type` = error and `metadata.dispatch.code` ∈ SELF_DESCRIBING_CODES → `inferable`
|
|
19
|
+
* 4. `type` = error and content names a project-specific path, script or flag → `non_inferable`
|
|
20
|
+
* 5. otherwise → `unknown`
|
|
21
|
+
*
|
|
22
|
+
* Rule 4 beats rule 3: a TS2304 is inferable, but "TS2304 on
|
|
23
|
+
* `./scripts/gen-routes.ts` because the generator must run before tsc" is not —
|
|
24
|
+
* the project-specific script name is the payload, not the code. Rule 3's
|
|
25
|
+
* condition (code membership) is evaluated first for the bare case; rule 4
|
|
26
|
+
* catches what rule 3 does not.
|
|
27
|
+
*/
|
|
28
|
+
export declare function classify(memory: {
|
|
29
|
+
type: string;
|
|
30
|
+
content: string;
|
|
31
|
+
metadata?: unknown;
|
|
32
|
+
}): Inferability;
|
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
}
|
|
@@ -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,52 @@
|
|
|
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; write() is atomic and
|
|
28
|
+
// audits every outcome including noop. The disk write happens BEFORE the
|
|
29
|
+
// state transitions: if write() 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 outcome = writer.write({
|
|
34
|
+
path: row.target_path,
|
|
35
|
+
mode: "markers",
|
|
36
|
+
content: row.proposed_text,
|
|
37
|
+
}, args.proposalId);
|
|
38
|
+
curator.transition(args.proposalId, "approve");
|
|
39
|
+
curator.transition(args.proposalId, "apply");
|
|
40
|
+
const memoryIds = row.memory_id.split(",").filter((s) => s.length > 0);
|
|
41
|
+
const curated = memoryService.markCurated(memoryIds, sqliteNow());
|
|
42
|
+
metrics?.incr("proposals_approved", 1);
|
|
43
|
+
return {
|
|
44
|
+
proposalId: args.proposalId,
|
|
45
|
+
status: "applied",
|
|
46
|
+
outcome,
|
|
47
|
+
curated,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function sqliteNow() {
|
|
51
|
+
return new Date().toISOString().slice(0, 19).replace("T", " ");
|
|
52
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { type KevinEnv } from "./env.js";
|
|
2
|
+
import type { Store } from "./Store.js";
|
|
3
|
+
import type { Capabilities } from "./capabilities.js";
|
|
4
|
+
import type { Metrics } from "./metrics.js";
|
|
5
|
+
/**
|
|
6
|
+
* v0.5.0 (K5-016 / plan §5.7) — `kevin_audit`.
|
|
7
|
+
*
|
|
8
|
+
* Pure SQL over `memories`, `kevin_injections`, `kevin_metrics`,
|
|
9
|
+
* `memory_feedback`. No writes, no LLM, no filesystem access.
|
|
10
|
+
*
|
|
11
|
+
* There is deliberately **no `kevin_context_ratio`** (D5-09): Kevin cannot
|
|
12
|
+
* observe total session input tokens, so any such figure would be fabricated.
|
|
13
|
+
*
|
|
14
|
+
* Pre-006 databases degrade gracefully: any block that fails (missing column
|
|
15
|
+
* or table) falls back to its zero value and the report is flagged
|
|
16
|
+
* `"partial": true` instead of throwing.
|
|
17
|
+
*
|
|
18
|
+
* v0.6.0 (K6-023 / plan §5.8) — the `channels` and `curation` blocks are the
|
|
19
|
+
* release's own scoreboard. On a pre-007 database they are **omitted** (not
|
|
20
|
+
* zero-valued) and `"partial": true` is set: a report that cannot answer
|
|
21
|
+
* "do the pull channels beat push?" must say so rather than suggest it can.
|
|
22
|
+
*
|
|
23
|
+
* v0.7.0 (K7-019 / plan §5.3, K7-006) — the `truth` block is project-scoped:
|
|
24
|
+
* facts scanned, penalized memory count and the truncation flag for the
|
|
25
|
+
* current project. It is omitted (and `"partial": true` set) on a pre-008
|
|
26
|
+
* database, exactly like the conflicts block. `facts_scanned` counts every
|
|
27
|
+
* `repo_facts` row for the project — the same COUNT(*) semantics as the
|
|
28
|
+
* `repo_facts_scanned` metric — while `truncated` reports the scan cap
|
|
29
|
+
* separately, mirroring `kevin_facts`.
|
|
30
|
+
*/
|
|
31
|
+
export interface AuditReport {
|
|
32
|
+
memories: {
|
|
33
|
+
total: number;
|
|
34
|
+
by_status: Record<string, number>;
|
|
35
|
+
by_origin: Record<string, number>;
|
|
36
|
+
by_type: Record<string, number>;
|
|
37
|
+
ignored: number;
|
|
38
|
+
archived: number;
|
|
39
|
+
with_feedback: number;
|
|
40
|
+
superseded_with_target: number;
|
|
41
|
+
};
|
|
42
|
+
injections: {
|
|
43
|
+
total: number;
|
|
44
|
+
effective: number;
|
|
45
|
+
ineffective: number;
|
|
46
|
+
inconclusive: number;
|
|
47
|
+
unmeasured: number;
|
|
48
|
+
precision_rate: number;
|
|
49
|
+
coverage_rate: number;
|
|
50
|
+
};
|
|
51
|
+
blocked: Record<string, number>;
|
|
52
|
+
feedback: {
|
|
53
|
+
positive: number;
|
|
54
|
+
negative: number;
|
|
55
|
+
by_verdict: Record<string, number>;
|
|
56
|
+
};
|
|
57
|
+
tokens: {
|
|
58
|
+
pre_prompt: number;
|
|
59
|
+
compacting: number;
|
|
60
|
+
};
|
|
61
|
+
settings: Record<string, string>;
|
|
62
|
+
conflicts?: {
|
|
63
|
+
by_kind: Record<string, number>;
|
|
64
|
+
by_status: Record<string, number>;
|
|
65
|
+
};
|
|
66
|
+
truth?: TruthReport;
|
|
67
|
+
mix?: {
|
|
68
|
+
injected_by_type: Record<string, number>;
|
|
69
|
+
injected_total: number;
|
|
70
|
+
non_error_injected: number;
|
|
71
|
+
non_error_share: number;
|
|
72
|
+
precision_error: number;
|
|
73
|
+
precision_non_error: number;
|
|
74
|
+
meets_exit_criterion: boolean;
|
|
75
|
+
reason?: "immature_db";
|
|
76
|
+
};
|
|
77
|
+
channels?: ChannelReport;
|
|
78
|
+
curation?: CurationReport;
|
|
79
|
+
/**
|
|
80
|
+
* v0.8.0 (K8-018/023 / plan §5.2, §5.7) — the shared-layer block.
|
|
81
|
+
* K8-018 kept it minimal (write_refusals); K8-023 extends it with
|
|
82
|
+
* the full team rollup, computed in pure SQL. On a database below
|
|
83
|
+
* the v0.7.0 maturity floor the precision numbers are omitted and
|
|
84
|
+
* `reason: "immature_db"` reported instead.
|
|
85
|
+
*/
|
|
86
|
+
team?: {
|
|
87
|
+
write_refusals: number;
|
|
88
|
+
shared_total?: number;
|
|
89
|
+
tombstones?: number;
|
|
90
|
+
distinct_authors?: number;
|
|
91
|
+
last_import_at?: string | null;
|
|
92
|
+
last_import_rejected?: number;
|
|
93
|
+
precision_shared?: number;
|
|
94
|
+
precision_local?: number;
|
|
95
|
+
reason?: "immature_db";
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* v0.9.0 (K9-020 / plan §5.5) — the host block, alongside the v0.7.0
|
|
99
|
+
* `mix` and v0.8.0 `team` blocks. Pure SQL: hook states in aggregate
|
|
100
|
+
* (live/dead/unknown counts, fires and errors totals), the resolved
|
|
101
|
+
* plugin version, native registration outcomes per surface, and the
|
|
102
|
+
* verdict derivable from the database alone. On a pre-010 database
|
|
103
|
+
* the block is omitted (not zero-valued) and `"partial": true` set,
|
|
104
|
+
* following the channels/curation precedent.
|
|
105
|
+
*/
|
|
106
|
+
host?: {
|
|
107
|
+
plugin_version: string | null;
|
|
108
|
+
hooks: {
|
|
109
|
+
live: number;
|
|
110
|
+
dead: number;
|
|
111
|
+
unknown: number;
|
|
112
|
+
fires_total: number;
|
|
113
|
+
errors_total: number;
|
|
114
|
+
};
|
|
115
|
+
native: {
|
|
116
|
+
total: number;
|
|
117
|
+
verified: number;
|
|
118
|
+
failures: number;
|
|
119
|
+
by_surface: Record<string, {
|
|
120
|
+
registered: number;
|
|
121
|
+
verified: number;
|
|
122
|
+
}>;
|
|
123
|
+
};
|
|
124
|
+
verdict: "healthy" | "degraded" | "unknown";
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* v1.0.0 (K10-020 / plan §5.6) — the perf block: per scope, the most
|
|
128
|
+
* recent `perf_samples` aggregate row (count/p50/p95/max) plus the
|
|
129
|
+
* stored budget and verdict. The stored aggregates are used DIRECTLY —
|
|
130
|
+
* re-aggregating aggregates would produce a number with no meaning
|
|
131
|
+
* (plan anti-pattern 42), and using the most recent row per scope is
|
|
132
|
+
* exactly what `bench:check` does, so `within_budget` agrees with it
|
|
133
|
+
* on the same data. Omitted (not zero-valued) on a pre-011 database,
|
|
134
|
+
* following the host precedent.
|
|
135
|
+
*/
|
|
136
|
+
perf?: {
|
|
137
|
+
scopes: Record<string, {
|
|
138
|
+
count: number;
|
|
139
|
+
p50: number;
|
|
140
|
+
p95: number;
|
|
141
|
+
max: number;
|
|
142
|
+
budget_p95: number;
|
|
143
|
+
within_budget: boolean;
|
|
144
|
+
}>;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* v1.0.0 (K10-020 / plan §5.6) — the contract block: the live contract's
|
|
148
|
+
* identity, computed from source rather than the database, so it is
|
|
149
|
+
* present even on a pre-011 database.
|
|
150
|
+
*/
|
|
151
|
+
contract?: {
|
|
152
|
+
contract_version: number;
|
|
153
|
+
digest: string;
|
|
154
|
+
clause_count: number;
|
|
155
|
+
deprecated_count: number;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* v1.2.0 (K12-014 / D12-??) — TUI surface block. Read-only introspection:
|
|
159
|
+
* enabled_setting is the kevin_settings value, last_flush_age_s is seconds
|
|
160
|
+
* since meta.json generatedAt (null when absent/corrupt), mailbox_depth is
|
|
161
|
+
* queue length (null when file missing), last_results is the parsed
|
|
162
|
+
* results.json array (null when absent). Dashboard age and bridge counters
|
|
163
|
+
* added in K12-019.
|
|
164
|
+
*/
|
|
165
|
+
tui?: {
|
|
166
|
+
enabled_setting: string;
|
|
167
|
+
last_flush_age_s: number | null;
|
|
168
|
+
mailbox_depth: number | null;
|
|
169
|
+
last_results: unknown | null;
|
|
170
|
+
dashboard_last_write_age_s: number | null;
|
|
171
|
+
bridge_interceptions: number;
|
|
172
|
+
};
|
|
173
|
+
partial: boolean;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* v0.6.0 (K6-023 / plan §5.8) — three-channel comparison on the same axes.
|
|
177
|
+
* `skill_emission` / `reference_emission` distinguish the three states a
|
|
178
|
+
* channel can be in: "unavailable" (v1 host, no domain on the plugin input),
|
|
179
|
+
* "off" (capable host, setting '0'), "on" (capable host, setting '1').
|
|
180
|
+
* Collapsing "unavailable" and "off" would make "my host is too old"
|
|
181
|
+
* indistinguishable from "I turned it off".
|
|
182
|
+
*/
|
|
183
|
+
export type EmissionState = "on" | "off" | "unavailable";
|
|
184
|
+
export interface ChannelReport {
|
|
185
|
+
push: {
|
|
186
|
+
tokens_pre_prompt: number;
|
|
187
|
+
tokens_compacting: number;
|
|
188
|
+
injections_total: number;
|
|
189
|
+
precision_rate: number;
|
|
190
|
+
coverage_rate: number;
|
|
191
|
+
budget_tokens: number;
|
|
192
|
+
};
|
|
193
|
+
pull: {
|
|
194
|
+
proposals_created: number;
|
|
195
|
+
proposals_approved: number;
|
|
196
|
+
proposals_rejected: number;
|
|
197
|
+
artifact_writes_total: number;
|
|
198
|
+
artifact_writes_noop: number;
|
|
199
|
+
references_registered: number;
|
|
200
|
+
skills_registered: number;
|
|
201
|
+
skill_emission: EmissionState;
|
|
202
|
+
reference_emission: EmissionState;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export interface CurationReport {
|
|
206
|
+
eligible: number;
|
|
207
|
+
curated: number;
|
|
208
|
+
inferable: number;
|
|
209
|
+
non_inferable: number;
|
|
210
|
+
unknown: number;
|
|
211
|
+
proposals_by_status: Record<string, number>;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* v0.7.0 (K7-019 / plan §5.3) — the Project Truth block. The same shape
|
|
215
|
+
* `kevin_facts` exposes: `facts_scanned` counts every repo_facts row for the
|
|
216
|
+
* project (COUNT(*) semantics, matching the `repo_facts_scanned` metric),
|
|
217
|
+
* `penalized_memories` counts memories with `truth_penalty > 0`, and
|
|
218
|
+
* `truncated` reports the 500-fact scan cap from the `_truncated` marker row.
|
|
219
|
+
*/
|
|
220
|
+
export interface TruthReport {
|
|
221
|
+
facts_scanned: number;
|
|
222
|
+
penalized_memories: number;
|
|
223
|
+
truncated: {
|
|
224
|
+
is_truncated: true;
|
|
225
|
+
count: number;
|
|
226
|
+
} | {
|
|
227
|
+
is_truncated: false;
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
export declare function buildAudit(store: Store, metrics: Metrics, capabilities?: Capabilities, projectId?: string, repoId?: string | null, tuiRoot?: string, env?: KevinEnv): AuditReport;
|