mewkit 1.10.3 → 1.11.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 +56 -4
- package/dist/commands/budget.d.ts +13 -0
- package/dist/commands/budget.d.ts.map +1 -1
- package/dist/commands/budget.js +45 -0
- package/dist/commands/budget.js.map +1 -1
- package/dist/commands/doctor-checks.d.ts +1 -1
- package/dist/commands/doctor-checks.d.ts.map +1 -1
- package/dist/commands/doctor-checks.js +7 -1
- package/dist/commands/doctor-checks.js.map +1 -1
- package/dist/commands/doctor-hard-gates.d.ts +3 -0
- package/dist/commands/doctor-hard-gates.d.ts.map +1 -0
- package/dist/commands/doctor-hard-gates.js +138 -0
- package/dist/commands/doctor-hard-gates.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +12 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/evolve.d.ts +11 -0
- package/dist/commands/evolve.d.ts.map +1 -0
- package/dist/commands/evolve.js +63 -0
- package/dist/commands/evolve.js.map +1 -0
- package/dist/commands/health.d.ts +14 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +193 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +63 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/inventory.d.ts +17 -0
- package/dist/commands/inventory.d.ts.map +1 -0
- package/dist/commands/inventory.js +114 -0
- package/dist/commands/inventory.js.map +1 -0
- package/dist/commands/memory.d.ts +3 -0
- package/dist/commands/memory.d.ts.map +1 -1
- package/dist/commands/memory.js +67 -0
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/pack-helpers.d.ts +37 -0
- package/dist/commands/pack-helpers.d.ts.map +1 -0
- package/dist/commands/pack-helpers.js +105 -0
- package/dist/commands/pack-helpers.js.map +1 -0
- package/dist/commands/pack.d.ts +11 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +192 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/policy.d.ts +8 -0
- package/dist/commands/policy.d.ts.map +1 -0
- package/dist/commands/policy.js +65 -0
- package/dist/commands/policy.js.map +1 -0
- package/dist/commands/portability.d.ts +7 -0
- package/dist/commands/portability.d.ts.map +1 -0
- package/dist/commands/portability.js +50 -0
- package/dist/commands/portability.js.map +1 -0
- package/dist/commands/reflect.d.ts +14 -0
- package/dist/commands/reflect.d.ts.map +1 -0
- package/dist/commands/reflect.js +135 -0
- package/dist/commands/reflect.js.map +1 -0
- package/dist/commands/simulate.d.ts +14 -0
- package/dist/commands/simulate.d.ts.map +1 -0
- package/dist/commands/simulate.js +86 -0
- package/dist/commands/simulate.js.map +1 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +22 -1
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/validate.d.ts +28 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +170 -94
- package/dist/commands/validate.js.map +1 -1
- package/dist/core/build-inventory.d.ts +71 -0
- package/dist/core/build-inventory.d.ts.map +1 -0
- package/dist/core/build-inventory.js +222 -0
- package/dist/core/build-inventory.js.map +1 -0
- package/dist/core/check-packs.d.ts +13 -0
- package/dist/core/check-packs.d.ts.map +1 -0
- package/dist/core/check-packs.js +131 -0
- package/dist/core/check-packs.js.map +1 -0
- package/dist/core/check-stale-index.d.ts +35 -0
- package/dist/core/check-stale-index.d.ts.map +1 -0
- package/dist/core/check-stale-index.js +132 -0
- package/dist/core/check-stale-index.js.map +1 -0
- package/dist/core/check-workflow-drift.d.ts +49 -0
- package/dist/core/check-workflow-drift.d.ts.map +1 -0
- package/dist/core/check-workflow-drift.js +226 -0
- package/dist/core/check-workflow-drift.js.map +1 -0
- package/dist/core/context-budget.d.ts +9 -0
- package/dist/core/context-budget.d.ts.map +1 -0
- package/dist/core/context-budget.js +46 -0
- package/dist/core/context-budget.js.map +1 -0
- package/dist/core/event-log.d.ts +44 -0
- package/dist/core/event-log.d.ts.map +1 -0
- package/dist/core/event-log.js +169 -0
- package/dist/core/event-log.js.map +1 -0
- package/dist/core/evolution/event-clusters.d.ts +4 -0
- package/dist/core/evolution/event-clusters.d.ts.map +1 -0
- package/dist/core/evolution/event-clusters.js +82 -0
- package/dist/core/evolution/event-clusters.js.map +1 -0
- package/dist/core/evolution/recommendation-renderer.d.ts +3 -0
- package/dist/core/evolution/recommendation-renderer.d.ts.map +1 -0
- package/dist/core/evolution/recommendation-renderer.js +24 -0
- package/dist/core/evolution/recommendation-renderer.js.map +1 -0
- package/dist/core/evolution/review-failure-clusters.d.ts +10 -0
- package/dist/core/evolution/review-failure-clusters.d.ts.map +1 -0
- package/dist/core/evolution/review-failure-clusters.js +30 -0
- package/dist/core/evolution/review-failure-clusters.js.map +1 -0
- package/dist/core/evolution/suggestions.d.ts +24 -0
- package/dist/core/evolution/suggestions.d.ts.map +1 -0
- package/dist/core/evolution/suggestions.js +11 -0
- package/dist/core/evolution/suggestions.js.map +1 -0
- package/dist/core/gate-policy.d.ts +20 -0
- package/dist/core/gate-policy.d.ts.map +1 -0
- package/dist/core/gate-policy.js +64 -0
- package/dist/core/gate-policy.js.map +1 -0
- package/dist/core/harness-scaffold.d.ts +29 -0
- package/dist/core/harness-scaffold.d.ts.map +1 -0
- package/dist/core/harness-scaffold.js +53 -0
- package/dist/core/harness-scaffold.js.map +1 -0
- package/dist/core/hook-runner.d.ts +69 -0
- package/dist/core/hook-runner.d.ts.map +1 -0
- package/dist/core/hook-runner.js +95 -0
- package/dist/core/hook-runner.js.map +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/install-metadata.d.ts +15 -0
- package/dist/core/install-metadata.d.ts.map +1 -1
- package/dist/core/install-metadata.js +11 -0
- package/dist/core/install-metadata.js.map +1 -1
- package/dist/core/is-hook-script.d.ts +2 -0
- package/dist/core/is-hook-script.d.ts.map +1 -0
- package/dist/core/is-hook-script.js +45 -0
- package/dist/core/is-hook-script.js.map +1 -0
- package/dist/core/pack-manifest.d.ts +48 -0
- package/dist/core/pack-manifest.d.ts.map +1 -0
- package/dist/core/pack-manifest.js +126 -0
- package/dist/core/pack-manifest.js.map +1 -0
- package/dist/core/pack-resolver.d.ts +18 -0
- package/dist/core/pack-resolver.d.ts.map +1 -0
- package/dist/core/pack-resolver.js +144 -0
- package/dist/core/pack-resolver.js.map +1 -0
- package/dist/core/portability-matrix.d.ts +17 -0
- package/dist/core/portability-matrix.d.ts.map +1 -0
- package/dist/core/portability-matrix.js +31 -0
- package/dist/core/portability-matrix.js.map +1 -0
- package/dist/core/simulation-runner.d.ts +93 -0
- package/dist/core/simulation-runner.d.ts.map +1 -0
- package/dist/core/simulation-runner.js +161 -0
- package/dist/core/simulation-runner.js.map +1 -0
- package/dist/core/smart-update.d.ts +24 -0
- package/dist/core/smart-update.d.ts.map +1 -1
- package/dist/core/smart-update.js +69 -0
- package/dist/core/smart-update.js.map +1 -1
- package/dist/core/usage/usage-analyzer.d.ts +18 -0
- package/dist/core/usage/usage-analyzer.d.ts.map +1 -0
- package/dist/core/usage/usage-analyzer.js +41 -0
- package/dist/core/usage/usage-analyzer.js.map +1 -0
- package/dist/core/validate-install.d.ts.map +1 -1
- package/dist/core/validate-install.js +3 -1
- package/dist/core/validate-install.js.map +1 -1
- package/dist/index.js +175 -4
- package/dist/index.js.map +1 -1
- package/dist/memory/archive.d.ts +9 -0
- package/dist/memory/archive.d.ts.map +1 -0
- package/dist/memory/archive.js +42 -0
- package/dist/memory/archive.js.map +1 -0
- package/dist/memory/compact.d.ts +9 -0
- package/dist/memory/compact.d.ts.map +1 -0
- package/dist/memory/compact.js +33 -0
- package/dist/memory/compact.js.map +1 -0
- package/dist/memory/conflicts.d.ts +8 -0
- package/dist/memory/conflicts.d.ts.map +1 -0
- package/dist/memory/conflicts.js +28 -0
- package/dist/memory/conflicts.js.map +1 -0
- package/dist/memory/promote.d.ts +8 -0
- package/dist/memory/promote.d.ts.map +1 -0
- package/dist/memory/promote.js +10 -0
- package/dist/memory/promote.js.map +1 -0
- package/dist/memory/store-utils.d.ts +14 -0
- package/dist/memory/store-utils.d.ts.map +1 -0
- package/dist/memory/store-utils.js +44 -0
- package/dist/memory/store-utils.js.map +1 -0
- package/dist/migrate/types.d.ts +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
export class WorkflowSpecError extends Error {
|
|
5
|
+
kind;
|
|
6
|
+
/** "missing" = file absent (downgradable to WARN in a non-scoped run);
|
|
7
|
+
* "unparseable"/"malformed" = present but broken (always a FAIL). */
|
|
8
|
+
constructor(message, kind = "unparseable") {
|
|
9
|
+
super(message);
|
|
10
|
+
this.kind = kind;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Pull the second path segment out of a `tasks/<dir>/...` glob. */
|
|
14
|
+
function outputDirOf(glob) {
|
|
15
|
+
const m = /^tasks\/([A-Za-z0-9_-]+)\//.exec(glob.trim());
|
|
16
|
+
return m ? m[1] : null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse `.claude/workflow.yaml` into a CanonicalSpec. Throws WorkflowSpecError
|
|
20
|
+
* if the file is missing or unparseable — NEVER returns a degenerate "empty"
|
|
21
|
+
* spec that would let drift pass silently.
|
|
22
|
+
*/
|
|
23
|
+
export function loadWorkflowSpec(projectRoot) {
|
|
24
|
+
const specPath = path.join(projectRoot, ".claude", "workflow.yaml");
|
|
25
|
+
if (!fs.existsSync(specPath)) {
|
|
26
|
+
throw new WorkflowSpecError(`Canonical workflow spec missing: ${specPath}`, "missing");
|
|
27
|
+
}
|
|
28
|
+
let raw;
|
|
29
|
+
try {
|
|
30
|
+
raw = yaml.load(fs.readFileSync(specPath, "utf-8"));
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
34
|
+
throw new WorkflowSpecError(`Canonical workflow spec is unparseable (${specPath}): ${msg}`, "unparseable");
|
|
35
|
+
}
|
|
36
|
+
if (!raw || typeof raw !== "object" || !Array.isArray(raw.phases)) {
|
|
37
|
+
throw new WorkflowSpecError(`Canonical workflow spec malformed (no phases): ${specPath}`, "malformed");
|
|
38
|
+
}
|
|
39
|
+
const phaseNames = new Set();
|
|
40
|
+
const nameById = new Map();
|
|
41
|
+
const integerPhaseIds = [];
|
|
42
|
+
let reflectLeads = [];
|
|
43
|
+
for (const phase of raw.phases) {
|
|
44
|
+
if (phase.id === undefined || !phase.name)
|
|
45
|
+
continue;
|
|
46
|
+
const id = String(phase.id);
|
|
47
|
+
phaseNames.add(phase.name);
|
|
48
|
+
nameById.set(id, phase.name);
|
|
49
|
+
if (/^\d+$/.test(id))
|
|
50
|
+
integerPhaseIds.push(Number(id));
|
|
51
|
+
if (phase.name === "Reflect") {
|
|
52
|
+
reflectLeads = (phase.leads ?? (phase.lead ? [phase.lead] : [])).map((l) => String(l));
|
|
53
|
+
}
|
|
54
|
+
for (const sub of phase.substeps ?? []) {
|
|
55
|
+
if (sub.id === undefined || !sub.name)
|
|
56
|
+
continue;
|
|
57
|
+
phaseNames.add(sub.name);
|
|
58
|
+
nameById.set(String(sub.id), sub.name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const gateOutput = new Map();
|
|
62
|
+
const outputDirs = new Set();
|
|
63
|
+
for (const gate of raw.gates ?? []) {
|
|
64
|
+
if (gate.id && gate.required_output) {
|
|
65
|
+
gateOutput.set(gate.id, gate.required_output);
|
|
66
|
+
const dir = outputDirOf(gate.required_output);
|
|
67
|
+
if (dir)
|
|
68
|
+
outputDirs.add(dir);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const phase of raw.phases) {
|
|
72
|
+
for (const glob of phase.required_outputs ?? []) {
|
|
73
|
+
const dir = outputDirOf(glob);
|
|
74
|
+
if (dir)
|
|
75
|
+
outputDirs.add(dir);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (raw.contract_substep?.required_output) {
|
|
79
|
+
const dir = outputDirOf(raw.contract_substep.required_output);
|
|
80
|
+
if (dir)
|
|
81
|
+
outputDirs.add(dir);
|
|
82
|
+
}
|
|
83
|
+
const sources = (raw.sources ?? []).map(String);
|
|
84
|
+
return { phaseNames, nameById, integerPhaseIds, gateOutput, outputDirs, reflectLeads, sources };
|
|
85
|
+
}
|
|
86
|
+
const PHASE_NAME_RE = /Phase\s+(\d+(?:\.\d+)?)\s+\(?([A-Za-z][A-Za-z]+)/g;
|
|
87
|
+
// Matches only the inline flow-sequence form `applies_to: [...]`. YAML block
|
|
88
|
+
// sequences (one id per line) are not detected — an accepted token-level limit.
|
|
89
|
+
const APPLIES_TO_RE = /applies_to:\s*\[([^\]]*)\]/;
|
|
90
|
+
const TASKS_PATH_RE = /tasks\/([A-Za-z0-9_-]+)\//g;
|
|
91
|
+
/** Scan one prose file for tokens that contradict the canonical spec. */
|
|
92
|
+
export function scanForViolations(spec, projectRoot, relPath) {
|
|
93
|
+
const abs = path.join(projectRoot, relPath);
|
|
94
|
+
if (!fs.existsSync(abs)) {
|
|
95
|
+
return [{ file: relPath, line: 0, found: "missing source file", expected: "file listed in workflow.yaml sources must exist" }];
|
|
96
|
+
}
|
|
97
|
+
const violations = [];
|
|
98
|
+
const lines = fs.readFileSync(abs, "utf-8").split("\n");
|
|
99
|
+
// Confusable singular forms of the canonical output dirs (the realistic typo).
|
|
100
|
+
const dirTypos = new Map(); // typo -> canonical
|
|
101
|
+
for (const dir of spec.outputDirs) {
|
|
102
|
+
if (dir.endsWith("s"))
|
|
103
|
+
dirTypos.set(dir.slice(0, -1), dir);
|
|
104
|
+
}
|
|
105
|
+
lines.forEach((text, idx) => {
|
|
106
|
+
const lineNo = idx + 1;
|
|
107
|
+
// 1. Phase id ↔ name binding. Only a contradiction when the word after
|
|
108
|
+
// "Phase N" is itself an EXACT canonical phase name bound to a different
|
|
109
|
+
// id (e.g. "Phase 4 Build"). Prose like "Phase 3 GREEN" or "Phase 2
|
|
110
|
+
// optional" is not a name claim and is correctly ignored.
|
|
111
|
+
for (const m of text.matchAll(PHASE_NAME_RE)) {
|
|
112
|
+
const id = m[1];
|
|
113
|
+
const word = m[2];
|
|
114
|
+
if (spec.phaseNames.has(word) && spec.nameById.get(id) !== word) {
|
|
115
|
+
const expected = spec.nameById.get(id);
|
|
116
|
+
violations.push({
|
|
117
|
+
file: relPath,
|
|
118
|
+
line: lineNo,
|
|
119
|
+
found: `Phase ${id} ${word}`,
|
|
120
|
+
expected: expected ? `Phase ${id} ${expected}` : `${word} is canonical Phase ${[...spec.nameById].find(([, n]) => n === word)?.[0]}, not ${id}`,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 2. Required-output path typo (e.g. tasks/review/ for tasks/reviews/).
|
|
125
|
+
for (const m of text.matchAll(TASKS_PATH_RE)) {
|
|
126
|
+
const dir = m[1];
|
|
127
|
+
const canonical = dirTypos.get(dir);
|
|
128
|
+
if (canonical) {
|
|
129
|
+
violations.push({ file: relPath, line: lineNo, found: `tasks/${dir}/`, expected: `tasks/${canonical}/` });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// 3. Output glob bound to the wrong gate. Only when a SINGLE gate is on the
|
|
133
|
+
// line — a line that names both gates is a legitimate summary, not drift.
|
|
134
|
+
const reviewOut = spec.gateOutput.get("gate_2");
|
|
135
|
+
const planOut = spec.gateOutput.get("gate_1");
|
|
136
|
+
const hasGate1 = /\bGate\s*1\b/.test(text);
|
|
137
|
+
const hasGate2 = /\bGate\s*2\b/.test(text);
|
|
138
|
+
if (hasGate1 && !hasGate2 && reviewOut && new RegExp(globToProbe(reviewOut)).test(text)) {
|
|
139
|
+
violations.push({ file: relPath, line: lineNo, found: `Gate 1 referencing ${reviewOut}`, expected: `Gate 2 owns ${reviewOut}` });
|
|
140
|
+
}
|
|
141
|
+
if (hasGate2 && !hasGate1 && planOut && new RegExp(globToProbe(planOut)).test(text)) {
|
|
142
|
+
violations.push({ file: relPath, line: lineNo, found: `Gate 2 referencing ${planOut}`, expected: `Gate 1 owns ${planOut}` });
|
|
143
|
+
}
|
|
144
|
+
// 4. applies_to must enumerate every integer phase id.
|
|
145
|
+
const am = APPLIES_TO_RE.exec(text);
|
|
146
|
+
if (am) {
|
|
147
|
+
const present = new Set((am[1].match(/\d+/g) ?? []).map(Number));
|
|
148
|
+
const missing = spec.integerPhaseIds.filter((n) => !present.has(n));
|
|
149
|
+
if (missing.length > 0) {
|
|
150
|
+
violations.push({ file: relPath, line: lineNo, found: `applies_to omits Phase ${missing.join(", ")}`, expected: `applies_to includes Phase ${spec.integerPhaseIds.join(", ")}` });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
// 5. Reflect lead list (file-level). A file that enumerates the Reflect leads
|
|
155
|
+
// (mentions Reflect and ≥2 of the canonical leads) must carry ALL of them.
|
|
156
|
+
// Gating on ≥2 avoids flagging files that mention one agent incidentally.
|
|
157
|
+
const body = lines.join("\n");
|
|
158
|
+
if (/\bReflect\b/.test(body)) {
|
|
159
|
+
const present = spec.reflectLeads.filter((l) => body.includes(l));
|
|
160
|
+
if (present.length >= 2 && present.length < spec.reflectLeads.length) {
|
|
161
|
+
const missingLeads = spec.reflectLeads.filter((l) => !body.includes(l));
|
|
162
|
+
violations.push({ file: relPath, line: 0, found: `Reflect leads missing ${missingLeads.join(", ")}`, expected: `Reflect leads = ${spec.reflectLeads.join(" + ")}` });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return violations;
|
|
166
|
+
}
|
|
167
|
+
/** Turn a glob into a loose substring probe (escape regex metachars, `*`→`.*`). */
|
|
168
|
+
function globToProbe(glob) {
|
|
169
|
+
return glob.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Run the full drift check. Returns CheckResults under the "Workflow" section:
|
|
173
|
+
* a hard FAIL if the spec can't load, a per-source PASS/FAIL otherwise, and a
|
|
174
|
+
* spec-level FAIL if any canonical phase name appears in NO source file.
|
|
175
|
+
*/
|
|
176
|
+
export function checkWorkflowDrift(projectRoot, opts = {}) {
|
|
177
|
+
let spec;
|
|
178
|
+
try {
|
|
179
|
+
spec = loadWorkflowSpec(projectRoot);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
183
|
+
// A wholly-absent spec may downgrade to WARN (un-upgraded install); a
|
|
184
|
+
// present-but-broken spec is always a FAIL.
|
|
185
|
+
const kind = error instanceof WorkflowSpecError ? error.kind : "unparseable";
|
|
186
|
+
const status = kind === "missing" ? (opts.missingSpecSeverity ?? "fail") : "fail";
|
|
187
|
+
const detail = kind === "missing" && status === "warn" ? `${msg} — run \`mewkit upgrade\` to install it` : msg;
|
|
188
|
+
return [{ name: "Workflow spec loads", status, detail, section: "Workflow" }];
|
|
189
|
+
}
|
|
190
|
+
const results = [];
|
|
191
|
+
const seenNames = new Set();
|
|
192
|
+
for (const rel of spec.sources) {
|
|
193
|
+
const violations = scanForViolations(spec, projectRoot, rel);
|
|
194
|
+
// Record which canonical names this file mentions (for global presence).
|
|
195
|
+
const abs = path.join(projectRoot, rel);
|
|
196
|
+
if (fs.existsSync(abs)) {
|
|
197
|
+
const body = fs.readFileSync(abs, "utf-8");
|
|
198
|
+
for (const n of spec.phaseNames)
|
|
199
|
+
if (body.includes(n))
|
|
200
|
+
seenNames.add(n);
|
|
201
|
+
}
|
|
202
|
+
if (violations.length === 0) {
|
|
203
|
+
results.push({ name: `No drift: ${rel}`, status: "pass", detail: rel, section: "Workflow" });
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
const detail = violations
|
|
207
|
+
.map((v) => `${v.file}:${v.line} found "${v.found}" — expected "${v.expected}"`)
|
|
208
|
+
.join("\n ");
|
|
209
|
+
results.push({ name: `Drift in ${rel}`, status: "fail", detail, section: "Workflow" });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const absentNames = [...spec.phaseNames].filter((n) => !seenNames.has(n));
|
|
213
|
+
if (absentNames.length > 0) {
|
|
214
|
+
results.push({
|
|
215
|
+
name: "Canonical phase coverage",
|
|
216
|
+
status: "fail",
|
|
217
|
+
detail: `Phase name(s) defined in workflow.yaml but absent from all sources: ${absentNames.join(", ")}`,
|
|
218
|
+
section: "Workflow",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
results.push({ name: "Canonical phase coverage", status: "pass", detail: `${spec.phaseNames.size} phase names present across sources`, section: "Workflow" });
|
|
223
|
+
}
|
|
224
|
+
return results;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=check-workflow-drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-workflow-drift.js","sourceRoot":"","sources":["../../src/core/check-workflow-drift.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ContextBudgetReport {
|
|
2
|
+
profile: string;
|
|
3
|
+
files: number;
|
|
4
|
+
lines: number;
|
|
5
|
+
tokens: number;
|
|
6
|
+
}
|
|
7
|
+
/** Estimate the loadable context size for a profile. */
|
|
8
|
+
export declare function computeContextBudget(claudeDir: string, profile: string): ContextBudgetReport;
|
|
9
|
+
//# sourceMappingURL=context-budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-budget.d.ts","sourceRoot":"","sources":["../../src/core/context-budget.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAaD,wDAAwD;AACxD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAiB5F"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Lightweight per-profile context-budget estimator. Sums line counts and a cheap
|
|
2
|
+
// token estimate (chars/4) over a profile's *loadable* set — the always-on rules,
|
|
3
|
+
// skill SKILL.md entrypoints, agents, and commands the model pulls into context —
|
|
4
|
+
// NOT every reference/script/asset file (those load on demand). Proves "core is
|
|
5
|
+
// small and auditable" and backs the CI guardrail. Read-only; no untrusted exec.
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { loadPackManifest } from "./pack-manifest.js";
|
|
9
|
+
import { resolveProfile } from "./pack-resolver.js";
|
|
10
|
+
/** A path the model loads into context (vs. on-demand references/scripts/assets). */
|
|
11
|
+
function isLoadable(path) {
|
|
12
|
+
if (path === "CLAUDE.md")
|
|
13
|
+
return true;
|
|
14
|
+
if (/^rules\/.+\.md$/.test(path))
|
|
15
|
+
return true;
|
|
16
|
+
if (/^rules-conditional\/.+\.md$/.test(path))
|
|
17
|
+
return true;
|
|
18
|
+
if (/^agents\/(?!.*_INDEX\.md$).+\.md$/.test(path))
|
|
19
|
+
return true;
|
|
20
|
+
if (/^commands\/mk\/.+\.md$/.test(path))
|
|
21
|
+
return true;
|
|
22
|
+
if (/^skills\/[^/]+\/SKILL\.md$/.test(path))
|
|
23
|
+
return true;
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
/** Estimate the loadable context size for a profile. */
|
|
27
|
+
export function computeContextBudget(claudeDir, profile) {
|
|
28
|
+
const manifest = loadPackManifest(claudeDir);
|
|
29
|
+
const paths = [...resolveProfile(claudeDir, manifest, profile)].filter(isLoadable);
|
|
30
|
+
let lines = 0;
|
|
31
|
+
let chars = 0;
|
|
32
|
+
for (const rel of paths) {
|
|
33
|
+
// CLAUDE.md lives at the project root, not inside .claude/.
|
|
34
|
+
const abs = rel === "CLAUDE.md" ? join(claudeDir, "..", "CLAUDE.md") : join(claudeDir, rel);
|
|
35
|
+
try {
|
|
36
|
+
const body = readFileSync(abs, "utf-8");
|
|
37
|
+
lines += body.split("\n").length;
|
|
38
|
+
chars += body.length;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// unreadable/absent loadable file — skip; resolution already validated membership
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { profile, files: paths.length, lines, tokens: Math.ceil(chars / 4) };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=context-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-budget.js","sourceRoot":"","sources":["../../src/core/context-budget.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,kFAAkF;AAClF,kFAAkF;AAClF,gFAAgF;AAChF,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AASpD,qFAAqF;AACrF,SAAS,UAAU,CAAC,IAAY;IAC/B,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,IAAI,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,OAAe;IACtE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,GAAG,cAAc,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACzB,4DAA4D;QAC5D,MAAM,GAAG,GAAG,GAAG,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC5F,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACxC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YACjC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACR,kFAAkF;QACnF,CAAC;IACF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reader for the canonical event log at `.claude/memory/trace-log.jsonl`, the
|
|
3
|
+
* append-only JSONL stream written by `append-trace.sh`. Consumed by `reflect`
|
|
4
|
+
* and `health`. Tolerant by contract: it NEVER throws — malformed and oversized
|
|
5
|
+
* lines are skipped and tallied, unreadable files are ignored.
|
|
6
|
+
*
|
|
7
|
+
* Schema: see `.claude/skills/trace-analyze/references/trace-schema.md`.
|
|
8
|
+
*/
|
|
9
|
+
/** Event types with a live emitter, plus the reserved (no-emitter-yet) ones. */
|
|
10
|
+
export declare const KNOWN_EVENT_TYPES: readonly ["file_edited", "harness_run_start", "contract_signed", "verdict_written", "cost_sample", "session_end", "dead_weight_audit_needed", "benchmark_result", "gate.blocked", "privacy.blocked", "injection.blocked", "hook.failed", "skill.invoked", "memory.write"];
|
|
11
|
+
export type KnownEventType = (typeof KNOWN_EVENT_TYPES)[number];
|
|
12
|
+
/** Reserved types have no emitter yet; consumers render `N/A`, never a metric. */
|
|
13
|
+
export declare const RESERVED_EVENT_TYPES: Set<string>;
|
|
14
|
+
export interface EventRecord {
|
|
15
|
+
schema_version: string;
|
|
16
|
+
ts: string;
|
|
17
|
+
event: string;
|
|
18
|
+
run_id?: string;
|
|
19
|
+
harness_version?: string;
|
|
20
|
+
model?: string;
|
|
21
|
+
density?: string;
|
|
22
|
+
data: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface ReadEventsOptions {
|
|
25
|
+
/** Time window: `Nd` (days), `Nh` (hours), or an ISO-8601 instant. */
|
|
26
|
+
since?: string;
|
|
27
|
+
/** Keep only events whose `data.task` equals this id. */
|
|
28
|
+
task?: string;
|
|
29
|
+
/** Keep only these event types. */
|
|
30
|
+
types?: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface ReadEventsResult {
|
|
33
|
+
events: EventRecord[];
|
|
34
|
+
/** Count of lines skipped: failed JSON.parse OR exceeded the 64 KiB guard. */
|
|
35
|
+
malformed: number;
|
|
36
|
+
}
|
|
37
|
+
/** Resolve a `since` spec to an epoch-ms lower bound, or null if absent/invalid. */
|
|
38
|
+
export declare function parseSince(since: string | undefined): number | null;
|
|
39
|
+
/**
|
|
40
|
+
* Read events from `<claudeDir>/memory/trace-log.jsonl` (+ in-window rotated `.gz`
|
|
41
|
+
* archives), filtered by `since` / `task` / `types`. Never throws.
|
|
42
|
+
*/
|
|
43
|
+
export declare function readEvents(claudeDir: string, opts?: ReadEventsOptions): ReadEventsResult;
|
|
44
|
+
//# sourceMappingURL=event-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-log.d.ts","sourceRoot":"","sources":["../../src/core/event-log.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,gFAAgF;AAChF,eAAO,MAAM,iBAAiB,2QAkBpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,aAAqD,CAAC;AAEvF,MAAM,WAAW,WAAW;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IACjC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CAClB;AAKD,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAUnE;AAoFD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CA2B5F"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import zlib from "node:zlib";
|
|
4
|
+
/**
|
|
5
|
+
* Reader for the canonical event log at `.claude/memory/trace-log.jsonl`, the
|
|
6
|
+
* append-only JSONL stream written by `append-trace.sh`. Consumed by `reflect`
|
|
7
|
+
* and `health`. Tolerant by contract: it NEVER throws — malformed and oversized
|
|
8
|
+
* lines are skipped and tallied, unreadable files are ignored.
|
|
9
|
+
*
|
|
10
|
+
* Schema: see `.claude/skills/trace-analyze/references/trace-schema.md`.
|
|
11
|
+
*/
|
|
12
|
+
/** Event types with a live emitter, plus the reserved (no-emitter-yet) ones. */
|
|
13
|
+
export const KNOWN_EVENT_TYPES = [
|
|
14
|
+
// existing
|
|
15
|
+
"file_edited",
|
|
16
|
+
"harness_run_start",
|
|
17
|
+
"contract_signed",
|
|
18
|
+
"verdict_written",
|
|
19
|
+
"cost_sample",
|
|
20
|
+
"session_end",
|
|
21
|
+
"dead_weight_audit_needed",
|
|
22
|
+
"benchmark_result",
|
|
23
|
+
// Phase 4 — gate/hook taxonomy
|
|
24
|
+
"gate.blocked",
|
|
25
|
+
"privacy.blocked",
|
|
26
|
+
"injection.blocked",
|
|
27
|
+
"hook.failed",
|
|
28
|
+
// reserved — no emitter today (consumers must render N/A, never zero/list)
|
|
29
|
+
"skill.invoked",
|
|
30
|
+
"memory.write",
|
|
31
|
+
];
|
|
32
|
+
/** Reserved types have no emitter yet; consumers render `N/A`, never a metric. */
|
|
33
|
+
export const RESERVED_EVENT_TYPES = new Set(["skill.invoked", "memory.write"]);
|
|
34
|
+
/** Reject any single line larger than this (defends against a torn/huge line). */
|
|
35
|
+
const MAX_LINE_BYTES = 64 * 1024;
|
|
36
|
+
/** Resolve a `since` spec to an epoch-ms lower bound, or null if absent/invalid. */
|
|
37
|
+
export function parseSince(since) {
|
|
38
|
+
if (!since)
|
|
39
|
+
return null;
|
|
40
|
+
const rel = since.match(/^(\d+)([dh])$/);
|
|
41
|
+
if (rel) {
|
|
42
|
+
const n = Number(rel[1]);
|
|
43
|
+
const unitMs = rel[2] === "d" ? 86_400_000 : 3_600_000;
|
|
44
|
+
return Date.now() - n * unitMs;
|
|
45
|
+
}
|
|
46
|
+
const parsed = Date.parse(since);
|
|
47
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
48
|
+
}
|
|
49
|
+
function isRecord(value) {
|
|
50
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
51
|
+
}
|
|
52
|
+
/** Normalize a parsed JSON line into an EventRecord, or null if it isn't one. */
|
|
53
|
+
function toEventRecord(parsed) {
|
|
54
|
+
if (!isRecord(parsed))
|
|
55
|
+
return null;
|
|
56
|
+
if (typeof parsed.event !== "string" || typeof parsed.ts !== "string")
|
|
57
|
+
return null;
|
|
58
|
+
const data = isRecord(parsed.data) ? parsed.data : {};
|
|
59
|
+
return {
|
|
60
|
+
schema_version: typeof parsed.schema_version === "string" ? parsed.schema_version : "",
|
|
61
|
+
ts: parsed.ts,
|
|
62
|
+
event: parsed.event,
|
|
63
|
+
run_id: typeof parsed.run_id === "string" ? parsed.run_id : undefined,
|
|
64
|
+
harness_version: typeof parsed.harness_version === "string" ? parsed.harness_version : undefined,
|
|
65
|
+
model: typeof parsed.model === "string" ? parsed.model : undefined,
|
|
66
|
+
density: typeof parsed.density === "string" ? parsed.density : undefined,
|
|
67
|
+
data,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Parse one log file's text into records, mutating the accumulator + malformed tally. */
|
|
71
|
+
function parseLines(text, out, state) {
|
|
72
|
+
for (const line of text.split("\n")) {
|
|
73
|
+
if (line.trim() === "")
|
|
74
|
+
continue;
|
|
75
|
+
if (Buffer.byteLength(line, "utf8") > MAX_LINE_BYTES) {
|
|
76
|
+
state.malformed++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
let parsed;
|
|
80
|
+
try {
|
|
81
|
+
parsed = JSON.parse(line);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
state.malformed++;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const record = toEventRecord(parsed);
|
|
88
|
+
if (record)
|
|
89
|
+
out.push(record);
|
|
90
|
+
else
|
|
91
|
+
state.malformed++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Discover the active log + any rotated archives whose mtime is in the window. */
|
|
95
|
+
function discoverLogFiles(memoryDir, sinceMs) {
|
|
96
|
+
const active = path.join(memoryDir, "trace-log.jsonl");
|
|
97
|
+
const files = [];
|
|
98
|
+
let entries = [];
|
|
99
|
+
try {
|
|
100
|
+
entries = fs.readdirSync(memoryDir);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return fs.existsSync(active) ? [active] : [];
|
|
104
|
+
}
|
|
105
|
+
if (entries.includes("trace-log.jsonl"))
|
|
106
|
+
files.push(active);
|
|
107
|
+
// Rotated archives: trace-log.<stamp>.jsonl(.gz). Fold one in unconditionally
|
|
108
|
+
// unless its mtime predates the window (its events are all older than `since`).
|
|
109
|
+
const rotated = /^trace-log\.[^/]+\.jsonl(\.gz)?$/;
|
|
110
|
+
for (const name of entries) {
|
|
111
|
+
if (name === "trace-log.jsonl" || !rotated.test(name))
|
|
112
|
+
continue;
|
|
113
|
+
const full = path.join(memoryDir, name);
|
|
114
|
+
if (sinceMs !== null) {
|
|
115
|
+
try {
|
|
116
|
+
if (fs.statSync(full).mtimeMs < sinceMs)
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
files.push(full);
|
|
124
|
+
}
|
|
125
|
+
return files;
|
|
126
|
+
}
|
|
127
|
+
function readFileText(file) {
|
|
128
|
+
try {
|
|
129
|
+
if (file.endsWith(".gz")) {
|
|
130
|
+
return zlib.gunzipSync(fs.readFileSync(file)).toString("utf8");
|
|
131
|
+
}
|
|
132
|
+
return fs.readFileSync(file, "utf8");
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Read events from `<claudeDir>/memory/trace-log.jsonl` (+ in-window rotated `.gz`
|
|
140
|
+
* archives), filtered by `since` / `task` / `types`. Never throws.
|
|
141
|
+
*/
|
|
142
|
+
export function readEvents(claudeDir, opts = {}) {
|
|
143
|
+
const memoryDir = path.join(claudeDir, "memory");
|
|
144
|
+
const sinceMs = parseSince(opts.since);
|
|
145
|
+
const typeSet = opts.types && opts.types.length > 0 ? new Set(opts.types) : null;
|
|
146
|
+
const collected = [];
|
|
147
|
+
const state = { malformed: 0 };
|
|
148
|
+
for (const file of discoverLogFiles(memoryDir, sinceMs)) {
|
|
149
|
+
const text = readFileText(file);
|
|
150
|
+
if (text !== null)
|
|
151
|
+
parseLines(text, collected, state);
|
|
152
|
+
}
|
|
153
|
+
const events = collected.filter((e) => {
|
|
154
|
+
if (typeSet && !typeSet.has(e.event))
|
|
155
|
+
return false;
|
|
156
|
+
if (opts.task !== undefined && e.data.task !== opts.task)
|
|
157
|
+
return false;
|
|
158
|
+
if (sinceMs !== null) {
|
|
159
|
+
const eventMs = Date.parse(e.ts);
|
|
160
|
+
if (Number.isNaN(eventMs) || eventMs < sinceMs)
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
});
|
|
165
|
+
// Chronological order regardless of file-read order.
|
|
166
|
+
events.sort((a, b) => Date.parse(a.ts) - Date.parse(b.ts));
|
|
167
|
+
return { events, malformed: state.malformed };
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=event-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-log.js","sourceRoot":"","sources":["../../src/core/event-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EventRecord } from "../event-log.js";
|
|
2
|
+
import { type EvolutionSuggestion } from "./suggestions.js";
|
|
3
|
+
export declare function suggestionsFromEvents(events: EventRecord[], malformed: number): EvolutionSuggestion[];
|
|
4
|
+
//# sourceMappingURL=event-clusters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-clusters.d.ts","sourceRoot":"","sources":["../../../src/core/evolution/event-clusters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAc5E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,EAAE,CA2ErG"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { clusterReviewFailures } from "./review-failure-clusters.js";
|
|
2
|
+
import { makeSuggestion } from "./suggestions.js";
|
|
3
|
+
function str(value, fallback = "unknown") {
|
|
4
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback;
|
|
5
|
+
}
|
|
6
|
+
function bump(map, key) {
|
|
7
|
+
map.set(key, (map.get(key) ?? 0) + 1);
|
|
8
|
+
}
|
|
9
|
+
function repeated(map, min = 2) {
|
|
10
|
+
return [...map.entries()].filter(([, count]) => count >= min).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
|
|
11
|
+
}
|
|
12
|
+
export function suggestionsFromEvents(events, malformed) {
|
|
13
|
+
const suggestions = [];
|
|
14
|
+
const hookFailures = new Map();
|
|
15
|
+
const gateBlocks = new Map();
|
|
16
|
+
for (const event of events) {
|
|
17
|
+
if (event.event === "hook.failed") {
|
|
18
|
+
bump(hookFailures, `${str(event.data.hook)} exit ${str(event.data.exit_code, "?")}`);
|
|
19
|
+
}
|
|
20
|
+
if (event.event === "gate.blocked") {
|
|
21
|
+
bump(gateBlocks, `${str(event.data.gate)}: ${str(event.data.reason, "")}`);
|
|
22
|
+
}
|
|
23
|
+
if (event.event === "dead_weight_audit_needed") {
|
|
24
|
+
suggestions.push(makeSuggestion({
|
|
25
|
+
kind: "pack-pruning",
|
|
26
|
+
title: "Run a dead-weight audit",
|
|
27
|
+
evidence: [{ source: "event-log", detail: "dead_weight_audit_needed event observed", count: 1 }],
|
|
28
|
+
confidence: 0.72,
|
|
29
|
+
impact: "medium",
|
|
30
|
+
risk: "low",
|
|
31
|
+
proposedAction: "Run `mewkit evolve report` and review pack/skill pruning candidates.",
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for (const [label, count] of repeated(hookFailures)) {
|
|
36
|
+
suggestions.push(makeSuggestion({
|
|
37
|
+
kind: "hook-test",
|
|
38
|
+
title: `Add regression coverage for ${label}`,
|
|
39
|
+
evidence: [{ source: "event-log", detail: label, count }],
|
|
40
|
+
confidence: Math.min(0.95, 0.55 + count * 0.1),
|
|
41
|
+
impact: "high",
|
|
42
|
+
risk: "low",
|
|
43
|
+
proposedAction: "Add or extend a `mewkit simulate` scenario and a configured-hook regression test.",
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
for (const [label, count] of repeated(gateBlocks, 3)) {
|
|
47
|
+
suggestions.push(makeSuggestion({
|
|
48
|
+
kind: "policy",
|
|
49
|
+
title: `Review gate policy for repeated ${label}`,
|
|
50
|
+
evidence: [{ source: "event-log", detail: label, count }],
|
|
51
|
+
confidence: Math.min(0.9, 0.45 + count * 0.08),
|
|
52
|
+
impact: "medium",
|
|
53
|
+
risk: "medium",
|
|
54
|
+
proposedAction: "Run `mewkit policy explain`; consider a clearer policy profile or docs clarification.",
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
for (const cluster of clusterReviewFailures(events)) {
|
|
58
|
+
const diversity = cluster.tasks.length > 1 ? " across multiple tasks" : "";
|
|
59
|
+
suggestions.push(makeSuggestion({
|
|
60
|
+
kind: "review-promotion",
|
|
61
|
+
title: `Promote repeated review failure: ${cluster.key}`,
|
|
62
|
+
evidence: [{ source: "verdict_written", detail: `${cluster.count} failure(s)${diversity}`, count: cluster.count }],
|
|
63
|
+
confidence: Math.min(0.92, 0.5 + cluster.count * 0.12 + (cluster.tasks.length > 1 ? 0.1 : 0)),
|
|
64
|
+
impact: "high",
|
|
65
|
+
risk: "medium",
|
|
66
|
+
proposedAction: "Generate a candidate checklist/rule via `mewkit memory promote --review-failures`.",
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
if (malformed > 0) {
|
|
70
|
+
suggestions.push(makeSuggestion({
|
|
71
|
+
kind: "trace-hardening",
|
|
72
|
+
title: "Harden trace writer or reader against malformed rows",
|
|
73
|
+
evidence: [{ source: "event-log", detail: "malformed or oversized rows skipped", count: malformed }],
|
|
74
|
+
confidence: Math.min(0.9, 0.5 + malformed * 0.05),
|
|
75
|
+
impact: "medium",
|
|
76
|
+
risk: "low",
|
|
77
|
+
proposedAction: "Add an emitter-output JSON validity test and inspect trace append paths.",
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
return suggestions;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=event-clusters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-clusters.js","sourceRoot":"","sources":["../../../src/core/evolution/event-clusters.ts"],"names":[],"mappings":"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"}
|