daftari 1.30.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 (310) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/README.md +188 -4
  3. package/dist/access/rbac.d.ts +1 -0
  4. package/dist/access/rbac.d.ts.map +1 -1
  5. package/dist/access/rbac.js +7 -0
  6. package/dist/access/rbac.js.map +1 -1
  7. package/dist/audit/checks/broken_refs.d.ts +1 -1
  8. package/dist/audit/checks/broken_refs.d.ts.map +1 -1
  9. package/dist/audit/checks/broken_refs.js +77 -22
  10. package/dist/audit/checks/broken_refs.js.map +1 -1
  11. package/dist/audit/collect.d.ts +1 -0
  12. package/dist/audit/collect.d.ts.map +1 -1
  13. package/dist/audit/collect.js +22 -2
  14. package/dist/audit/collect.js.map +1 -1
  15. package/dist/audit/index.d.ts.map +1 -1
  16. package/dist/audit/index.js +9 -3
  17. package/dist/audit/index.js.map +1 -1
  18. package/dist/audit/links.d.ts.map +1 -1
  19. package/dist/audit/links.js +9 -3
  20. package/dist/audit/links.js.map +1 -1
  21. package/dist/audit/report.d.ts.map +1 -1
  22. package/dist/audit/report.js +2 -0
  23. package/dist/audit/report.js.map +1 -1
  24. package/dist/audit/types.d.ts +4 -1
  25. package/dist/audit/types.d.ts.map +1 -1
  26. package/dist/audit/types.js.map +1 -1
  27. package/dist/backfill/derive.d.ts.map +1 -1
  28. package/dist/backfill/derive.js +1 -0
  29. package/dist/backfill/derive.js.map +1 -1
  30. package/dist/cli.d.ts.map +1 -1
  31. package/dist/cli.js +24 -0
  32. package/dist/cli.js.map +1 -1
  33. package/dist/consolidate/index.d.ts.map +1 -1
  34. package/dist/consolidate/index.js +10 -12
  35. package/dist/consolidate/index.js.map +1 -1
  36. package/dist/court/precedent.d.ts.map +1 -1
  37. package/dist/court/precedent.js +6 -1
  38. package/dist/court/precedent.js.map +1 -1
  39. package/dist/curation/consumes.d.ts +24 -0
  40. package/dist/curation/consumes.d.ts.map +1 -0
  41. package/dist/curation/consumes.js +122 -0
  42. package/dist/curation/consumes.js.map +1 -0
  43. package/dist/curation/edge-staleness.d.ts +47 -0
  44. package/dist/curation/edge-staleness.d.ts.map +1 -0
  45. package/dist/curation/edge-staleness.js +258 -0
  46. package/dist/curation/edge-staleness.js.map +1 -0
  47. package/dist/curation/edges.d.ts.map +1 -1
  48. package/dist/curation/edges.js +190 -17
  49. package/dist/curation/edges.js.map +1 -1
  50. package/dist/curation/lint.d.ts +6 -1
  51. package/dist/curation/lint.d.ts.map +1 -1
  52. package/dist/curation/lint.js +87 -24
  53. package/dist/curation/lint.js.map +1 -1
  54. package/dist/curation/provenance.d.ts +2 -0
  55. package/dist/curation/provenance.d.ts.map +1 -1
  56. package/dist/curation/provenance.js +2 -0
  57. package/dist/curation/provenance.js.map +1 -1
  58. package/dist/curation/read-log.d.ts +19 -0
  59. package/dist/curation/read-log.d.ts.map +1 -0
  60. package/dist/curation/read-log.js +120 -0
  61. package/dist/curation/read-log.js.map +1 -0
  62. package/dist/curation/review-throughput.d.ts +24 -0
  63. package/dist/curation/review-throughput.d.ts.map +1 -0
  64. package/dist/curation/review-throughput.js +102 -0
  65. package/dist/curation/review-throughput.js.map +1 -0
  66. package/dist/curation/shadow.d.ts +1 -0
  67. package/dist/curation/shadow.d.ts.map +1 -1
  68. package/dist/curation/shadow.js +17 -11
  69. package/dist/curation/shadow.js.map +1 -1
  70. package/dist/curation/staged-actions.d.ts +12 -1
  71. package/dist/curation/staged-actions.d.ts.map +1 -1
  72. package/dist/curation/staged-actions.js +123 -48
  73. package/dist/curation/staged-actions.js.map +1 -1
  74. package/dist/curation/structural.d.ts +16 -0
  75. package/dist/curation/structural.d.ts.map +1 -0
  76. package/dist/curation/structural.js +64 -0
  77. package/dist/curation/structural.js.map +1 -0
  78. package/dist/curation/tension-blast.d.ts +4 -0
  79. package/dist/curation/tension-blast.d.ts.map +1 -1
  80. package/dist/curation/tension-blast.js +9 -0
  81. package/dist/curation/tension-blast.js.map +1 -1
  82. package/dist/curation/tension.d.ts +5 -2
  83. package/dist/curation/tension.d.ts.map +1 -1
  84. package/dist/curation/tension.js +68 -25
  85. package/dist/curation/tension.js.map +1 -1
  86. package/dist/curation/tier0.d.ts +27 -0
  87. package/dist/curation/tier0.d.ts.map +1 -0
  88. package/dist/curation/tier0.js +196 -0
  89. package/dist/curation/tier0.js.map +1 -0
  90. package/dist/curation/tier1.d.ts +30 -0
  91. package/dist/curation/tier1.d.ts.map +1 -0
  92. package/dist/curation/tier1.js +142 -0
  93. package/dist/curation/tier1.js.map +1 -0
  94. package/dist/curation/tier2.d.ts +43 -0
  95. package/dist/curation/tier2.d.ts.map +1 -0
  96. package/dist/curation/tier2.js +182 -0
  97. package/dist/curation/tier2.js.map +1 -0
  98. package/dist/curation/vault-docs.d.ts +5 -1
  99. package/dist/curation/vault-docs.d.ts.map +1 -1
  100. package/dist/curation/vault-docs.js +14 -0
  101. package/dist/curation/vault-docs.js.map +1 -1
  102. package/dist/eval/generate.d.ts.map +1 -1
  103. package/dist/eval/generate.js +38 -5
  104. package/dist/eval/generate.js.map +1 -1
  105. package/dist/eval/index.d.ts +1 -0
  106. package/dist/eval/index.d.ts.map +1 -1
  107. package/dist/eval/index.js +249 -50
  108. package/dist/eval/index.js.map +1 -1
  109. package/dist/eval/llm-openrouter.d.ts.map +1 -1
  110. package/dist/eval/llm-openrouter.js +158 -65
  111. package/dist/eval/llm-openrouter.js.map +1 -1
  112. package/dist/eval/llm.js +1 -1
  113. package/dist/eval/llm.js.map +1 -1
  114. package/dist/eval/prune.d.ts +24 -0
  115. package/dist/eval/prune.d.ts.map +1 -0
  116. package/dist/eval/prune.js +83 -0
  117. package/dist/eval/prune.js.map +1 -0
  118. package/dist/eval/storage.d.ts +3 -0
  119. package/dist/eval/storage.d.ts.map +1 -1
  120. package/dist/eval/storage.js +14 -0
  121. package/dist/eval/storage.js.map +1 -1
  122. package/dist/frontmatter/schema.d.ts.map +1 -1
  123. package/dist/frontmatter/schema.js +19 -1
  124. package/dist/frontmatter/schema.js.map +1 -1
  125. package/dist/frontmatter/types.d.ts +4 -1
  126. package/dist/frontmatter/types.d.ts.map +1 -1
  127. package/dist/frontmatter/types.js +8 -0
  128. package/dist/frontmatter/types.js.map +1 -1
  129. package/dist/import/index.d.ts.map +1 -1
  130. package/dist/import/index.js +44 -9
  131. package/dist/import/index.js.map +1 -1
  132. package/dist/import/langgraph-store.d.ts +53 -0
  133. package/dist/import/langgraph-store.d.ts.map +1 -0
  134. package/dist/import/langgraph-store.js +292 -0
  135. package/dist/import/langgraph-store.js.map +1 -0
  136. package/dist/index.d.ts +5 -0
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +56 -18
  139. package/dist/index.js.map +1 -1
  140. package/dist/interview/index.d.ts +7 -0
  141. package/dist/interview/index.d.ts.map +1 -0
  142. package/dist/interview/index.js +219 -0
  143. package/dist/interview/index.js.map +1 -0
  144. package/dist/interview/questions.d.ts +18 -0
  145. package/dist/interview/questions.d.ts.map +1 -0
  146. package/dist/interview/questions.js +169 -0
  147. package/dist/interview/questions.js.map +1 -0
  148. package/dist/interview/transcript.d.ts +23 -0
  149. package/dist/interview/transcript.d.ts.map +1 -0
  150. package/dist/interview/transcript.js +155 -0
  151. package/dist/interview/transcript.js.map +1 -0
  152. package/dist/lifecycle/lock.d.ts +9 -1
  153. package/dist/lifecycle/lock.d.ts.map +1 -1
  154. package/dist/lifecycle/lock.js +34 -9
  155. package/dist/lifecycle/lock.js.map +1 -1
  156. package/dist/okf/export.d.ts +12 -0
  157. package/dist/okf/export.d.ts.map +1 -0
  158. package/dist/okf/export.js +117 -0
  159. package/dist/okf/export.js.map +1 -0
  160. package/dist/okf/import.d.ts +24 -0
  161. package/dist/okf/import.d.ts.map +1 -0
  162. package/dist/okf/import.js +115 -0
  163. package/dist/okf/import.js.map +1 -0
  164. package/dist/okf/index.d.ts +2 -0
  165. package/dist/okf/index.d.ts.map +1 -0
  166. package/dist/okf/index.js +159 -0
  167. package/dist/okf/index.js.map +1 -0
  168. package/dist/okf/map.d.ts +27 -0
  169. package/dist/okf/map.d.ts.map +1 -0
  170. package/dist/okf/map.js +327 -0
  171. package/dist/okf/map.js.map +1 -0
  172. package/dist/okf/types.d.ts +13 -0
  173. package/dist/okf/types.d.ts.map +1 -0
  174. package/dist/okf/types.js +82 -0
  175. package/dist/okf/types.js.map +1 -0
  176. package/dist/search/coverage.d.ts.map +1 -1
  177. package/dist/search/coverage.js +1 -1
  178. package/dist/search/coverage.js.map +1 -1
  179. package/dist/search/hybrid.d.ts +19 -0
  180. package/dist/search/hybrid.d.ts.map +1 -1
  181. package/dist/search/hybrid.js +60 -15
  182. package/dist/search/hybrid.js.map +1 -1
  183. package/dist/search/reindex.d.ts +4 -0
  184. package/dist/search/reindex.d.ts.map +1 -1
  185. package/dist/search/reindex.js +64 -14
  186. package/dist/search/reindex.js.map +1 -1
  187. package/dist/search/watcher.d.ts +2 -0
  188. package/dist/search/watcher.d.ts.map +1 -1
  189. package/dist/search/watcher.js +29 -27
  190. package/dist/search/watcher.js.map +1 -1
  191. package/dist/serve/index.d.ts +36 -0
  192. package/dist/serve/index.d.ts.map +1 -0
  193. package/dist/serve/index.js +507 -0
  194. package/dist/serve/index.js.map +1 -0
  195. package/dist/server.d.ts +10 -1
  196. package/dist/server.d.ts.map +1 -1
  197. package/dist/server.js +89 -14
  198. package/dist/server.js.map +1 -1
  199. package/dist/sleep/index.d.ts +2 -0
  200. package/dist/sleep/index.d.ts.map +1 -1
  201. package/dist/sleep/index.js +212 -21
  202. package/dist/sleep/index.js.map +1 -1
  203. package/dist/sleep/report.d.ts +3 -0
  204. package/dist/sleep/report.d.ts.map +1 -1
  205. package/dist/sleep/report.js +52 -0
  206. package/dist/sleep/report.js.map +1 -1
  207. package/dist/sleep/tension-scan-state.d.ts +19 -0
  208. package/dist/sleep/tension-scan-state.d.ts.map +1 -0
  209. package/dist/sleep/tension-scan-state.js +0 -0
  210. package/dist/sleep/tension-scan-state.js.map +1 -0
  211. package/dist/sleep/tension-scan.d.ts +44 -0
  212. package/dist/sleep/tension-scan.d.ts.map +1 -0
  213. package/dist/sleep/tension-scan.js +0 -0
  214. package/dist/sleep/tension-scan.js.map +1 -0
  215. package/dist/storage/backend.d.ts +12 -0
  216. package/dist/storage/backend.d.ts.map +1 -0
  217. package/dist/storage/backend.js +231 -0
  218. package/dist/storage/backend.js.map +1 -0
  219. package/dist/storage/backends/fs.d.ts +4 -0
  220. package/dist/storage/backends/fs.d.ts.map +1 -0
  221. package/dist/storage/backends/fs.js +99 -0
  222. package/dist/storage/backends/fs.js.map +1 -0
  223. package/dist/storage/fs-walk.d.ts +5 -0
  224. package/dist/storage/fs-walk.d.ts.map +1 -0
  225. package/dist/storage/fs-walk.js +28 -0
  226. package/dist/storage/fs-walk.js.map +1 -0
  227. package/dist/storage/index-db.d.ts +16 -0
  228. package/dist/storage/index-db.d.ts.map +1 -1
  229. package/dist/storage/index-db.js +95 -5
  230. package/dist/storage/index-db.js.map +1 -1
  231. package/dist/storage/local.d.ts +1 -0
  232. package/dist/storage/local.d.ts.map +1 -1
  233. package/dist/storage/local.js +12 -0
  234. package/dist/storage/local.js.map +1 -1
  235. package/dist/storage/sync.d.ts +25 -0
  236. package/dist/storage/sync.d.ts.map +1 -0
  237. package/dist/storage/sync.js +308 -0
  238. package/dist/storage/sync.js.map +1 -0
  239. package/dist/sync/index.d.ts +2 -0
  240. package/dist/sync/index.d.ts.map +1 -0
  241. package/dist/sync/index.js +136 -0
  242. package/dist/sync/index.js.map +1 -0
  243. package/dist/themes/clustering.d.ts +6 -11
  244. package/dist/themes/clustering.d.ts.map +1 -1
  245. package/dist/themes/clustering.js +76 -84
  246. package/dist/themes/clustering.js.map +1 -1
  247. package/dist/tools/consumes.d.ts +14 -0
  248. package/dist/tools/consumes.d.ts.map +1 -0
  249. package/dist/tools/consumes.js +99 -0
  250. package/dist/tools/consumes.js.map +1 -0
  251. package/dist/tools/curation.d.ts +2 -0
  252. package/dist/tools/curation.d.ts.map +1 -1
  253. package/dist/tools/curation.js +53 -15
  254. package/dist/tools/curation.js.map +1 -1
  255. package/dist/tools/edge-staleness.d.ts +28 -0
  256. package/dist/tools/edge-staleness.d.ts.map +1 -0
  257. package/dist/tools/edge-staleness.js +205 -0
  258. package/dist/tools/edge-staleness.js.map +1 -0
  259. package/dist/tools/edges.d.ts.map +1 -1
  260. package/dist/tools/edges.js +27 -21
  261. package/dist/tools/edges.js.map +1 -1
  262. package/dist/tools/read.d.ts +15 -1
  263. package/dist/tools/read.d.ts.map +1 -1
  264. package/dist/tools/read.js +211 -76
  265. package/dist/tools/read.js.map +1 -1
  266. package/dist/tools/receipt.d.ts.map +1 -1
  267. package/dist/tools/receipt.js +16 -7
  268. package/dist/tools/receipt.js.map +1 -1
  269. package/dist/tools/search.d.ts +1 -0
  270. package/dist/tools/search.d.ts.map +1 -1
  271. package/dist/tools/search.js +147 -5
  272. package/dist/tools/search.js.map +1 -1
  273. package/dist/tools/staged-actions.d.ts +3 -0
  274. package/dist/tools/staged-actions.d.ts.map +1 -1
  275. package/dist/tools/staged-actions.js +225 -22
  276. package/dist/tools/staged-actions.js.map +1 -1
  277. package/dist/tools/themes.d.ts +8 -0
  278. package/dist/tools/themes.d.ts.map +1 -1
  279. package/dist/tools/themes.js +208 -122
  280. package/dist/tools/themes.js.map +1 -1
  281. package/dist/tools/tier1.d.ts +14 -0
  282. package/dist/tools/tier1.d.ts.map +1 -0
  283. package/dist/tools/tier1.js +169 -0
  284. package/dist/tools/tier1.js.map +1 -0
  285. package/dist/tools/tier2.d.ts +27 -0
  286. package/dist/tools/tier2.d.ts.map +1 -0
  287. package/dist/tools/tier2.js +344 -0
  288. package/dist/tools/tier2.js.map +1 -0
  289. package/dist/tools/write.d.ts +9 -1
  290. package/dist/tools/write.d.ts.map +1 -1
  291. package/dist/tools/write.js +596 -174
  292. package/dist/tools/write.js.map +1 -1
  293. package/dist/utils/config.d.ts +52 -0
  294. package/dist/utils/config.d.ts.map +1 -1
  295. package/dist/utils/config.js +394 -24
  296. package/dist/utils/config.js.map +1 -1
  297. package/dist/utils/dates.d.ts +1 -0
  298. package/dist/utils/dates.d.ts.map +1 -1
  299. package/dist/utils/dates.js +5 -0
  300. package/dist/utils/dates.js.map +1 -1
  301. package/dist/utils/run-id.d.ts +3 -0
  302. package/dist/utils/run-id.d.ts.map +1 -0
  303. package/dist/utils/run-id.js +19 -0
  304. package/dist/utils/run-id.js.map +1 -0
  305. package/dist/utils/vault-gitignore.d.ts +1 -1
  306. package/dist/utils/vault-gitignore.d.ts.map +1 -1
  307. package/dist/utils/vault-gitignore.js +4 -1
  308. package/dist/utils/vault-gitignore.js.map +1 -1
  309. package/package.json +21 -1
  310. package/templates/config.yaml +8 -0
