daftari 1.31.0 → 1.32.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +58 -9
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +6 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/consolidate/index.d.ts.map +1 -1
  7. package/dist/consolidate/index.js +10 -12
  8. package/dist/consolidate/index.js.map +1 -1
  9. package/dist/curation/edges.d.ts.map +1 -1
  10. package/dist/curation/edges.js +36 -17
  11. package/dist/curation/edges.js.map +1 -1
  12. package/dist/curation/lint.d.ts +2 -0
  13. package/dist/curation/lint.d.ts.map +1 -1
  14. package/dist/curation/lint.js +26 -18
  15. package/dist/curation/lint.js.map +1 -1
  16. package/dist/curation/shadow.d.ts +1 -0
  17. package/dist/curation/shadow.d.ts.map +1 -1
  18. package/dist/curation/shadow.js +17 -11
  19. package/dist/curation/shadow.js.map +1 -1
  20. package/dist/curation/staged-actions.d.ts +1 -0
  21. package/dist/curation/staged-actions.d.ts.map +1 -1
  22. package/dist/curation/staged-actions.js +21 -24
  23. package/dist/curation/staged-actions.js.map +1 -1
  24. package/dist/eval/generate.d.ts.map +1 -1
  25. package/dist/eval/generate.js +16 -0
  26. package/dist/eval/generate.js.map +1 -1
  27. package/dist/eval/index.d.ts +1 -0
  28. package/dist/eval/index.d.ts.map +1 -1
  29. package/dist/eval/index.js +79 -28
  30. package/dist/eval/index.js.map +1 -1
  31. package/dist/eval/llm-openrouter.d.ts.map +1 -1
  32. package/dist/eval/llm-openrouter.js +158 -65
  33. package/dist/eval/llm-openrouter.js.map +1 -1
  34. package/dist/interview/index.d.ts +7 -0
  35. package/dist/interview/index.d.ts.map +1 -0
  36. package/dist/interview/index.js +219 -0
  37. package/dist/interview/index.js.map +1 -0
  38. package/dist/interview/questions.d.ts +18 -0
  39. package/dist/interview/questions.d.ts.map +1 -0
  40. package/dist/interview/questions.js +169 -0
  41. package/dist/interview/questions.js.map +1 -0
  42. package/dist/interview/transcript.d.ts +23 -0
  43. package/dist/interview/transcript.d.ts.map +1 -0
  44. package/dist/interview/transcript.js +155 -0
  45. package/dist/interview/transcript.js.map +1 -0
  46. package/dist/okf/export.d.ts.map +1 -1
  47. package/dist/okf/export.js +4 -2
  48. package/dist/okf/export.js.map +1 -1
  49. package/dist/okf/import.d.ts.map +1 -1
  50. package/dist/okf/import.js +11 -3
  51. package/dist/okf/import.js.map +1 -1
  52. package/dist/okf/index.d.ts.map +1 -1
  53. package/dist/okf/index.js +13 -1
  54. package/dist/okf/index.js.map +1 -1
  55. package/dist/okf/map.d.ts +11 -0
  56. package/dist/okf/map.d.ts.map +1 -1
  57. package/dist/okf/map.js +191 -13
  58. package/dist/okf/map.js.map +1 -1
  59. package/dist/okf/types.d.ts +6 -2
  60. package/dist/okf/types.d.ts.map +1 -1
  61. package/dist/okf/types.js +39 -5
  62. package/dist/okf/types.js.map +1 -1
  63. package/dist/search/hybrid.d.ts.map +1 -1
  64. package/dist/search/hybrid.js +2 -5
  65. package/dist/search/hybrid.js.map +1 -1
  66. package/dist/search/reindex.d.ts +3 -0
  67. package/dist/search/reindex.d.ts.map +1 -1
  68. package/dist/search/reindex.js +30 -10
  69. package/dist/search/reindex.js.map +1 -1
  70. package/dist/search/watcher.d.ts.map +1 -1
  71. package/dist/search/watcher.js +8 -17
  72. package/dist/search/watcher.js.map +1 -1
  73. package/dist/storage/index-db.d.ts.map +1 -1
  74. package/dist/storage/index-db.js +1 -0
  75. package/dist/storage/index-db.js.map +1 -1
  76. package/dist/tools/read.d.ts.map +1 -1
  77. package/dist/tools/read.js +69 -47
  78. package/dist/tools/read.js.map +1 -1
  79. package/dist/tools/staged-actions.d.ts.map +1 -1
  80. package/dist/tools/staged-actions.js +32 -34
  81. package/dist/tools/staged-actions.js.map +1 -1
  82. package/dist/tools/write.d.ts.map +1 -1
  83. package/dist/tools/write.js +152 -216
  84. package/dist/tools/write.js.map +1 -1
  85. package/dist/utils/config.d.ts.map +1 -1
  86. package/dist/utils/config.js +86 -86
  87. package/dist/utils/config.js.map +1 -1
  88. package/dist/utils/dates.d.ts +1 -0
  89. package/dist/utils/dates.d.ts.map +1 -1
  90. package/dist/utils/dates.js +5 -0
  91. package/dist/utils/dates.js.map +1 -1
  92. package/package.json +1 -1
