@isaacriehm/cairn-core 0.14.0 → 0.14.2
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/.tsbuildinfo +1 -1
- package/dist/gc/classify.js +0 -1
- package/dist/gc/classify.js.map +1 -1
- package/dist/gc/doc-gardening.d.ts +0 -14
- package/dist/gc/doc-gardening.js +0 -40
- package/dist/gc/doc-gardening.js.map +1 -1
- package/dist/gc/sweep.d.ts +0 -2
- package/dist/gc/sweep.js +1 -4
- package/dist/gc/sweep.js.map +1 -1
- package/dist/gc/walk-source.js +0 -1
- package/dist/gc/walk-source.js.map +1 -1
- package/dist/init/curator/regex-prefilter.d.ts +1 -1
- package/dist/init/curator/regex-prefilter.js +2 -2
- package/dist/init/curator/regex-prefilter.js.map +1 -1
- package/dist/init/curator/walker.js +2 -2
- package/dist/init/curator/walker.js.map +1 -1
- package/dist/init/ingest-docs.js +0 -1
- package/dist/init/ingest-docs.js.map +1 -1
- package/dist/init/init.d.ts +1 -1
- package/dist/init/init.js +2 -2
- package/dist/init/init.js.map +1 -1
- package/dist/init/module-slicer.js +0 -1
- package/dist/init/module-slicer.js.map +1 -1
- package/dist/init/phases/5-preflight.js +0 -1
- package/dist/init/phases/5-preflight.js.map +1 -1
- package/dist/init/seed.d.ts +1 -1
- package/dist/init/seed.js +1 -2
- package/dist/init/seed.js.map +1 -1
- package/dist/init/source-comments/walker.js +0 -1
- package/dist/init/source-comments/walker.js.map +1 -1
- package/dist/init/topic-index/walk.js +0 -1
- package/dist/init/topic-index/walk.js.map +1 -1
- package/dist/init/walker.js +0 -1
- package/dist/init/walker.js.map +1 -1
- package/dist/mcp/index.d.ts +0 -2
- package/dist/mcp/index.js +0 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/path-allowlist.d.ts +1 -1
- package/dist/mcp/path-allowlist.js +1 -2
- package/dist/mcp/path-allowlist.js.map +1 -1
- package/dist/mcp/schemas.d.ts +0 -6
- package/dist/mcp/schemas.js +0 -7
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/mcp/serve.js +8 -6
- package/dist/mcp/serve.js.map +1 -1
- package/dist/mcp/tools/index.js +0 -3
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/retire-entity.d.ts +2 -2
- package/dist/mcp/tools/retire-entity.js +4 -4
- package/dist/mcp/tools/retire-entity.js.map +1 -1
- package/dist/session-start/build.d.ts +26 -0
- package/dist/session-start/build.js +30 -0
- package/dist/session-start/build.js.map +1 -1
- package/dist/session-start/index.d.ts +4 -4
- package/dist/session-start/index.js +4 -4
- package/dist/session-start/index.js.map +1 -1
- package/dist/session-start/templates.js +1 -2
- package/dist/session-start/templates.js.map +1 -1
- package/package.json +2 -2
- package/dist/mcp/history/index.d.ts +0 -6
- package/dist/mcp/history/index.js +0 -5
- package/dist/mcp/history/index.js.map +0 -1
- package/dist/mcp/history/prompt.d.ts +0 -33
- package/dist/mcp/history/prompt.js +0 -99
- package/dist/mcp/history/prompt.js.map +0 -1
- package/dist/mcp/history/schema.d.ts +0 -58
- package/dist/mcp/history/schema.js +0 -41
- package/dist/mcp/history/schema.js.map +0 -1
- package/dist/mcp/history/summarizer.d.ts +0 -81
- package/dist/mcp/history/summarizer.js +0 -201
- package/dist/mcp/history/summarizer.js.map +0 -1
- package/dist/mcp/history/walker.d.ts +0 -57
- package/dist/mcp/history/walker.js +0 -156
- package/dist/mcp/history/walker.js.map +0 -1
- package/dist/mcp/tools/query-history.d.ts +0 -20
- package/dist/mcp/tools/query-history.js +0 -51
- package/dist/mcp/tools/query-history.js.map +0 -1
- package/templates/.archive/README.md +0 -67
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
export const TWO_ZONE_REMINDER_BASE = "## Two-zone reminder\n\n" +
|
|
12
12
|
"Reads/grep/glob default to the canonical zone (AGENTS.md, CLAUDE.md, " +
|
|
13
13
|
"docs/**, .cairn/ground/**, .cairn/tasks/active/**). Historical content " +
|
|
14
|
-
"(.
|
|
15
|
-
"`cairn_query_history(scope, question)` when you need a summarized read.";
|
|
14
|
+
"(.cairn/tasks/done/) is excluded by cairn's walkers.";
|
|
16
15
|
export const SESSION_START_HEADER = "# Cairn ground state — authoritative for this session";
|
|
17
16
|
/**
|
|
18
17
|
* The code-change contract — system-level rule injected on every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/session-start/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GACjC,0BAA0B;IAC1B,uEAAuE;IACvE,yEAAyE;IACzE,
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/session-start/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GACjC,0BAA0B;IAC1B,uEAAuE;IACvE,yEAAyE;IACzE,sDAAsD,CAAC;AAEzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,uDAAuD,CAAC;AAE5F;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,gDAAgD;IAChD,yEAAyE;IACzE,wEAAwE;IACxE,uDAAuD;IACvD,qEAAqE;IACrE,uEAAuE;IACvE,uEAAuE;IACvE,wEAAwE;IACxE,kEAAkE;IAClE,yEAAyE;IACzE,wEAAwE;IACxE,yEAAyE;IACzE,uEAAuE;IACvE,wEAAwE;IACxE,gEAAgE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isaacriehm/cairn-core",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Cairn core — state + context layer. Curated `.cairn/ground/` (decisions, §INV invariants, canonical-map, brand, quality-grades), MCP server, init wizard, hook runners, sensors, GC drift sweep.",
|
|
5
5
|
"author": "Isaac Riehm",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"simple-git": "^3.36.0",
|
|
40
40
|
"yaml": "^2.8.4",
|
|
41
41
|
"zod": "^4.4.3",
|
|
42
|
-
"@isaacriehm/cairn-state": "0.14.
|
|
42
|
+
"@isaacriehm/cairn-state": "0.14.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/cli-progress": "^3.11.6",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { walkArchive } from "./walker.js";
|
|
2
|
-
export type { ArchiveFile, WalkArchiveOptions, WalkArchiveResult } from "./walker.js";
|
|
3
|
-
export { HISTORY_SUMMARIZER_SYSTEM_PROMPT, buildHistorySummarizerUserPrompt, CAIRN_HISTORY_SUMMARIZE_PROMPT_ID, CAIRN_HISTORY_SUMMARIZE_VERSION, } from "./prompt.js";
|
|
4
|
-
export { HISTORY_SUMMARIZER_OUTPUT_SCHEMA } from "./schema.js";
|
|
5
|
-
export { runHistorySummarizer, runQueryHistory, } from "./summarizer.js";
|
|
6
|
-
export type { QueryHistoryResponse, RunQueryHistoryArgs, SummarizedClaim, } from "./summarizer.js";
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { walkArchive } from "./walker.js";
|
|
2
|
-
export { HISTORY_SUMMARIZER_SYSTEM_PROMPT, buildHistorySummarizerUserPrompt, CAIRN_HISTORY_SUMMARIZE_PROMPT_ID, CAIRN_HISTORY_SUMMARIZE_VERSION, } from "./prompt.js";
|
|
3
|
-
export { HISTORY_SUMMARIZER_OUTPUT_SCHEMA } from "./schema.js";
|
|
4
|
-
export { runHistorySummarizer, runQueryHistory, } from "./summarizer.js";
|
|
5
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/history/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EAChC,iCAAiC,EACjC,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,oBAAoB,EACpB,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tier-1 (Haiku) summarizer prompts for cairn_query_history.
|
|
3
|
-
*
|
|
4
|
-
* Constraint: the LLM emits ONLY structured claims; raw historical
|
|
5
|
-
* content never reaches the agent's context. Each claim cites a
|
|
6
|
-
* concrete source_path + source_lines so the operator (and any future
|
|
7
|
-
* audit) can verify the summary against the original.
|
|
8
|
-
*
|
|
9
|
-
* The prompt id + version are committed in source so a behavior change
|
|
10
|
-
* here is a versioned change in the source tree, not a silent runtime
|
|
11
|
-
* update.
|
|
12
|
-
*/
|
|
13
|
-
import type { ArchiveFile } from "./walker.js";
|
|
14
|
-
export declare const CAIRN_HISTORY_SUMMARIZE_PROMPT_ID = "cairn.history_summarize.v1";
|
|
15
|
-
export declare const CAIRN_HISTORY_SUMMARIZE_VERSION = "v1";
|
|
16
|
-
export declare const HISTORY_SUMMARIZER_SYSTEM_PROMPT = "You are the **history summarizer** for an agent cairn's two-zone read separation. The agent calling you cannot read .archive/ files directly \u2014 by design. You read those files on its behalf and emit a structured response with cited claims. Only your structured response reaches the agent's context.\n\nYour job: read N historical files and the operator's scope question. Produce per-claim records that capture what the historical files said, with full citation, dates, and supersedes-tags pointing at currently-canonical decisions when they exist.\n\n## Hard contract\n\nEvery claim you emit MUST include:\n\n- `claim` \u2014 one-sentence factual statement of what the historical content said. Past-tense. Imperative voice avoided. Example: \"The project considered using a JSONB expression index on commandPayload->>'userId' for dashboard queries.\" NOT \"The project should use a JSONB index\" \u2014 that is current-tense and reads as canon.\n- `as_of` \u2014 ISO date when the source content was authored / valid. Use the file's frontmatter `generated` or `verified-at`, the bucket date in the path (`.archive/2026-05-pre-cairn/`), or the most explicit date you can find in the body. If genuinely unknown, set the bucket date.\n- `source_path` \u2014 the repo-relative path EXACTLY as given in the file headers. Do not invent a path or a hash.\n- `source_lines` \u2014 line range like \"320-410\" or a single line \"47\". Required so the operator can audit your summary by opening the original file.\n- `superseded_by` \u2014 when an accepted decision in the supplied \"Currently-accepted decisions\" list directly relates to the historical claim, set the DEC-NNNN id. Otherwise set null. Do NOT invent decision ids.\n\n## When you should set `no_relevant_history: true`\n\nThe supplied files don't contain anything relevant to the operator's scope question. Better to short-circuit than to fabricate a summary. The cairn returns an empty claims array with a one-line caveat.\n\n## When you should set `summary_caveat`\n\nAnything important about the input that affects how the agent should treat your output:\n- \"Summary covers 8 files; 3 additional matches were truncated.\"\n- \"All claims are from a single bucket dated 2026-04-23; nothing more recent in scope.\"\n\n## What you must NOT do\n\n- Do NOT issue a recommendation. Your output is descriptive (what was said), not prescriptive (what to do).\n- Do NOT phrase claims as if they are current truth. Always past-tense + cited.\n- Do NOT invent paths, line ranges, decision ids, or dates. If you can't find a value, set what's required by schema and skip the claim.\n- Do NOT emit a free-form preamble before the JSON.\n- Do NOT emit fields not in the schema.\n\nOutput ONLY the JSON object.";
|
|
17
|
-
interface BuildHistoryUserPromptArgs {
|
|
18
|
-
/** Operator's free-text scope description. */
|
|
19
|
-
scope: string;
|
|
20
|
-
/** Repo-relative pathHint glob, when provided. */
|
|
21
|
-
pathHint?: string;
|
|
22
|
-
since?: string;
|
|
23
|
-
until?: string;
|
|
24
|
-
files: ArchiveFile[];
|
|
25
|
-
/** Optional ledger of currently-accepted decisions for supersedes inference. */
|
|
26
|
-
acceptedDecisions: {
|
|
27
|
-
id: string;
|
|
28
|
-
title: string;
|
|
29
|
-
scope_globs?: string[];
|
|
30
|
-
}[];
|
|
31
|
-
}
|
|
32
|
-
export declare function buildHistorySummarizerUserPrompt(args: BuildHistoryUserPromptArgs): string;
|
|
33
|
-
export {};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tier-1 (Haiku) summarizer prompts for cairn_query_history.
|
|
3
|
-
*
|
|
4
|
-
* Constraint: the LLM emits ONLY structured claims; raw historical
|
|
5
|
-
* content never reaches the agent's context. Each claim cites a
|
|
6
|
-
* concrete source_path + source_lines so the operator (and any future
|
|
7
|
-
* audit) can verify the summary against the original.
|
|
8
|
-
*
|
|
9
|
-
* The prompt id + version are committed in source so a behavior change
|
|
10
|
-
* here is a versioned change in the source tree, not a silent runtime
|
|
11
|
-
* update.
|
|
12
|
-
*/
|
|
13
|
-
export const CAIRN_HISTORY_SUMMARIZE_PROMPT_ID = "cairn.history_summarize.v1";
|
|
14
|
-
export const CAIRN_HISTORY_SUMMARIZE_VERSION = "v1";
|
|
15
|
-
export const HISTORY_SUMMARIZER_SYSTEM_PROMPT = `You are the **history summarizer** for an agent cairn's two-zone read separation. The agent calling you cannot read .archive/ files directly — by design. You read those files on its behalf and emit a structured response with cited claims. Only your structured response reaches the agent's context.
|
|
16
|
-
|
|
17
|
-
Your job: read N historical files and the operator's scope question. Produce per-claim records that capture what the historical files said, with full citation, dates, and supersedes-tags pointing at currently-canonical decisions when they exist.
|
|
18
|
-
|
|
19
|
-
## Hard contract
|
|
20
|
-
|
|
21
|
-
Every claim you emit MUST include:
|
|
22
|
-
|
|
23
|
-
- \`claim\` — one-sentence factual statement of what the historical content said. Past-tense. Imperative voice avoided. Example: "The project considered using a JSONB expression index on commandPayload->>'userId' for dashboard queries." NOT "The project should use a JSONB index" — that is current-tense and reads as canon.
|
|
24
|
-
- \`as_of\` — ISO date when the source content was authored / valid. Use the file's frontmatter \`generated\` or \`verified-at\`, the bucket date in the path (\`.archive/2026-05-pre-cairn/\`), or the most explicit date you can find in the body. If genuinely unknown, set the bucket date.
|
|
25
|
-
- \`source_path\` — the repo-relative path EXACTLY as given in the file headers. Do not invent a path or a hash.
|
|
26
|
-
- \`source_lines\` — line range like "320-410" or a single line "47". Required so the operator can audit your summary by opening the original file.
|
|
27
|
-
- \`superseded_by\` — when an accepted decision in the supplied "Currently-accepted decisions" list directly relates to the historical claim, set the DEC-NNNN id. Otherwise set null. Do NOT invent decision ids.
|
|
28
|
-
|
|
29
|
-
## When you should set \`no_relevant_history: true\`
|
|
30
|
-
|
|
31
|
-
The supplied files don't contain anything relevant to the operator's scope question. Better to short-circuit than to fabricate a summary. The cairn returns an empty claims array with a one-line caveat.
|
|
32
|
-
|
|
33
|
-
## When you should set \`summary_caveat\`
|
|
34
|
-
|
|
35
|
-
Anything important about the input that affects how the agent should treat your output:
|
|
36
|
-
- "Summary covers 8 files; 3 additional matches were truncated."
|
|
37
|
-
- "All claims are from a single bucket dated 2026-04-23; nothing more recent in scope."
|
|
38
|
-
|
|
39
|
-
## What you must NOT do
|
|
40
|
-
|
|
41
|
-
- Do NOT issue a recommendation. Your output is descriptive (what was said), not prescriptive (what to do).
|
|
42
|
-
- Do NOT phrase claims as if they are current truth. Always past-tense + cited.
|
|
43
|
-
- Do NOT invent paths, line ranges, decision ids, or dates. If you can't find a value, set what's required by schema and skip the claim.
|
|
44
|
-
- Do NOT emit a free-form preamble before the JSON.
|
|
45
|
-
- Do NOT emit fields not in the schema.
|
|
46
|
-
|
|
47
|
-
Output ONLY the JSON object.`;
|
|
48
|
-
const PER_FILE_HEADER_PREVIEW_LINES = 800;
|
|
49
|
-
export function buildHistorySummarizerUserPrompt(args) {
|
|
50
|
-
const sections = [];
|
|
51
|
-
sections.push("## Operator scope question");
|
|
52
|
-
sections.push(args.scope.trim());
|
|
53
|
-
sections.push("");
|
|
54
|
-
sections.push("## Filters applied to the .archive/ walk");
|
|
55
|
-
sections.push(`path_hint: ${args.pathHint ?? "(none — full archive)"}`);
|
|
56
|
-
sections.push(`since: ${args.since ?? "(none — beginning of time)"}`);
|
|
57
|
-
sections.push(`until: ${args.until ?? "(none — present)"}`);
|
|
58
|
-
sections.push(`matched_files: ${args.files.length}`);
|
|
59
|
-
if (args.acceptedDecisions.length > 0) {
|
|
60
|
-
sections.push("");
|
|
61
|
-
sections.push("## Currently-accepted decisions (for supersedes inference)");
|
|
62
|
-
sections.push("Each line: `<DEC-id> — <title> (scope: <globs>)`. If a historical claim directly contradicts or has been replaced by one of these, cite the id in `superseded_by`. Otherwise set null. Do NOT invent ids.");
|
|
63
|
-
sections.push("");
|
|
64
|
-
for (const d of args.acceptedDecisions.slice(0, 30)) {
|
|
65
|
-
const scope = d.scope_globs && d.scope_globs.length > 0 ? d.scope_globs.join(", ") : "(no scope)";
|
|
66
|
-
sections.push(`- **${d.id}** — ${d.title} (scope: ${scope})`);
|
|
67
|
-
}
|
|
68
|
-
if (args.acceptedDecisions.length > 30) {
|
|
69
|
-
sections.push(`…(${args.acceptedDecisions.length - 30} additional accepted decisions omitted)`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
sections.push("");
|
|
73
|
-
sections.push("## Historical files (line-numbered)");
|
|
74
|
-
if (args.files.length === 0) {
|
|
75
|
-
sections.push("(none — return `no_relevant_history: true`)");
|
|
76
|
-
}
|
|
77
|
-
for (const f of args.files) {
|
|
78
|
-
sections.push("");
|
|
79
|
-
sections.push(`### ${f.relPath} (bucket: ${f.bucket}, archive_date: ${f.archiveDate}${f.truncated ? ", TRUNCATED" : ""})`);
|
|
80
|
-
sections.push("```");
|
|
81
|
-
sections.push(numberLines(f.content, PER_FILE_HEADER_PREVIEW_LINES));
|
|
82
|
-
sections.push("```");
|
|
83
|
-
}
|
|
84
|
-
sections.push("");
|
|
85
|
-
sections.push("## Your task");
|
|
86
|
-
sections.push("Emit the JSON object per the schema. Cite source_path EXACTLY as the headers above show. Output ONLY the JSON object.");
|
|
87
|
-
return sections.join("\n");
|
|
88
|
-
}
|
|
89
|
-
function numberLines(text, maxLines) {
|
|
90
|
-
const lines = text.split(/\r?\n/);
|
|
91
|
-
const truncated = lines.length > maxLines;
|
|
92
|
-
const slice = truncated ? lines.slice(0, maxLines) : lines;
|
|
93
|
-
const padWidth = String(slice.length).length;
|
|
94
|
-
const out = slice.map((line, i) => `${String(i + 1).padStart(padWidth, " ")} ${line}`);
|
|
95
|
-
if (truncated)
|
|
96
|
-
out.push(`…[${lines.length - maxLines} more lines elided]`);
|
|
97
|
-
return out.join("\n");
|
|
98
|
-
}
|
|
99
|
-
//# sourceMappingURL=prompt.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/mcp/history/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Schema enforced by `claude --json-schema` for the history
|
|
3
|
-
* summarizer Tier-1 call.
|
|
4
|
-
*
|
|
5
|
-
* Per MCP_SURFACE.md §"cairn_query_history": every claim MUST carry
|
|
6
|
-
* source_path, source_lines, as_of, and a supersedes-tag (string DEC-id
|
|
7
|
-
* or null). The cairn post-resolves currently_canonical_pointer from
|
|
8
|
-
* the decisions ledger after the LLM returns — keeps the LLM's
|
|
9
|
-
* responsibilities tight (cite + summarize) and makes the canonical
|
|
10
|
-
* cross-reference mechanical.
|
|
11
|
-
*/
|
|
12
|
-
export declare const HISTORY_SUMMARIZER_OUTPUT_SCHEMA: {
|
|
13
|
-
readonly type: "object";
|
|
14
|
-
readonly additionalProperties: false;
|
|
15
|
-
readonly properties: {
|
|
16
|
-
readonly claims: {
|
|
17
|
-
readonly type: "array";
|
|
18
|
-
readonly items: {
|
|
19
|
-
readonly type: "object";
|
|
20
|
-
readonly additionalProperties: false;
|
|
21
|
-
readonly properties: {
|
|
22
|
-
readonly claim: {
|
|
23
|
-
readonly type: "string";
|
|
24
|
-
readonly minLength: 1;
|
|
25
|
-
};
|
|
26
|
-
readonly as_of: {
|
|
27
|
-
readonly type: "string";
|
|
28
|
-
readonly minLength: 1;
|
|
29
|
-
};
|
|
30
|
-
readonly source_path: {
|
|
31
|
-
readonly type: "string";
|
|
32
|
-
readonly minLength: 1;
|
|
33
|
-
};
|
|
34
|
-
readonly source_lines: {
|
|
35
|
-
readonly type: "string";
|
|
36
|
-
readonly minLength: 1;
|
|
37
|
-
};
|
|
38
|
-
readonly superseded_by: {
|
|
39
|
-
readonly anyOf: readonly [{
|
|
40
|
-
readonly type: "string";
|
|
41
|
-
readonly pattern: "^DEC-\\d{4,}$";
|
|
42
|
-
}, {
|
|
43
|
-
readonly type: "null";
|
|
44
|
-
}];
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
readonly required: readonly ["claim", "as_of", "source_path", "source_lines"];
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
readonly summary_caveat: {
|
|
51
|
-
readonly type: "string";
|
|
52
|
-
};
|
|
53
|
-
readonly no_relevant_history: {
|
|
54
|
-
readonly type: "boolean";
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
readonly required: readonly ["claims"];
|
|
58
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Schema enforced by `claude --json-schema` for the history
|
|
3
|
-
* summarizer Tier-1 call.
|
|
4
|
-
*
|
|
5
|
-
* Per MCP_SURFACE.md §"cairn_query_history": every claim MUST carry
|
|
6
|
-
* source_path, source_lines, as_of, and a supersedes-tag (string DEC-id
|
|
7
|
-
* or null). The cairn post-resolves currently_canonical_pointer from
|
|
8
|
-
* the decisions ledger after the LLM returns — keeps the LLM's
|
|
9
|
-
* responsibilities tight (cite + summarize) and makes the canonical
|
|
10
|
-
* cross-reference mechanical.
|
|
11
|
-
*/
|
|
12
|
-
export const HISTORY_SUMMARIZER_OUTPUT_SCHEMA = {
|
|
13
|
-
type: "object",
|
|
14
|
-
additionalProperties: false,
|
|
15
|
-
properties: {
|
|
16
|
-
claims: {
|
|
17
|
-
type: "array",
|
|
18
|
-
items: {
|
|
19
|
-
type: "object",
|
|
20
|
-
additionalProperties: false,
|
|
21
|
-
properties: {
|
|
22
|
-
claim: { type: "string", minLength: 1 },
|
|
23
|
-
as_of: { type: "string", minLength: 1 },
|
|
24
|
-
source_path: { type: "string", minLength: 1 },
|
|
25
|
-
source_lines: { type: "string", minLength: 1 },
|
|
26
|
-
superseded_by: {
|
|
27
|
-
anyOf: [
|
|
28
|
-
{ type: "string", pattern: "^DEC-\\d{4,}$" },
|
|
29
|
-
{ type: "null" },
|
|
30
|
-
],
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
required: ["claim", "as_of", "source_path", "source_lines"],
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
summary_caveat: { type: "string" },
|
|
37
|
-
no_relevant_history: { type: "boolean" },
|
|
38
|
-
},
|
|
39
|
-
required: ["claims"],
|
|
40
|
-
};
|
|
41
|
-
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/mcp/history/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,UAAU,EAAE;QACV,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;oBACvC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;oBACvC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;oBAC7C,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;oBAC9C,aAAa,EAAE;wBACb,KAAK,EAAE;4BACL,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE;4BAC5C,EAAE,IAAI,EAAE,MAAM,EAAE;yBACjB;qBACF;iBACF;gBACD,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,CAAC;aAC5D;SACF;QACD,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAClC,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KACzC;IACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;CACZ,CAAC"}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composes walker + Tier-1 summarizer + post-resolution of
|
|
3
|
-
* currently_canonical_pointer for cairn_query_history.
|
|
4
|
-
*
|
|
5
|
-
* Flow:
|
|
6
|
-
* 1. walkArchive(repoRoot, pathHint, since, until) → ArchiveFile[]
|
|
7
|
-
* 2. Load currently-accepted decisions ledger.
|
|
8
|
-
* 3. Build summarizer prompt with files + ledger.
|
|
9
|
-
* 4. runClaude(tier=haiku, jsonSchema=HISTORY_SUMMARIZER_OUTPUT_SCHEMA).
|
|
10
|
-
* 5. Validate output structurally.
|
|
11
|
-
* 6. Post-resolve currently_canonical_pointer per claim by looking up
|
|
12
|
-
* `superseded_by` against the on-disk decisions/ dir.
|
|
13
|
-
* 7. Attach summarizer_model + summarizer_prompt_id metadata.
|
|
14
|
-
*
|
|
15
|
-
* Returns the structured QueryHistoryResponse the MCP tool emits.
|
|
16
|
-
*/
|
|
17
|
-
import type { ClaudeTier } from "../../claude/index.js";
|
|
18
|
-
import { type ArchiveFile } from "./walker.js";
|
|
19
|
-
export interface SummarizedClaim {
|
|
20
|
-
claim: string;
|
|
21
|
-
as_of: string;
|
|
22
|
-
source_path: string;
|
|
23
|
-
source_lines: string;
|
|
24
|
-
superseded_by: string | null;
|
|
25
|
-
currently_canonical_pointer: string | null;
|
|
26
|
-
warning: string;
|
|
27
|
-
}
|
|
28
|
-
export interface QueryHistoryResponse {
|
|
29
|
-
historical_only: true;
|
|
30
|
-
claims: SummarizedClaim[];
|
|
31
|
-
summary_caveat: string;
|
|
32
|
-
summarizer_model: string;
|
|
33
|
-
summarizer_prompt_id: string;
|
|
34
|
-
/** Structural metadata about the walk — useful for telemetry + tests. */
|
|
35
|
-
walked_files: number;
|
|
36
|
-
walked_buckets: string[];
|
|
37
|
-
truncated_walk: boolean;
|
|
38
|
-
}
|
|
39
|
-
export interface RunQueryHistoryArgs {
|
|
40
|
-
repoRoot: string;
|
|
41
|
-
scope: string;
|
|
42
|
-
pathHint?: string;
|
|
43
|
-
since?: string;
|
|
44
|
-
until?: string;
|
|
45
|
-
/** Tier override; default haiku per workflow.md. */
|
|
46
|
-
tier?: ClaudeTier;
|
|
47
|
-
/** Per-call timeout. Default 120000 ms. */
|
|
48
|
-
timeoutMs?: number;
|
|
49
|
-
/** Smoke override — return canned summarizer output without burning quota. */
|
|
50
|
-
summarizerOverride?: typeof runHistorySummarizer;
|
|
51
|
-
}
|
|
52
|
-
interface RunSummarizerInput {
|
|
53
|
-
scope: string;
|
|
54
|
-
pathHint?: string;
|
|
55
|
-
since?: string;
|
|
56
|
-
until?: string;
|
|
57
|
-
files: ArchiveFile[];
|
|
58
|
-
acceptedDecisions: {
|
|
59
|
-
id: string;
|
|
60
|
-
title: string;
|
|
61
|
-
scope_globs?: string[];
|
|
62
|
-
}[];
|
|
63
|
-
tier: ClaudeTier;
|
|
64
|
-
timeoutMs: number;
|
|
65
|
-
}
|
|
66
|
-
interface RunSummarizerResult {
|
|
67
|
-
claims: {
|
|
68
|
-
claim: string;
|
|
69
|
-
as_of: string;
|
|
70
|
-
source_path: string;
|
|
71
|
-
source_lines: string;
|
|
72
|
-
superseded_by: string | null;
|
|
73
|
-
}[];
|
|
74
|
-
summary_caveat: string;
|
|
75
|
-
no_relevant_history: boolean;
|
|
76
|
-
model: string;
|
|
77
|
-
}
|
|
78
|
-
export declare function runQueryHistory(args: RunQueryHistoryArgs): Promise<QueryHistoryResponse>;
|
|
79
|
-
/** Default summarizer implementation — runs the real LLM. */
|
|
80
|
-
export declare function runHistorySummarizer(input: RunSummarizerInput): Promise<RunSummarizerResult>;
|
|
81
|
-
export {};
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composes walker + Tier-1 summarizer + post-resolution of
|
|
3
|
-
* currently_canonical_pointer for cairn_query_history.
|
|
4
|
-
*
|
|
5
|
-
* Flow:
|
|
6
|
-
* 1. walkArchive(repoRoot, pathHint, since, until) → ArchiveFile[]
|
|
7
|
-
* 2. Load currently-accepted decisions ledger.
|
|
8
|
-
* 3. Build summarizer prompt with files + ledger.
|
|
9
|
-
* 4. runClaude(tier=haiku, jsonSchema=HISTORY_SUMMARIZER_OUTPUT_SCHEMA).
|
|
10
|
-
* 5. Validate output structurally.
|
|
11
|
-
* 6. Post-resolve currently_canonical_pointer per claim by looking up
|
|
12
|
-
* `superseded_by` against the on-disk decisions/ dir.
|
|
13
|
-
* 7. Attach summarizer_model + summarizer_prompt_id metadata.
|
|
14
|
-
*
|
|
15
|
-
* Returns the structured QueryHistoryResponse the MCP tool emits.
|
|
16
|
-
*/
|
|
17
|
-
import { existsSync } from "node:fs";
|
|
18
|
-
import { join } from "node:path";
|
|
19
|
-
import { runClaude } from "../../claude/index.js";
|
|
20
|
-
import { logger } from "../../logger.js";
|
|
21
|
-
import { decisionsDir } from "@isaacriehm/cairn-state";
|
|
22
|
-
import { loadAcceptedDecisions } from "../../sensors/decisions.js";
|
|
23
|
-
import { buildHistorySummarizerUserPrompt, CAIRN_HISTORY_SUMMARIZE_PROMPT_ID, HISTORY_SUMMARIZER_SYSTEM_PROMPT, } from "./prompt.js";
|
|
24
|
-
import { HISTORY_SUMMARIZER_OUTPUT_SCHEMA } from "./schema.js";
|
|
25
|
-
import { walkArchive } from "./walker.js";
|
|
26
|
-
const log = logger("mcp.history.summarizer");
|
|
27
|
-
const HISTORICAL_WARNING = "This claim is HISTORICAL. Verify against the canonical pointer before acting.";
|
|
28
|
-
export async function runQueryHistory(args) {
|
|
29
|
-
const tier = args.tier ?? "haiku";
|
|
30
|
-
const timeoutMs = args.timeoutMs ?? 120_000;
|
|
31
|
-
const summarize = args.summarizerOverride ?? runHistorySummarizer;
|
|
32
|
-
const walkOpts = { repoRoot: args.repoRoot };
|
|
33
|
-
if (args.pathHint !== undefined)
|
|
34
|
-
walkOpts.pathHint = args.pathHint;
|
|
35
|
-
if (args.since !== undefined)
|
|
36
|
-
walkOpts.since = args.since;
|
|
37
|
-
if (args.until !== undefined)
|
|
38
|
-
walkOpts.until = args.until;
|
|
39
|
-
const walk = walkArchive(walkOpts);
|
|
40
|
-
if (walk.files.length === 0) {
|
|
41
|
-
return {
|
|
42
|
-
historical_only: true,
|
|
43
|
-
claims: [],
|
|
44
|
-
summary_caveat: walk.bucketsScanned.length === 0
|
|
45
|
-
? "No .archive/ directory found at this repo root."
|
|
46
|
-
: `No files matched the walk filters (path_hint, since, until) across ${walk.bucketsScanned.length} archive bucket${walk.bucketsScanned.length === 1 ? "" : "s"}.`,
|
|
47
|
-
summarizer_model: "(skipped — no matches)",
|
|
48
|
-
summarizer_prompt_id: CAIRN_HISTORY_SUMMARIZE_PROMPT_ID,
|
|
49
|
-
walked_files: 0,
|
|
50
|
-
walked_buckets: walk.bucketsScanned,
|
|
51
|
-
truncated_walk: walk.capHit,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
const decisions = loadAcceptedDecisions(args.repoRoot).map((d) => {
|
|
55
|
-
const entry = {
|
|
56
|
-
id: d.id,
|
|
57
|
-
title: d.title,
|
|
58
|
-
};
|
|
59
|
-
if (d.scope_globs !== undefined)
|
|
60
|
-
entry.scope_globs = d.scope_globs;
|
|
61
|
-
return entry;
|
|
62
|
-
});
|
|
63
|
-
log.info({
|
|
64
|
-
repo: args.repoRoot,
|
|
65
|
-
scope_preview: args.scope.slice(0, 80),
|
|
66
|
-
files: walk.files.length,
|
|
67
|
-
buckets: walk.bucketsScanned.length,
|
|
68
|
-
total_bytes: walk.totalBytes,
|
|
69
|
-
tier,
|
|
70
|
-
}, "history summarizer dispatch");
|
|
71
|
-
const summarizerInput = {
|
|
72
|
-
scope: args.scope,
|
|
73
|
-
files: walk.files,
|
|
74
|
-
acceptedDecisions: decisions,
|
|
75
|
-
tier,
|
|
76
|
-
timeoutMs,
|
|
77
|
-
};
|
|
78
|
-
if (args.pathHint !== undefined)
|
|
79
|
-
summarizerInput.pathHint = args.pathHint;
|
|
80
|
-
if (args.since !== undefined)
|
|
81
|
-
summarizerInput.since = args.since;
|
|
82
|
-
if (args.until !== undefined)
|
|
83
|
-
summarizerInput.until = args.until;
|
|
84
|
-
const summary = await summarize(summarizerInput);
|
|
85
|
-
const acceptedById = new Map();
|
|
86
|
-
for (const d of decisions)
|
|
87
|
-
acceptedById.set(d.id, true);
|
|
88
|
-
const claims = summary.claims.map((c) => {
|
|
89
|
-
const supersededBy = resolveSupersededBy(c.superseded_by, acceptedById);
|
|
90
|
-
const pointer = supersededBy
|
|
91
|
-
? canonicalPointerFor(args.repoRoot, supersededBy)
|
|
92
|
-
: null;
|
|
93
|
-
return {
|
|
94
|
-
claim: c.claim,
|
|
95
|
-
as_of: c.as_of,
|
|
96
|
-
source_path: c.source_path,
|
|
97
|
-
source_lines: c.source_lines,
|
|
98
|
-
superseded_by: supersededBy,
|
|
99
|
-
currently_canonical_pointer: pointer,
|
|
100
|
-
warning: HISTORICAL_WARNING,
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
const caveatBits = [];
|
|
104
|
-
if (summary.summary_caveat.trim().length > 0)
|
|
105
|
-
caveatBits.push(summary.summary_caveat.trim());
|
|
106
|
-
if (walk.capHit) {
|
|
107
|
-
caveatBits.push(`Walk truncated — additional matching files were not summarized; refine path_hint / since / until and re-query.`);
|
|
108
|
-
}
|
|
109
|
-
if (summary.no_relevant_history && claims.length === 0) {
|
|
110
|
-
caveatBits.push("Summarizer found no claims relevant to the scope question.");
|
|
111
|
-
}
|
|
112
|
-
caveatBits.push("All claims are dated and superseded-tagged. Do not treat any line as current truth. Cross-reference the canonical pointer (or call cairn_decision_get / cairn_canonical_for_topic) before acting.");
|
|
113
|
-
return {
|
|
114
|
-
historical_only: true,
|
|
115
|
-
claims,
|
|
116
|
-
summary_caveat: caveatBits.join(" "),
|
|
117
|
-
summarizer_model: summary.model,
|
|
118
|
-
summarizer_prompt_id: CAIRN_HISTORY_SUMMARIZE_PROMPT_ID,
|
|
119
|
-
walked_files: walk.files.length,
|
|
120
|
-
walked_buckets: walk.bucketsScanned,
|
|
121
|
-
truncated_walk: walk.capHit,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/** Default summarizer implementation — runs the real LLM. */
|
|
125
|
-
export async function runHistorySummarizer(input) {
|
|
126
|
-
const userPrompt = buildHistorySummarizerUserPrompt({
|
|
127
|
-
scope: input.scope,
|
|
128
|
-
files: input.files,
|
|
129
|
-
acceptedDecisions: input.acceptedDecisions,
|
|
130
|
-
...(input.pathHint !== undefined ? { pathHint: input.pathHint } : {}),
|
|
131
|
-
...(input.since !== undefined ? { since: input.since } : {}),
|
|
132
|
-
...(input.until !== undefined ? { until: input.until } : {}),
|
|
133
|
-
});
|
|
134
|
-
const result = await runClaude({
|
|
135
|
-
tier: input.tier,
|
|
136
|
-
prompt: userPrompt,
|
|
137
|
-
system: HISTORY_SUMMARIZER_SYSTEM_PROMPT,
|
|
138
|
-
jsonSchema: HISTORY_SUMMARIZER_OUTPUT_SCHEMA,
|
|
139
|
-
timeoutMs: input.timeoutMs,
|
|
140
|
-
// Summarizer only needs the walker-collected archive files and the
|
|
141
|
-
// accepted-decisions ledger that buildHistorySummarizerUserPrompt
|
|
142
|
-
// already serialized into the prompt. Ambient project context
|
|
143
|
-
// would be redundant + expensive.
|
|
144
|
-
isolateAmbientContext: true,
|
|
145
|
-
});
|
|
146
|
-
if (!isSummarizerOutput(result.parsed)) {
|
|
147
|
-
throw new Error(`history summarizer returned malformed output. preview: ${result.text.slice(0, 200)}`);
|
|
148
|
-
}
|
|
149
|
-
return {
|
|
150
|
-
claims: result.parsed.claims.map((c) => ({
|
|
151
|
-
claim: c.claim,
|
|
152
|
-
as_of: c.as_of,
|
|
153
|
-
source_path: c.source_path,
|
|
154
|
-
source_lines: c.source_lines,
|
|
155
|
-
superseded_by: c.superseded_by ?? null,
|
|
156
|
-
})),
|
|
157
|
-
summary_caveat: result.parsed.summary_caveat ?? "",
|
|
158
|
-
no_relevant_history: result.parsed.no_relevant_history === true,
|
|
159
|
-
model: result.model,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
function isSummarizerOutput(v) {
|
|
163
|
-
if (typeof v !== "object" || v === null)
|
|
164
|
-
return false;
|
|
165
|
-
const o = v;
|
|
166
|
-
if (!Array.isArray(o["claims"]))
|
|
167
|
-
return false;
|
|
168
|
-
for (const c of o["claims"]) {
|
|
169
|
-
if (typeof c !== "object" || c === null)
|
|
170
|
-
return false;
|
|
171
|
-
const cc = c;
|
|
172
|
-
if (typeof cc["claim"] !== "string")
|
|
173
|
-
return false;
|
|
174
|
-
if (typeof cc["as_of"] !== "string")
|
|
175
|
-
return false;
|
|
176
|
-
if (typeof cc["source_path"] !== "string")
|
|
177
|
-
return false;
|
|
178
|
-
if (typeof cc["source_lines"] !== "string")
|
|
179
|
-
return false;
|
|
180
|
-
if (cc["superseded_by"] !== undefined &&
|
|
181
|
-
cc["superseded_by"] !== null &&
|
|
182
|
-
typeof cc["superseded_by"] !== "string") {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
function resolveSupersededBy(proposed, acceptedById) {
|
|
189
|
-
if (proposed === undefined || proposed === null)
|
|
190
|
-
return null;
|
|
191
|
-
if (!/^DEC-[0-9a-f]{7,}$/.test(proposed))
|
|
192
|
-
return null;
|
|
193
|
-
return acceptedById.has(proposed) ? proposed : null;
|
|
194
|
-
}
|
|
195
|
-
function canonicalPointerFor(repoRoot, decisionId) {
|
|
196
|
-
const path = join(decisionsDir(repoRoot), `${decisionId}.md`);
|
|
197
|
-
if (!existsSync(path))
|
|
198
|
-
return null;
|
|
199
|
-
return `.cairn/ground/decisions/${decisionId}.md`;
|
|
200
|
-
}
|
|
201
|
-
//# sourceMappingURL=summarizer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../../src/mcp/history/summarizer.ts"],"names":[],"mappings":"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"}
|