@@ -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":"AAAA,oEAAoE;AACpE,EAAE;AACF,uEAAuE;AACvE,yEAAyE;AACzE,4EAA4E;AAC5E,oCAAoC;AACpC,EAAE;AACF,wEAAwE;AACxE,uEAAuE;AACvE,yEAAyE;AACzE,4EAA4E;AAC5E,yEAAyE;AACzE,4EAA4E;AAC5E,qEAAqE;AACrE,qEAAqE;AACrE,EAAE;AACF,sEAAsE;AACtE,+DAA+D;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,MAAM,CAAC,MAAM,4BAA4B,GAAG,YAAY,CAAC;AAEzD,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,gEAAgE;AAChE,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAErD,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,wEAAwE;AACxE,6CAA6C;AAC7C,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AAE5D,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/E,CAAC;AAaD,MAAM,UAAU,gBAAgB,CAAC,OAA0B,EAAE,IAAoB;IAC/E,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtE,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,WAAW,GAA4B;QAC3C,KAAK,EAAE,eAAe,IAAI,CAAC,IAAI,EAAE;QACjC,MAAM,EAAE,cAAc;QACtB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,WAAW;QACnB,UAAU,EAAE,MAAM;QAClB,OAAO,EAAE,IAAI,CAAC,IAAI;QAClB,OAAO,EAAE,IAAI,CAAC,IAAI;QAClB,UAAU,EAAE,IAAI,CAAC,EAAE;QACnB,UAAU,EAAE,QAAQ;QACpB,IAAI,EAAE,QAAQ;QACd,OAAO;QACP,aAAa,EAAE,IAAI;QACnB,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,CAAC,WAAW,CAAC;QACnB,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC3D,gBAAgB,EAAE,EAAE;KACrB,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,iBAAiB,IAAI,CAAC,IAAI,EAAE;QAC5B,EAAE;QACF,kEAAkE;QAClE,wEAAwE;QACxE,uEAAuE;QACvE,EAAE;KACH,CAAC;IACF,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,wBAAwB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,CAAC,eAAe,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED,yEAAyE;AACzE,2EAA2E;AAC3E,mCAAmC;AACnC,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,UAAkB,EAAE,IAAY;IACnF,MAAM,IAAI,GAAG,GAAG,UAAU,IAAI,IAAI,YAAY,CAAC;IAC/C,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtD,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAQD,sEAAsE;AACtE,wEAAwE;AACxE,0EAA0E;AAC1E,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,OAA0B,EAC1B,IAAoB;IAEpB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5C,OAAO,GAAG,CACR,IAAI,KAAK,CACP,4BAA4B,IAAI,CAAC,UAAU,gCAAgC;YACzE,GAAG,kBAAkB,uBAAuB,CAC/C,CACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAChD,0EAA0E;IAC1E,qEAAqE;IACrE,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,6CAA6C,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM;aAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACtC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,4CAA4C,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,yEAAyE;IACzE,yEAAyE;IACzE,wCAAwC;IACxC,MAAM,QAAQ,GAAG,gBAAgB,CAC/B,SAAS,EACT,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CACzD,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1D,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,4BAA4B,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAE3D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,MAAM,CAC5B,SAAS,EACT,CAAC,OAAO,CAAC,EACT,oBAAoB,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAC5F,IAAI,CAAC,EAAE,EACP,EAAE,MAAM,EAAE,CACX,CAAC;IACF,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;YACR,OAAO;YACP,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,yCAAyC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE;SAC5E,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC"}
@@ -1,15 +1,23 @@
1
1
  import { type Result } from "../frontmatter/types.js";