@@ -0,0 +1,219 @@
1
+ // Top-level entry for `daftari interview` — the vault interrogates its
2
+ // principal.
3
+ //
4
+ // daftari interview print the question sheet (read-only): open
5
+ // tensions, expired canon, unanswered
6
+ // questions_raised — priority-ordered
7
+ // daftari interview ask conduct the interview at the terminal and
8
+ // record the verbatim answers as a vault doc
9
+ //
10
+ // Operator-only, like the court: the sheet reads the full tension log and
11
+ // every collection with no access context. Deterministic and LLM-free, like
12
+ // the circadian pass: nothing on this surface can spend.
13
+ //
14
+ // Exit codes (the audit convention):
15
+ // 0 — sheet printed / interview recorded (or nothing to ask)
16
+ // 2 — config/usage error (bad flag value)
17
+ // 3 — runtime error (IO failure)
18
+ import { writeFile } from "node:fs/promises";
19
+ import { userInfo } from "node:os";
20
+ import { resolve } from "node:path";
21
+ import { createInterface } from "node:readline";
22
+ import { gatherQuestions, renderSheet } from "./questions.js";
23
+ import { DEFAULT_INTERVIEW_COLLECTION, isValidCollectionName, writeTranscript, } from "./transcript.js";
24
+ const HELP = `daftari interview — the vault interrogates its principal.
25
+
26
+ The sheet is assembled from what the vault already knows is unclear: open
27
+ tensions (contested first, longest-carried first), canonical accumulation
28
+ docs past their ttl_days (largest overshoot first), and questions_raised
29
+ entries that no document's questions_answered covers. Deterministic, LLM-free.
30
+
31
+ Usage:
32
+ daftari interview [--vault <path>] [--limit <n>] [--output <md>] [--output-json <json>]
33
+ daftari interview ask [--vault <path>] [--limit <n>] [--collection <name>] [--by <identity>]
34
+ daftari interview --help
35
+
36
+ Sheet (default, read-only):
37
+ --limit Cap the sheet at the n highest-priority questions.
38
+ --output Write the sheet to a file instead of stdout.
39
+ --output-json Also write the questions as JSON.
40
+
41
+ Interview (ask):
42
+ Each question is put to you in turn. Your answer is recorded VERBATIM.
43
+ An empty answer skips the question; 'q' (or end-of-input) ends the
44
+ session. Answered questions become a transcript document in the vault —
45
+ tier: source, provenance: direct — committed like any other write.
46
+
47
+ --collection Collection the transcript lands in (default: interviews).
48
+ One path segment: letters, digits, '-', '_'.
49
+ Note: the transcript quotes claims from every collection
50
+ the sheet touched. Under the template config only roles
51
+ with read: ["*"] can read a new collection; granting a
52
+ narrower role read here exposes those quotes to it.
53
+ --by Identity recorded as updated_by and commit author
54
+ (default: human:<os username>).
55
+
56
+ Recording testimony resolves nothing. The transcript is evidence: close a
57
+ tension with 'daftari court rule <id> --references <transcript>', freshen a
58
+ stale doc with a re-verified write.
59
+
60
+ Exit codes:
61
+ 0 — sheet printed / interview recorded
62
+ 2 — config/usage error
63
+ 3 — runtime error (IO failure)
64
+ `;
65
+ function readStringArg(argv, flag) {
66
+ const raw = argv.find((a) => a === flag || a.startsWith(`${flag}=`));
67
+ if (raw === undefined)
68
+ return undefined;
69
+ const idx = argv.indexOf(raw);
70
+ return raw.includes("=") ? raw.slice(raw.indexOf("=") + 1) : argv[idx + 1];
71
+ }
72
+ const VALUE_FLAGS = ["--vault", "--limit", "--output", "--output-json", "--collection", "--by"];
73
+ function findPositionals(argv) {
74
+ const out = [];
75
+ for (let i = 0; i < argv.length; i++) {
76
+ const a = argv[i];
77
+ if (a.startsWith("--"))
78
+ continue;
79
+ const prev = i > 0 ? argv[i - 1] : undefined;
80
+ if (prev !== undefined && VALUE_FLAGS.includes(prev))
81
+ continue;
82
+ out.push(a);
83
+ }
84
+ return out;
85
+ }
86
+ function terminalIo() {
87
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
88
+ const closed = new Promise((res) => rl.once("close", () => res(null)));
89
+ return {
90
+ ask: (prompt) => Promise.race([new Promise((res) => rl.question(prompt, res)), closed]),
91
+ write: (text) => process.stdout.write(text),
92
+ close: () => rl.close(),
93
+ };
94
+ }
95
+ function questionBlock(q, total) {
96
+ const n = Number.parseInt(q.id.slice(2), 10);
97
+ return (`\n[${n}/${total}] ${q.id} — ${q.kind}\n` +
98
+ `${q.question}\n` +
99
+ `(asked because: ${q.context})\n` +
100
+ `(empty answer skips; 'q' ends the session)\n`);
101
+ }
102
+ async function runAsk(vaultRoot, questions, argv, collection, io) {
103
+ const answers = [];
104
+ try {
105
+ for (const q of questions) {
106
+ io.write(questionBlock(q, questions.length));
107
+ const raw = await io.ask("> ");
108
+ if (raw === null)
109
+ break; // end-of-input
110
+ const answer = raw.trim();
111
+ if (answer.length === 0)
112
+ continue; // skip
113
+ if (answer === "q" || answer === "quit")
114
+ break;
115
+ answers.push({ question: q, answer });
116
+ }
117
+ }
118
+ finally {
119
+ io.close();
120
+ }
121
+ if (answers.length === 0) {
122
+ io.write("\nNo answers recorded — nothing written.\n");
123
+ return 0;
124
+ }
125
+ const meta = {
126
+ date: new Date().toISOString().slice(0, 10),
127
+ by: readStringArg(argv, "--by") ?? `human:${userInfo().username}`,
128
+ collection,
129
+ };
130
+ const written = await writeTranscript(vaultRoot, answers, meta);
131
+ if (!written.ok) {
132
+ process.stderr.write(`daftari interview: ${written.error.message}\n`);
133
+ return 3;
134
+ }
135
+ const lines = [
136
+ `\nRecorded ${answers.length} answer${answers.length === 1 ? "" : "s"} → ${written.value.relPath}`,
137
+ ];
138
+ if (written.value.commitHash)
139
+ lines.push(`Committed as ${written.value.commitHash}.`);
140
+ if (written.value.warning)
141
+ lines.push(`Warning: ${written.value.warning}`);
142
+ // Testimony is evidence, not resolution — point at the acts that remain.
143
+ const tensionIds = answers
144
+ .filter((a) => a.question.kind === "tension")
145
+ .map((a) => a.question.refs[0]);
146
+ if (tensionIds.length > 0) {
147
+ lines.push("");
148
+ lines.push("Answers touch open tensions. A ruling is still yours to make:");
149
+ for (const id of tensionIds) {
150
+ lines.push(` daftari court rule ${id} --kind <kind> --references ${written.value.relPath}`);
151
+ }
152
+ }
153
+ if (answers.some((a) => a.question.kind === "stale")) {
154
+ lines.push("");
155
+ lines.push("Answers touch stale docs. The transcript does not freshen them — " +
156
+ "re-verify and rewrite each doc to renew its promise.");
157
+ }
158
+ io.write(`${lines.join("\n")}\n`);
159
+ return 0;
160
+ }
161
+ export async function runInterview(argv, io) {
162
+ if (argv.includes("--help") || argv.includes("-h")) {
163
+ process.stdout.write(HELP);
164
+ return 0;
165
+ }
166
+ const vaultRoot = resolve(readStringArg(argv, "--vault") ?? ".");
167
+ let limit;
168
+ const rawLimit = readStringArg(argv, "--limit");
169
+ if (rawLimit !== undefined) {
170
+ limit = Number.parseInt(rawLimit, 10);
171
+ if (!Number.isFinite(limit) || limit < 1) {
172
+ process.stderr.write(`daftari interview: --limit must be a positive integer\n`);
173
+ return 2;
174
+ }
175
+ }
176
+ const gathered = await gatherQuestions(vaultRoot, { limit });
177
+ if (!gathered.ok) {
178
+ process.stderr.write(`daftari interview: ${gathered.error.message}\n`);
179
+ return 3;
180
+ }
181
+ const questions = gathered.value;
182
+ if (findPositionals(argv)[0] === "ask") {
183
+ // Validated before a single question is put to the principal: the
184
+ // collection lands in both the transcript's frontmatter and its on-disk
185
+ // path, so a bad flag must fail here, not after the testimony is given.
186
+ const collection = readStringArg(argv, "--collection") ?? DEFAULT_INTERVIEW_COLLECTION;
187
+ if (!isValidCollectionName(collection)) {
188
+ process.stderr.write("daftari interview: --collection must be a single path segment " +
189
+ "(letters, digits, '-', '_') and not a reserved name like node_modules\n");
190
+ return 2;
191
+ }
192
+ if (questions.length === 0) {
193
+ process.stdout.write("Nothing is unclear: no open tensions, no expired canon, no unanswered questions_raised.\n");
194
+ return 0;
195
+ }
196
+ return runAsk(vaultRoot, questions, argv, collection, io ?? terminalIo());
197
+ }
198
+ const sheet = renderSheet(questions, new Date().toISOString().slice(0, 10));
199
+ const outputMd = readStringArg(argv, "--output");
200
+ const outputJson = readStringArg(argv, "--output-json");
201
+ try {
202
+ if (outputMd) {
203
+ await writeFile(resolve(outputMd), sheet, "utf-8");
204
+ }
205
+ else {
206
+ process.stdout.write(sheet);
207
+ }
208
+ if (outputJson) {
209
+ await writeFile(resolve(outputJson), `${JSON.stringify(questions, null, 2)}\n`, "utf-8");
210
+ }
211
+ }
212
+ catch (e) {
213
+ const reason = e instanceof Error ? e.message : String(e);
214
+ process.stderr.write(`daftari interview: write failed: ${reason}\n`);
215
+ return 3;
216
+ }
217
+ return 0;
218
+ }
219
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interview/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type Result } from "../frontmatter/types.js";
2
+ export declare const QUESTION_KINDS: readonly ["tension", "stale", "open_question"];
3
+ export type QuestionKind = (typeof QUESTION_KINDS)[number];
4
+ export interface InterviewQuestion {
5
+ id: string;
6
+ kind: QuestionKind;
7
+ question: string;
8
+ context: string;
9
+ refs: string[];
10
+ }
11
+ export declare function normalizeQuestion(q: string): string;
12
+ export interface GatherOptions {
13
+ now?: Date;
14
+ limit?: number;
15
+ }
16
+ export declare function gatherQuestions(vaultRoot: string, opts?: GatherOptions): Promise<Result<InterviewQuestion[], Error>>;
17
+ export declare function renderSheet(questions: InterviewQuestion[], generatedAt: string): string;
18
+ //# sourceMappingURL=questions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../src/interview/questions.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE1D,eAAO,MAAM,cAAc,gDAAiD,CAAC;AAC7E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AASD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAsGD,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC,CAAC,CAgB7C;AAID,wBAAgB,WAAW,CAAC,SAAS,EAAE,iBAAiB,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAmBvF"}
@@ -0,0 +1,169 @@
1
+ // Interview questions — the deterministic half of `daftari interview`.
2
+ //
3
+ // The design steal is the companion interview on a "living summary" page:
4
+ // after an assistant compiles a corpus of someone's positions, its highest-
5
+ // value next move is not more compilation — it is to ask the principal about
6
+ // the places the corpus is unclear, and fold the verbatim answers back in as
7
+ // first-class source material.
8
+ //
9
+ // Daftari already computes "unclear" three ways, so the sheet is assembled
10
+ // from existing signals and costs nothing:
11
+ //
12
+ // tension — two docs disagree and neither superseded the other
13
+ // stale — a canonical accumulation doc has outlived its ttl_days
14
+ // open_question — a questions_raised entry no doc's questions_answered
15
+ // covers
16
+ //
17
+ // LLM-FREE by design (the circadian precedent from `daftari sleep`): no flag
18
+ // on this surface can spend. This module is operator-only and takes no access
19
+ // context — the court convention; see the 2026-07-25 design spec.
20
+ import { computeStaleness } from "../curation/staleness.js";
21
+ import { agingTier, listTensions } from "../curation/tension.js";
22
+ import { loadDocuments } from "../curation/vault-docs.js";
23
+ import { ok } from "../frontmatter/types.js";
24
+ export const QUESTION_KINDS = ["tension", "stale", "open_question"];
25
+ // Statuses whose questions_raised no longer count as open: the doc has been
26
+ // retired, and its curiosity retired with it. Its questions_answered still
27
+ // count — an answer recorded anywhere stays an answer.
28
+ const RETIRED_STATUSES = new Set(["deprecated", "superseded", "archived"]);
29
+ // Whitespace/case normalization for matching a raised question against the
30
+ // vault's answered set. Exact semantics stay deterministic — no fuzzy match.
31
+ export function normalizeQuestion(q) {
32
+ return q.trim().replace(/\s+/g, " ").toLowerCase();
33
+ }
34
+ // Aging-tier priority for tension questions: the disputes the vault has
35
+ // carried longest are asked first. Unresolved entries never tier to null
36
+ // (that carve-out is for accepted resolutions), but rank it last defensively.
37
+ const TIER_RANK = { stale: 0, aging: 1, fresh: 2 };
38
+ function tensionQuestions(entries, now) {
39
+ const open = entries.filter((e) => !e.resolved &&
40
+ e.id !== undefined &&
41
+ // Legacy `unspecified` entries cannot be ruled through the tools, and
42
+ // `inter-proposal` conflicts close through vault_ratify, not testimony.
43
+ e.kind !== "unspecified" &&
44
+ e.kind !== "inter-proposal");
45
+ open.sort((a, b) => {
46
+ const tierA = TIER_RANK[agingTier(a, now) ?? ""] ?? 3;
47
+ const tierB = TIER_RANK[agingTier(b, now) ?? ""] ?? 3;
48
+ if (tierA !== tierB)
49
+ return tierA - tierB;
50
+ return a.date.localeCompare(b.date);
51
+ });
52
+ return open.map((e) => ({
53
+ id: "", // assigned after the kinds are concatenated
54
+ kind: "tension",
55
+ question: `Two documents disagree (${e.kind}): ${e.sourceA} says "${e.claimA}" ` +
56
+ `while ${e.sourceB} says "${e.claimB}". Which claim reflects your ` +
57
+ `current position — or do both stand?`,
58
+ context: `open tension ${e.id} (${agingTier(e, now) ?? "unaged"}), logged ${e.date}`,
59
+ refs: [e.id, e.sourceA, e.sourceB],
60
+ }));
61
+ }
62
+ function staleQuestions(docs, now) {
63
+ const candidates = [];
64
+ for (const doc of docs) {
65
+ const fm = doc.frontmatter;
66
+ // Sleep's domain split: generative docs going stale is expected — never
67
+ // asked about. Only canonical accumulation docs made a freshness promise.
68
+ if (fm.domain !== "accumulation" || fm.status !== "canonical")
69
+ continue;
70
+ const staleness = computeStaleness({ updated: fm.updated, ttl_days: fm.ttl_days }, now);
71
+ if (!staleness.expired || staleness.ttlDays === null)
72
+ continue;
73
+ candidates.push({
74
+ doc,
75
+ overshootDays: staleness.ageDays - staleness.ttlDays,
76
+ ttlDays: staleness.ttlDays,
77
+ });
78
+ }
79
+ candidates.sort((a, b) => b.overshootDays - a.overshootDays || a.doc.path.localeCompare(b.doc.path));
80
+ return candidates.map(({ doc, overshootDays, ttlDays }) => ({
81
+ id: "",
82
+ kind: "stale",
83
+ question: `"${doc.frontmatter.title}" (${doc.path}) is ${overshootDays} days past ` +
84
+ `its ${ttlDays}-day freshness window. Is it still accurate — and if ` +
85
+ `not, what changed?`,
86
+ context: `stale: updated ${doc.frontmatter.updated}, ttl ${ttlDays} days`,
87
+ refs: [doc.path],
88
+ }));
89
+ }
90
+ function openQuestions(docs) {
91
+ // An answer recorded anywhere counts, whatever the answering doc's status.
92
+ const answered = new Set();
93
+ for (const doc of docs) {
94
+ for (const q of doc.frontmatter.questions_answered) {
95
+ answered.add(normalizeQuestion(q));
96
+ }
97
+ }
98
+ // Duplicate raisings merge into one question with every raising doc as a
99
+ // ref. Insertion order over the sorted file walk keeps the sheet stable.
100
+ const raised = new Map();
101
+ for (const doc of docs) {
102
+ if (RETIRED_STATUSES.has(doc.frontmatter.status))
103
+ continue;
104
+ for (const q of doc.frontmatter.questions_raised) {
105
+ const norm = normalizeQuestion(q);
106
+ if (norm.length === 0 || answered.has(norm))
107
+ continue;
108
+ const existing = raised.get(norm);
109
+ if (existing) {
110
+ if (!existing.refs.includes(doc.path))
111
+ existing.refs.push(doc.path);
112
+ }
113
+ else {
114
+ raised.set(norm, { text: q.trim(), refs: [doc.path] });
115
+ }
116
+ }
117
+ }
118
+ return [...raised.values()].map(({ text, refs }) => ({
119
+ id: "",
120
+ kind: "open_question",
121
+ question: `An open question no document answers: "${text}" (raised by ` +
122
+ `${refs.join(", ")}). What is your current answer — even a partial one?`,
123
+ context: `questions_raised with no matching questions_answered anywhere in the vault`,
124
+ refs,
125
+ }));
126
+ }
127
+ // Assembles the priority-ordered question sheet: contested first (the vault
128
+ // is actively carrying a disagreement), then broken freshness promises, then
129
+ // open curiosity.
130
+ export async function gatherQuestions(vaultRoot, opts = {}) {
131
+ const now = opts.now ?? new Date();
132
+ const tensions = await listTensions(vaultRoot);
133
+ if (!tensions.ok)
134
+ return tensions;
135
+ const docs = await loadDocuments(vaultRoot);
136
+ if (!docs.ok)
137
+ return docs;
138
+ let questions = [
139
+ ...tensionQuestions(tensions.value, now),
140
+ ...staleQuestions(docs.value, now),
141
+ ...openQuestions(docs.value),
142
+ ];
143
+ if (opts.limit !== undefined)
144
+ questions = questions.slice(0, opts.limit);
145
+ return ok(questions.map((q, i) => ({ ...q, id: `q-${String(i + 1).padStart(3, "0")}` })));
146
+ }
147
+ // The read-only sheet, as markdown. Printed by the default `daftari
148
+ // interview` invocation (court convention: the default surface never writes).
149
+ export function renderSheet(questions, generatedAt) {
150
+ const lines = [
151
+ `# Interview sheet — ${generatedAt}`,
152
+ "",
153
+ `${questions.length} question${questions.length === 1 ? "" : "s"}. ` +
154
+ `Order: contested first, then stale canon, then open questions. ` +
155
+ `Answer them with \`daftari interview ask\`.`,
156
+ "",
157
+ ];
158
+ for (const q of questions) {
159
+ lines.push(`## ${q.id} — ${q.kind}`);
160
+ lines.push("");
161
+ lines.push(q.question);
162
+ lines.push("");
163
+ lines.push(`- **Asked because:** ${q.context}`);
164
+ lines.push(`- **Refs:** ${q.refs.join(", ")}`);
165
+ lines.push("");
166
+ }
167
+ return lines.join("\n");
168
+ }
169
+ //# sourceMappingURL=questions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.js","sourceRoot":"","sources":["../../src/interview/questions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type Result } from "../frontmatter/types.js";
2
+ import type { InterviewQuestion } from "./questions.js";
3
+ export declare const DEFAULT_INTERVIEW_COLLECTION = "interviews";
4
+ export declare const COLLECTION_NAME_RE: RegExp;
5
+ export declare function isValidCollectionName(name: string): boolean;
6
+ export interface InterviewAnswer {
7
+ question: InterviewQuestion;
8
+ answer: string;
9
+ }
10
+ export interface TranscriptMeta {
11
+ date: string;
12
+ by: string;
13
+ collection: string;
14
+ }
15
+ export declare function renderTranscript(answers: InterviewAnswer[], meta: TranscriptMeta): string;
16
+ export declare function transcriptRelPath(vaultRoot: string, collection: string, date: string): string;
17
+ export interface WriteTranscriptResult {
18
+ relPath: string;
19
+ commitHash: string | null;
20
+ warning?: string;
21
+ }
22
+ export declare function writeTranscript(vaultRoot: string, answers: InterviewAnswer[], meta: TranscriptMeta): Promise<Result<WriteTranscriptResult, Error>>;
23
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/interview/transcript.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAI/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,eAAO,MAAM,4BAA4B,eAAe,CAAC;AAOzD,eAAO,MAAM,kBAAkB,QAAqB,CAAC;AASrD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CA8CzF;AAKD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAO7F;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,EAAE,EAC1B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAoE/C"}
@@ -0,0 +1,155 @@
1
+ // Interview transcript — the fold-back half of `daftari interview`.
2
+ //
3
+ // Answers are the principal's words, verbatim, and the transcript is a
4
+ // first-class vault document so the testimony joins the corpus: indexed,
5
+ // searchable, citable as a reference in a court ruling. Frontmatter posture
6
+ // (see the 2026-07-25 design spec):
7
+ //
8
+ // tier: source — verbatim human words are raw source material;
9
+ // the body is immutable to every writer (#141)
10
+ // provenance: direct — the principal's own statement, not a synthesis
11
+ // ttl_days: null — a record of what was said on a date never expires
12
+ // sources — the tension ids / doc paths that prompted each
13
+ // question, so testimony traces back to its signals
14
+ // questions_answered — the question texts, so a later sheet never
15
+ // re-asks what a transcript already answered
16
+ //
17
+ // Recording testimony resolves nothing. Tensions close only through a
18
+ // ruling; stale docs freshen only through a re-verified write.
19
+ import { existsSync } from "node:fs";
20
+ import { mkdir, writeFile } from "node:fs/promises";
21
+ import { dirname, join } from "node:path";
22
+ import matter from "gray-matter";
23
+ import { parseDocument } from "../frontmatter/parser.js";
24
+ import { err, ok } from "../frontmatter/types.js";
25
+ import { resolveVaultPath } from "../storage/local.js";
26
+ import { loadConfig } from "../utils/config.js";
27
+ import { commit } from "../utils/git.js";
28
+ export const DEFAULT_INTERVIEW_COLLECTION = "interviews";
29
+ // The collection name travels into both the transcript's frontmatter and its
30
+ // on-disk path, so it is allow-listed rather than escaped: one path segment,
31
+ // no separators, no `.` (rules out `..`), nothing YAML-significant. The same
32
+ // frontmatter-vs-path collection confusion was hardened on the MCP write
33
+ // path (S1, 2026-07-01) — the CLI flag gets the same treatment.
34
+ export const COLLECTION_NAME_RE = /^[A-Za-z0-9_-]+$/;
35
+ // Segments listFiles hard-ignores that the regex alone would admit (its other
36
+ // ignores — .daftari, .obsidian, .trash — are already blocked by the no-dot
37
+ // rule). A transcript under one of these would be written and committed but
38
+ // invisible to every vault-wide scan: staleness, lint, reindex, a later
39
+ // interview sheet. Fail loudly here instead.
40
+ const RESERVED_COLLECTION_NAMES = new Set(["node_modules"]);
41
+ export function isValidCollectionName(name) {
42
+ return COLLECTION_NAME_RE.test(name) && !RESERVED_COLLECTION_NAMES.has(name);
43
+ }
44
+ export function renderTranscript(answers, meta) {
45
+ const sources = [...new Set(answers.flatMap((a) => a.question.refs))];
46
+ // Serialized with matter.stringify (js-yaml), the same path vault_write and
47
+ // the OKF bridge use — arbitrary strings (quoted claims, verbatim answers)
48
+ // can never produce malformed YAML. Insertion order is the emitted order.
49
+ const frontmatter = {
50
+ title: `Interview — ${meta.date}`,
51
+ domain: "accumulation",
52
+ collection: meta.collection,
53
+ status: "canonical",
54
+ confidence: "high",
55
+ created: meta.date,
56
+ updated: meta.date,
57
+ updated_by: meta.by,
58
+ provenance: "direct",
59
+ tier: "source",
60
+ sources,
61
+ superseded_by: null,
62
+ ttl_days: null,
63
+ tags: ["interview"],
64
+ questions_answered: answers.map((a) => a.question.question),
65
+ questions_raised: [],
66
+ };
67
+ const body = [
68
+ `# Interview — ${meta.date}`,
69
+ "",
70
+ "Answers are the principal's words, verbatim. Recording testimony",
71
+ "resolves nothing: tensions close only through a ruling (`daftari court",
72
+ "rule`), and stale documents freshen only through a re-verified write.",
73
+ "",
74
+ ];
75
+ for (const { question, answer } of answers) {
76
+ body.push(`## ${question.id} — ${question.kind}`);
77
+ body.push("");
78
+ body.push(`**Q:** ${question.question}`);
79
+ body.push("");
80
+ body.push(`- **Asked because:** ${question.context}`);
81
+ body.push(`- **Refs:** ${question.refs.join(", ")}`);
82
+ body.push("");
83
+ body.push(`**A:** ${answer}`);
84
+ body.push("");
85
+ }
86
+ return matter.stringify(`\n${body.join("\n")}`, frontmatter);
87
+ }
88
+ // Allocates a collision-free vault-relative path for today's transcript:
89
+ // interviews/2026-07-25-interview.md, then -2, -3, … if the principal sits
90
+ // for more than one session a day.
91
+ export function transcriptRelPath(vaultRoot, collection, date) {
92
+ const base = `${collection}/${date}-interview`;
93
+ let rel = `${base}.md`;
94
+ for (let n = 2; existsSync(join(vaultRoot, rel)); n++) {
95
+ rel = `${base}-${n}.md`;
96
+ }
97
+ return rel;
98
+ }
99
+ // Writes the transcript into the vault and auto-commits, honoring the
100
+ // vault's `auto_commit` and `git_dir` config exactly like the MCP write
101
+ // path. A failed commit is a warning, not a failure — the file is on disk
102
+ // and durable either way (the initVault convention).
103
+ export async function writeTranscript(vaultRoot, answers, meta) {
104
+ if (answers.length === 0) {
105
+ return err(new Error("writeTranscript requires at least one answer"));
106
+ }
107
+ if (!isValidCollectionName(meta.collection)) {
108
+ return err(new Error(`invalid collection name '${meta.collection}' — one path segment matching ` +
109
+ `${COLLECTION_NAME_RE}, not a reserved name`));
110
+ }
111
+ const content = renderTranscript(answers, meta);
112
+ // Refuse to persist testimony the vault could not read back: the rendered
113
+ // document must round-trip the same parser every read uses, cleanly.
114
+ const roundTrip = parseDocument(content);
115
+ if (!roundTrip.ok) {
116
+ return err(new Error(`refusing to write a malformed transcript: ${roundTrip.error.message}`));
117
+ }
118
+ if (!roundTrip.value.validation.valid) {
119
+ const issues = roundTrip.value.validation.issues
120
+ .map((i) => `${i.field}: ${i.message}`)
121
+ .join("; ");
122
+ return err(new Error(`refusing to write an invalid transcript: ${issues}`));
123
+ }
124
+ // Vault confinement, same gate as every other write path. The allow-list
125
+ // above already rules out traversal; this keeps the invariant structural
126
+ // rather than an accident of the regex.
127
+ const resolved = resolveVaultPath(vaultRoot, transcriptRelPath(vaultRoot, meta.collection, meta.date));
128
+ if (!resolved.ok)
129
+ return resolved;
130
+ const relPath = resolved.value.relPath;
131
+ try {
132
+ await mkdir(dirname(resolved.value.absPath), { recursive: true });
133
+ await writeFile(resolved.value.absPath, content, "utf-8");
134
+ }
135
+ catch (e) {
136
+ const reason = e instanceof Error ? e.message : String(e);
137
+ return err(new Error(`cannot write transcript: ${reason}`));
138
+ }
139
+ const config = loadConfig(vaultRoot);
140
+ const autoCommit = config.ok ? config.value.autoCommit : true;
141
+ const gitDir = config.ok ? config.value.gitDir : undefined;
142
+ if (!autoCommit) {
143
+ return ok({ relPath, commitHash: null });
144
+ }
145
+ const committed = await commit(vaultRoot, [relPath], `Record interview ${meta.date} (${answers.length} answer${answers.length === 1 ? "" : "s"})`, meta.by, { gitDir });
146
+ if (!committed.ok) {
147
+ return ok({
148
+ relPath,
149
+ commitHash: null,
150
+ warning: `transcript written but not committed: ${committed.error.message}`,
151
+ });
152
+ }
153
+ return ok({ relPath, commitHash: committed.value.hash });
154
+ }
155
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/interview/transcript.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/okf/export.ts"],"names":[],"mappings":"AAaA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAK/D,MAAM,WAAW,aAAa;IAG5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAwDD,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CA8DtC"}
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/okf/export.ts"],"names":[],"mappings":"AAeA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAK/D,MAAM,WAAW,aAAa;IAG5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAwDD,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CA8DtC"}