2
+ export type LockMode = "stdio" | "serve";
2
3
  export type LockData = {
3
4
  daftari: true;
4
5
  pid: number;
5
6
  vaultRoot: string;
6
7
  startedAt: string;
7
8
  version: string;
9
+ mode?: LockMode;
10
+ bind?: string;
8
11
  };
9
12
  export declare function readLockfile(vaultRoot: string): Result<LockData | null, Error>;
10
13
  export declare function writeLockfile(vaultRoot: string, data: LockData): Result<void, Error>;
11
14
  export declare function isProcessAlive(pid: number): boolean;
12
15
  export declare function isDaftariProcess(pid: number, vaultRoot: string): boolean;
13
- export declare function acquireLock(vaultRoot: string, version: string): Promise<Result<void, Error>>;
16
+ export interface AcquireLockOptions {
17
+ mode?: LockMode;
18
+ bind?: string;
19
+ takeover?: boolean;
20
+ }
21
+ export declare function acquireLock(vaultRoot: string, version: string, options?: AcquireLockOptions): Promise<Result<void, Error>>;
14
22
  export declare function releaseLock(vaultRoot: string): void;
15
23
  //# sourceMappingURL=lock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/lifecycle/lock.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,IAAI,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,IAAI,EAAE,KAAK,CAAC,CAmB9E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAQpF;AAKD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQnD;AAaD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAYxE;AA8CD,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CA2C9B;AAMD,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CASnD"}
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/lifecycle/lock.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAI/D,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzC,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,IAAI,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAGhB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAMF,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,IAAI,EAAE,KAAK,CAAC,CAmB9E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAQpF;AAKD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQnD;AAaD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAYxE;AAoCD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAqBD,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAsE9B;AAMD,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CASnD"}
@@ -115,23 +115,35 @@ function tryCreateExclusive(vaultRoot, data) {
115
115
  return err(errno);
116
116
  }
117
117
  }
118
- // Acquire the per-vault process lock. Behavior:
118
+ // Acquire the per-vault process lock. Behavior (#52, amended by #5 spec
119
+ // 2026-07-20 Decision 4):
119
120
  // - No existing lock → atomic O_EXCL create, return ok.
120
- // - Existing lock with dead PID → stale, overwrite.
121
+ // - Existing lock with dead PID → stale, overwrite (every mode).
121
122
  // - Existing lock with live PID that does not look like a daftari for this
122
- // vault (PID recycled) → stale, overwrite.
123
- // - Existing lock with live daftari for this vault SIGTERM it, wait up to
124
- // 3s for exit, then overwrite. If it does not exit, log a warning and
125
- // overwrite anyway.
123
+ // vault (PID recycled) → stale, overwrite (every mode).
124
+ // - LIVE daftari holder precedence favors the durable tenant:
125
+ // stdio finding stdio → SIGTERM-and-wait takeover (the
126
+ // single-user convenience, unchanged).
127
+ // stdio finding serve → REFUSE, naming the server and the
128
+ // remedy. Never SIGTERMs a serve holder.
129
+ // serve finding stdio or serve → REFUSE unless --takeover: a server
130
+ // deployment must not silently kill a
131
+ // live desktop session, and a
132
+ // double-start must not bounce every
133
+ // session. With takeover, SIGTERM-and-
134
+ // wait against either holder mode.
126
135
  //
127
136
  // Logs go to stderr (MCP convention; stdout is reserved for JSON-RPC).
128
- export async function acquireLock(vaultRoot, version) {
137
+ export async function acquireLock(vaultRoot, version, options = {}) {
138
+ const mode = options.mode ?? "stdio";
129
139
  const our = {
130
140
  daftari: true,
131
141
  pid: process.pid,
132
142
  vaultRoot,
133
143
  startedAt: new Date().toISOString(),
134
144
  version,
145
+ mode,
146
+ ...(options.bind ? { bind: options.bind } : {}),
135
147
  };
136
148
  const created = tryCreateExclusive(vaultRoot, our);
137
149
  if (!created.ok)
@@ -144,8 +156,21 @@ export async function acquireLock(vaultRoot, version) {
144
156
  if (existing.value !== null) {
145
157
  const prior = existing.value;
146
158
  if (isDaftariProcess(prior.pid, vaultRoot)) {
147
- process.stderr.write(`daftari: another instance is holding this vault (pid=${prior.pid}, ` +
148
- `started=${prior.startedAt}); sending SIGTERM and taking over\n`);
159
+ const priorMode = prior.mode ?? "stdio";
160
+ const holder = `pid=${prior.pid}, mode=${priorMode}, started=${prior.startedAt}` +
161
+ (prior.bind ? `, bind=${prior.bind}` : "");
162
+ if (mode === "stdio" && priorMode === "serve") {
163
+ return err(new Error(`this vault is held by a live daftari serve (${holder}). ` +
164
+ `Connect to it over HTTP instead, or stop the server ` +
165
+ `deliberately (or replace it with 'daftari serve --takeover').`));
166
+ }
167
+ if (mode === "serve" && !options.takeover) {
168
+ return err(new Error(`this vault is held by a live daftari instance (${holder}). ` +
169
+ `A server start never silently replaces a live holder; ` +
170
+ `re-run with --takeover to replace it deliberately.`));
171
+ }
172
+ process.stderr.write(`daftari: another instance is holding this vault (${holder}); ` +
173
+ `sending SIGTERM and taking over\n`);
149
174
  try {
150
175
  process.kill(prior.pid, "SIGTERM");
151
176
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/lifecycle/lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/lifecycle/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type Result } from "../frontmatter/types.js";
2
+ export interface ExportOptions {
3
+ collection?: string;
4
+ }
5
+ export interface ExportResult {
6
+ outDir: string;
7
+ documentCount: number;
8
+ skipped: number;
9
+ warnings: string[];
10
+ }
11
+ export declare function exportBundle(vaultRoot: string, outDir: string, options?: ExportOptions): Promise<Result<ExportResult, Error>>;
12
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,117 @@
1
+ // `daftari okf export` — render a Daftari vault as an OKF bundle.
2
+ //
3
+ // Each vault document becomes an OKF concept doc at the same relative path (so
4
+ // the collection folder layout is preserved), with OKF core frontmatter — v0.2
5
+ // trust signals (`generated`, `status`, `stale_after`, structured `sources`)
6
+ // derived from the doc's native metadata — plus a verbatim `daftari` sidecar
7
+ // for lossless round-trip. Two reserved files are
8
+ // generated at the bundle root: index.md (a progressive-disclosure listing) and
9
+ // log.md (a chronological history, newest first). The source vault is never
10
+ // mutated — this is a pure read-then-write to a separate output directory.
11
+ import { mkdir, writeFile } from "node:fs/promises";
12
+ import { dirname, join } from "node:path";
13
+ import matter from "gray-matter";
14
+ import { parseDocument } from "../frontmatter/parser.js";
15
+ import { err, ok } from "../frontmatter/types.js";
16
+ import { listFiles, readFile } from "../storage/local.js";
17
+ import { daftariToOkf, deriveDescription } from "./map.js";
18
+ import { OKF_INDEX_FILE, OKF_RESERVED_FILES, OKF_VERSION } from "./types.js";
19
+ function collectionOf(relPath) {
20
+ const parts = relPath.split("/").filter((p) => p !== "");
21
+ return parts.length > 1 ? parts[0] : "";
22
+ }
23
+ // Bundle-relative absolute link (leading "/"), the OKF form that stays stable if
24
+ // a doc is relocated.
25
+ function bundleLink(relPath) {
26
+ return `/${relPath}`;
27
+ }
28
+ function renderIndex(entries) {
29
+ const lines = ["# Index", ""];
30
+ for (const e of entries) {
31
+ const suffix = e.description ? ` — ${e.description}` : "";
32
+ lines.push(`- [${e.title}](${bundleLink(e.relPath)})${suffix}`);
33
+ }
34
+ lines.push("");
35
+ return matter.stringify(`\n${lines.join("\n")}`, { okf_version: OKF_VERSION });
36
+ }
37
+ function renderLog(entries) {
38
+ // Group by `updated` date, newest first. Entries with no usable date fall
39
+ // under an "undated" bucket sorted last.
40
+ const byDate = new Map();
41
+ for (const e of entries) {
42
+ const key = e.updated || "undated";
43
+ const bucket = byDate.get(key);
44
+ if (bucket)
45
+ bucket.push(e);
46
+ else
47
+ byDate.set(key, [e]);
48
+ }
49
+ const keys = [...byDate.keys()].sort((a, b) => {
50
+ if (a === "undated")
51
+ return 1;
52
+ if (b === "undated")
53
+ return -1;
54
+ return a < b ? 1 : a > b ? -1 : 0; // descending
55
+ });
56
+ const lines = ["# Log", ""];
57
+ for (const key of keys) {
58
+ lines.push(`## ${key}`);
59
+ for (const e of byDate.get(key) ?? []) {
60
+ lines.push(`- [${e.title}](${bundleLink(e.relPath)})`);
61
+ }
62
+ lines.push("");
63
+ }
64
+ return `${lines.join("\n").trimEnd()}\n`;
65
+ }
66
+ export async function exportBundle(vaultRoot, outDir, options = {}) {
67
+ const listed = await listFiles(vaultRoot);
68
+ if (!listed.ok)
69
+ return err(listed.error);
70
+ const warnings = [];
71
+ const entries = [];
72
+ let skipped = 0;
73
+ for (const relPath of listed.value) {
74
+ if (options.collection !== undefined && collectionOf(relPath) !== options.collection) {
75
+ continue;
76
+ }
77
+ const raw = await readFile(join(vaultRoot, relPath));
78
+ if (!raw.ok) {
79
+ warnings.push(`could not read ${relPath}: ${raw.error.message}`);
80
+ skipped++;
81
+ continue;
82
+ }
83
+ const parsed = parseDocument(raw.value);
84
+ if (!parsed.ok) {
85
+ warnings.push(`could not parse ${relPath}: ${parsed.error.message}`);
86
+ skipped++;
87
+ continue;
88
+ }
89
+ const { frontmatter, content, raw: rawFm } = parsed.value;
90
+ const okfFm = daftariToOkf(rawFm, frontmatter, content);
91
+ const fileText = matter.stringify(content.startsWith("\n") ? content : `\n${content}`, okfFm);
92
+ const targetPath = join(outDir, relPath);
93
+ await mkdir(dirname(targetPath), { recursive: true });
94
+ await writeFile(targetPath, fileText, "utf-8");
95
+ entries.push({
96
+ relPath,
97
+ title: typeof okfFm.title === "string" ? okfFm.title : relPath,
98
+ description: deriveDescription(frontmatter, content),
99
+ updated: frontmatter.updated,
100
+ });
101
+ }
102
+ entries.sort((a, b) => (a.relPath < b.relPath ? -1 : a.relPath > b.relPath ? 1 : 0));
103
+ await mkdir(outDir, { recursive: true });
104
+ // A vault doc named index.md / log.md at its root would occupy a reserved
105
+ // path. Keep the author's content and skip generating that reserved file.
106
+ const exportedPaths = new Set(entries.map((e) => e.relPath));
107
+ for (const reserved of OKF_RESERVED_FILES) {
108
+ if (exportedPaths.has(reserved)) {
109
+ warnings.push(`vault contains a root '${reserved}' — kept as a concept doc, reserved file not generated`);
110
+ continue;
111
+ }
112
+ const text = reserved === OKF_INDEX_FILE ? renderIndex(entries) : renderLog(entries);
113
+ await writeFile(join(outDir, reserved), text, "utf-8");
114
+ }
115
+ return ok({ outDir, documentCount: entries.length, skipped, warnings });
116
+ }
117
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/okf/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type Result } from "../frontmatter/types.js";
2
+ export interface ImportOptions {
3
+ agent?: string;
4
+ dryRun?: boolean;
5
+ today?: string;
6
+ }
7
+ export interface ImportPlanItem {
8
+ relPath: string;
9
+ collection: string;
10
+ title: string;
11
+ roundTrip: boolean;
12
+ }
13
+ export interface ImportResult {
14
+ vaultRoot: string;
15
+ imported: number;
16
+ skipped: number;
17
+ commit: string | null;
18
+ reindexed: boolean;
19
+ dryRun: boolean;
20
+ warnings: string[];
21
+ plan: ImportPlanItem[];
22
+ }
23
+ export declare function importBundle(bundleDir: string, vaultRoot: string, options?: ImportOptions): Promise<Result<ImportResult, Error>>;
24
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/okf/import.ts"],"names":[],"mappings":"AAeA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAQ/D,MAAM,WAAW,aAAa;IAE5B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,cAAc,EAAE,CAAC;CACxB;AAQD,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAuGtC"}
@@ -0,0 +1,115 @@
1
+ // `daftari okf import` — adopt an OKF bundle into a Daftari vault.
2
+ //
3
+ // Every non-reserved markdown file in the bundle is mapped to Daftari
4
+ // frontmatter (see okfToDaftari) and written into the target vault at the same
5
+ // relative path. A bundle produced by `daftari okf export` round-trips exactly
6
+ // via its `daftari` sidecar; a foreign bundle is mapped conservatively (imported
7
+ // docs land as drafts in the accumulation domain), with v0.2 trust signals
8
+ // informing the mapping — see okfToDaftari. Writes are auto-committed —
9
+ // git is Daftari's version layer — and the SQLite index is rebuilt so search
10
+ // sees the new docs immediately. `--dry-run` reports the plan and writes nothing.
11
+ import { mkdir, writeFile } from "node:fs/promises";
12
+ import { basename, dirname, join } from "node:path";
13
+ import { parseDocument } from "../frontmatter/parser.js";
14
+ import { validateFrontmatter } from "../frontmatter/schema.js";
15
+ import { err, ok } from "../frontmatter/types.js";
16
+ import { reindexVault } from "../search/reindex.js";
17
+ import { listFiles, readFile } from "../storage/local.js";
18
+ import { serializeDocument } from "../tools/write.js";
19
+ import { commit } from "../utils/git.js";
20
+ import { hasDaftariSidecar, isAttestedComputation, okfToDaftari } from "./map.js";
21
+ import { OKF_RESERVED_FILES } from "./types.js";
22
+ const DEFAULT_IMPORT_AGENT = "agent:okf-import";
23
+ function isReserved(relPath) {
24
+ return OKF_RESERVED_FILES.includes(basename(relPath));
25
+ }
26
+ export async function importBundle(bundleDir, vaultRoot, options = {}) {
27
+ const listed = await listFiles(bundleDir);
28
+ if (!listed.ok)
29
+ return err(listed.error);
30
+ const agent = options.agent ?? DEFAULT_IMPORT_AGENT;
31
+ const today = options.today ?? new Date().toISOString().slice(0, 10);
32
+ const dryRun = options.dryRun === true;
33
+ const warnings = [];
34
+ const plan = [];
35
+ const writtenPaths = [];
36
+ let skipped = 0;
37
+ for (const relPath of listed.value) {
38
+ if (isReserved(relPath))
39
+ continue; // structural, not a concept doc
40
+ const raw = await readFile(join(bundleDir, relPath));
41
+ if (!raw.ok) {
42
+ warnings.push(`could not read ${relPath}: ${raw.error.message}`);
43
+ skipped++;
44
+ continue;
45
+ }
46
+ const parsed = parseDocument(raw.value);
47
+ if (!parsed.ok) {
48
+ warnings.push(`could not parse ${relPath}: ${parsed.error.message}`);
49
+ skipped++;
50
+ continue;
51
+ }
52
+ const okfRaw = parsed.value.raw;
53
+ const daftariRaw = okfToDaftari(okfRaw, { relPath, today, updatedBy: agent });
54
+ const { frontmatter } = validateFrontmatter(daftariRaw);
55
+ const roundTrip = hasDaftariSidecar(okfRaw);
56
+ // Advisory only, never enforcement: a bundle's self-declared type must not
57
+ // buy write protection. The operator reviews and elevates deliberately.
58
+ if (isAttestedComputation(okfRaw.type) && !roundTrip) {
59
+ warnings.push(`${relPath}: Attested Computation imported WITHOUT write protection — ` +
60
+ `review it, then elevate with vault_set_tier (tier: source) if this vault should enforce it`);
61
+ }
62
+ plan.push({
63
+ relPath,
64
+ collection: frontmatter.collection,
65
+ title: frontmatter.title,
66
+ roundTrip,
67
+ });
68
+ if (dryRun)
69
+ continue;
70
+ const fileText = serializeDocument(frontmatter, parsed.value.content, [], daftariRaw);
71
+ const targetPath = join(vaultRoot, relPath);
72
+ await mkdir(dirname(targetPath), { recursive: true });
73
+ await writeFile(targetPath, fileText, "utf-8");
74
+ writtenPaths.push(relPath);
75
+ }
76
+ if (dryRun) {
77
+ return ok({
78
+ vaultRoot,
79
+ imported: plan.length,
80
+ skipped,
81
+ commit: null,
82
+ reindexed: false,
83
+ dryRun: true,
84
+ warnings,
85
+ plan,
86
+ });
87
+ }
88
+ let commitHash = null;
89
+ if (writtenPaths.length > 0) {
90
+ const committed = await commit(vaultRoot, writtenPaths, `okf import: ${writtenPaths.length} document(s)`, agent);
91
+ if (committed.ok)
92
+ commitHash = committed.value.hash;
93
+ else
94
+ warnings.push(`could not commit import: ${committed.error.message}`);
95
+ }
96
+ let reindexed = false;
97
+ if (writtenPaths.length > 0) {
98
+ const reindex = await reindexVault(vaultRoot);
99
+ if (reindex.ok)
100
+ reindexed = true;
101
+ else
102
+ warnings.push(`could not reindex vault: ${reindex.error.message}`);
103
+ }
104
+ return ok({
105
+ vaultRoot,
106
+ imported: writtenPaths.length,
107
+ skipped,
108
+ commit: commitHash,
109
+ reindexed,
110
+ dryRun: false,
111
+ warnings,
112
+ plan,
113
+ });
114
+ }
115
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/okf/import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runOkf(argv: string[]): Promise<number>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/okf/index.ts"],"names":[],"mappings":"AAkKA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB5D"}