@they-juanreina/compost-cli 0.1.1 → 0.1.3

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 (242) hide show
  1. package/dist/commands/agreement.d.ts +3 -0
  2. package/dist/commands/agreement.d.ts.map +1 -0
  3. package/dist/commands/agreement.js +35 -0
  4. package/dist/commands/agreement.js.map +1 -0
  5. package/dist/commands/create.d.ts +1 -0
  6. package/dist/commands/create.d.ts.map +1 -1
  7. package/dist/commands/create.js +39 -1
  8. package/dist/commands/create.js.map +1 -1
  9. package/dist/commands/export.d.ts.map +1 -1
  10. package/dist/commands/export.js +47 -4
  11. package/dist/commands/export.js.map +1 -1
  12. package/dist/commands/import.d.ts +3 -0
  13. package/dist/commands/import.d.ts.map +1 -0
  14. package/dist/commands/import.js +59 -0
  15. package/dist/commands/import.js.map +1 -0
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +1 -0
  18. package/dist/commands/init.js.map +1 -1
  19. package/dist/commands/jobs.d.ts +3 -0
  20. package/dist/commands/jobs.d.ts.map +1 -0
  21. package/dist/commands/jobs.js +105 -0
  22. package/dist/commands/jobs.js.map +1 -0
  23. package/dist/commands/label.d.ts +3 -0
  24. package/dist/commands/label.d.ts.map +1 -0
  25. package/dist/commands/label.js +67 -0
  26. package/dist/commands/label.js.map +1 -0
  27. package/dist/commands/models.d.ts.map +1 -1
  28. package/dist/commands/models.js +2 -1
  29. package/dist/commands/models.js.map +1 -1
  30. package/dist/commands/recode.d.ts +3 -0
  31. package/dist/commands/recode.d.ts.map +1 -0
  32. package/dist/commands/recode.js +60 -0
  33. package/dist/commands/recode.js.map +1 -0
  34. package/dist/commands/reindex.d.ts.map +1 -1
  35. package/dist/commands/reindex.js +6 -4
  36. package/dist/commands/reindex.js.map +1 -1
  37. package/dist/commands/rerun.d.ts +3 -0
  38. package/dist/commands/rerun.d.ts.map +1 -0
  39. package/dist/commands/rerun.js +91 -0
  40. package/dist/commands/rerun.js.map +1 -0
  41. package/dist/commands/search.d.ts.map +1 -1
  42. package/dist/commands/search.js +2 -1
  43. package/dist/commands/search.js.map +1 -1
  44. package/dist/commands/secrets.d.ts +3 -0
  45. package/dist/commands/secrets.d.ts.map +1 -0
  46. package/dist/commands/secrets.js +143 -0
  47. package/dist/commands/secrets.js.map +1 -0
  48. package/dist/commands/setup.d.ts.map +1 -1
  49. package/dist/commands/setup.js +90 -1
  50. package/dist/commands/setup.js.map +1 -1
  51. package/dist/commands/status.d.ts.map +1 -1
  52. package/dist/commands/status.js +2 -1
  53. package/dist/commands/status.js.map +1 -1
  54. package/dist/commands/transcribe.d.ts.map +1 -1
  55. package/dist/commands/transcribe.js +13 -2
  56. package/dist/commands/transcribe.js.map +1 -1
  57. package/dist/commands/validate.d.ts.map +1 -1
  58. package/dist/commands/validate.js +29 -1
  59. package/dist/commands/validate.js.map +1 -1
  60. package/dist/engine.d.ts +23 -0
  61. package/dist/engine.d.ts.map +1 -0
  62. package/dist/engine.js +32 -0
  63. package/dist/engine.js.map +1 -0
  64. package/dist/exporters/prov.d.ts +11 -0
  65. package/dist/exporters/prov.d.ts.map +1 -0
  66. package/dist/exporters/prov.js +151 -0
  67. package/dist/exporters/prov.js.map +1 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +6 -0
  70. package/dist/index.js.map +1 -1
  71. package/dist/lib/agreement.d.ts +77 -0
  72. package/dist/lib/agreement.d.ts.map +1 -0
  73. package/dist/lib/agreement.js +261 -0
  74. package/dist/lib/agreement.js.map +1 -0
  75. package/dist/lib/artifacts.d.ts +32 -1
  76. package/dist/lib/artifacts.d.ts.map +1 -1
  77. package/dist/lib/artifacts.js +156 -22
  78. package/dist/lib/artifacts.js.map +1 -1
  79. package/dist/lib/blame.d.ts.map +1 -1
  80. package/dist/lib/blame.js +3 -2
  81. package/dist/lib/blame.js.map +1 -1
  82. package/dist/lib/config.d.ts +3 -0
  83. package/dist/lib/config.d.ts.map +1 -1
  84. package/dist/lib/config.js.map +1 -1
  85. package/dist/lib/doctor.d.ts +3 -0
  86. package/dist/lib/doctor.d.ts.map +1 -1
  87. package/dist/lib/doctor.js +24 -1
  88. package/dist/lib/doctor.js.map +1 -1
  89. package/dist/lib/events.d.ts +34 -1
  90. package/dist/lib/events.d.ts.map +1 -1
  91. package/dist/lib/events.js +35 -1
  92. package/dist/lib/events.js.map +1 -1
  93. package/dist/lib/importTranscript.d.ts +16 -0
  94. package/dist/lib/importTranscript.d.ts.map +1 -0
  95. package/dist/lib/importTranscript.js +94 -0
  96. package/dist/lib/importTranscript.js.map +1 -0
  97. package/dist/lib/ingest.d.ts.map +1 -1
  98. package/dist/lib/ingest.js +12 -6
  99. package/dist/lib/ingest.js.map +1 -1
  100. package/dist/lib/journal.d.ts +13 -0
  101. package/dist/lib/journal.d.ts.map +1 -1
  102. package/dist/lib/journal.js +58 -2
  103. package/dist/lib/journal.js.map +1 -1
  104. package/dist/lib/legacyNative.d.ts +24 -0
  105. package/dist/lib/legacyNative.d.ts.map +1 -0
  106. package/dist/lib/legacyNative.js +51 -0
  107. package/dist/lib/legacyNative.js.map +1 -0
  108. package/dist/lib/migrate.d.ts.map +1 -1
  109. package/dist/lib/migrate.js +1 -0
  110. package/dist/lib/migrate.js.map +1 -1
  111. package/dist/lib/nativeRuntime.d.ts +6 -3
  112. package/dist/lib/nativeRuntime.d.ts.map +1 -1
  113. package/dist/lib/nativeRuntime.js +6 -3
  114. package/dist/lib/nativeRuntime.js.map +1 -1
  115. package/dist/lib/provisionNative.js +1 -1
  116. package/dist/lib/provisionNative.js.map +1 -1
  117. package/dist/lib/queue.d.ts +25 -0
  118. package/dist/lib/queue.d.ts.map +1 -1
  119. package/dist/lib/queue.js +70 -3
  120. package/dist/lib/queue.js.map +1 -1
  121. package/dist/lib/reads.d.ts +24 -0
  122. package/dist/lib/reads.d.ts.map +1 -0
  123. package/dist/lib/reads.js +115 -0
  124. package/dist/lib/reads.js.map +1 -0
  125. package/dist/lib/recode.d.ts +19 -0
  126. package/dist/lib/recode.d.ts.map +1 -0
  127. package/dist/lib/recode.js +43 -0
  128. package/dist/lib/recode.js.map +1 -0
  129. package/dist/lib/rerun.d.ts +51 -0
  130. package/dist/lib/rerun.d.ts.map +1 -0
  131. package/dist/lib/rerun.js +166 -0
  132. package/dist/lib/rerun.js.map +1 -0
  133. package/dist/lib/retrieve.d.ts +8 -4
  134. package/dist/lib/retrieve.d.ts.map +1 -1
  135. package/dist/lib/retrieve.js +12 -10
  136. package/dist/lib/retrieve.js.map +1 -1
  137. package/dist/lib/schemas.generated.d.ts.map +1 -1
  138. package/dist/lib/schemas.generated.js +28 -0
  139. package/dist/lib/schemas.generated.js.map +1 -1
  140. package/dist/lib/secrets.d.ts +158 -0
  141. package/dist/lib/secrets.d.ts.map +1 -0
  142. package/dist/lib/secrets.js +507 -0
  143. package/dist/lib/secrets.js.map +1 -0
  144. package/dist/lib/seed.d.ts +5 -0
  145. package/dist/lib/seed.d.ts.map +1 -1
  146. package/dist/lib/seed.js +15 -2
  147. package/dist/lib/seed.js.map +1 -1
  148. package/dist/lib/seedResolve.d.ts.map +1 -1
  149. package/dist/lib/seedResolve.js +1 -0
  150. package/dist/lib/seedResolve.js.map +1 -1
  151. package/dist/lib/session.d.ts +14 -0
  152. package/dist/lib/session.d.ts.map +1 -1
  153. package/dist/lib/session.js +47 -0
  154. package/dist/lib/session.js.map +1 -1
  155. package/dist/lib/setup.d.ts +5 -0
  156. package/dist/lib/setup.d.ts.map +1 -1
  157. package/dist/lib/setup.js +78 -14
  158. package/dist/lib/setup.js.map +1 -1
  159. package/dist/lib/setupWizard.d.ts +51 -0
  160. package/dist/lib/setupWizard.d.ts.map +1 -0
  161. package/dist/lib/setupWizard.js +223 -0
  162. package/dist/lib/setupWizard.js.map +1 -0
  163. package/dist/lib/snap.d.ts.map +1 -1
  164. package/dist/lib/snap.js +2 -5
  165. package/dist/lib/snap.js.map +1 -1
  166. package/dist/lib/speakers.d.ts +41 -0
  167. package/dist/lib/speakers.d.ts.map +1 -0
  168. package/dist/lib/speakers.js +78 -0
  169. package/dist/lib/speakers.js.map +1 -0
  170. package/dist/lib/status.d.ts.map +1 -1
  171. package/dist/lib/status.js +21 -0
  172. package/dist/lib/status.js.map +1 -1
  173. package/dist/lib/userConfig.d.ts +22 -0
  174. package/dist/lib/userConfig.d.ts.map +1 -0
  175. package/dist/lib/userConfig.js +67 -0
  176. package/dist/lib/userConfig.js.map +1 -0
  177. package/dist/lib/validate.d.ts +18 -0
  178. package/dist/lib/validate.d.ts.map +1 -1
  179. package/dist/lib/validate.js +70 -1
  180. package/dist/lib/validate.js.map +1 -1
  181. package/dist/lib/version.d.ts +30 -0
  182. package/dist/lib/version.d.ts.map +1 -0
  183. package/dist/lib/version.js +73 -0
  184. package/dist/lib/version.js.map +1 -0
  185. package/dist/llm/adapter.d.ts.map +1 -1
  186. package/dist/llm/adapter.js +2 -0
  187. package/dist/llm/adapter.js.map +1 -1
  188. package/dist/llm/providers/ollama.d.ts.map +1 -1
  189. package/dist/llm/providers/ollama.js +6 -0
  190. package/dist/llm/providers/ollama.js.map +1 -1
  191. package/dist/loops/ingest_watcher.d.ts.map +1 -1
  192. package/dist/loops/ingest_watcher.js +6 -3
  193. package/dist/loops/ingest_watcher.js.map +1 -1
  194. package/dist/loops/legacy_worker.d.ts +28 -1
  195. package/dist/loops/legacy_worker.d.ts.map +1 -1
  196. package/dist/loops/legacy_worker.js +81 -9
  197. package/dist/loops/legacy_worker.js.map +1 -1
  198. package/dist/loops/supervisor.d.ts +3 -0
  199. package/dist/loops/supervisor.d.ts.map +1 -1
  200. package/dist/loops/supervisor.js +12 -0
  201. package/dist/loops/supervisor.js.map +1 -1
  202. package/dist/loops/synthesis.d.ts.map +1 -1
  203. package/dist/loops/synthesis.js +15 -0
  204. package/dist/loops/synthesis.js.map +1 -1
  205. package/dist/loops/transcribe_worker.d.ts.map +1 -1
  206. package/dist/loops/transcribe_worker.js +2 -4
  207. package/dist/loops/transcribe_worker.js.map +1 -1
  208. package/dist/output.d.ts +13 -1
  209. package/dist/output.d.ts.map +1 -1
  210. package/dist/output.js +22 -2
  211. package/dist/output.js.map +1 -1
  212. package/dist/render/human.d.ts +20 -0
  213. package/dist/render/human.d.ts.map +1 -0
  214. package/dist/render/human.js +54 -0
  215. package/dist/render/human.js.map +1 -0
  216. package/dist/router.d.ts.map +1 -1
  217. package/dist/router.js +17 -2
  218. package/dist/router.js.map +1 -1
  219. package/package.json +18 -5
  220. package/templates/config.toml +6 -1
  221. package/transcriber/app/__init__.py +3 -0
  222. package/transcriber/app/asr.py +198 -0
  223. package/transcriber/app/asr_parakeet.py +174 -0
  224. package/transcriber/app/cue_parser.py +110 -0
  225. package/transcriber/app/diarization.py +330 -0
  226. package/transcriber/app/frame_annotation.py +77 -0
  227. package/transcriber/app/frames.py +130 -0
  228. package/transcriber/app/health.py +70 -0
  229. package/transcriber/app/legacy.py +355 -0
  230. package/transcriber/app/legacy_cli.py +90 -0
  231. package/transcriber/app/main.py +30 -0
  232. package/transcriber/app/pipeline.py +210 -0
  233. package/transcriber/app/pptx_export.py +42 -0
  234. package/transcriber/app/prosody.py +128 -0
  235. package/transcriber/app/routes/__init__.py +1 -0
  236. package/transcriber/app/routes/legacy.py +117 -0
  237. package/transcriber/app/routes/transcribe.py +133 -0
  238. package/transcriber/app/shot_change.py +74 -0
  239. package/transcriber/app/silence_typer.py +144 -0
  240. package/transcriber/app/transcribe_cli.py +82 -0
  241. package/transcriber/app/vad.py +216 -0
  242. package/transcriber/pyproject.toml +56 -0
@@ -0,0 +1,115 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { reduce } from '@they-juanreina/compost-provenance';
4
+ import Database from 'better-sqlite3';
5
+ function rowToEvent(r) {
6
+ return {
7
+ id: r.id,
8
+ ts: r.ts,
9
+ artifact_kind: r.artifact_kind,
10
+ artifact_id: r.artifact_id,
11
+ action: r.action,
12
+ actor_type: r.actor_type,
13
+ actor_id: r.actor_id,
14
+ payload: JSON.parse(r.payload),
15
+ parent_event: r.parent_event,
16
+ batch_id: r.batch_id,
17
+ ...(r.agent_name !== null ? { agent_name: r.agent_name } : {}),
18
+ ...(r.agent_version !== null ? { agent_version: r.agent_version } : {}),
19
+ ...(r.prompt_hash !== null ? { prompt_hash: r.prompt_hash } : {}),
20
+ ...(r.model !== null ? { model: r.model } : {}),
21
+ ...(r.input_id !== null ? { input_id: r.input_id } : {}),
22
+ };
23
+ }
24
+ function openReadonly(seedPath) {
25
+ const dbPath = join(seedPath, '.compost', 'events.sqlite');
26
+ if (!existsSync(dbPath))
27
+ return null;
28
+ return new Database(dbPath, { readonly: true, fileMustExist: true });
29
+ }
30
+ const EVENT_COLUMNS = 'id, ts, artifact_kind, artifact_id, action, actor_type, actor_id, agent_name, agent_version, prompt_hash, model, input_id, payload, parent_event, batch_id';
31
+ /**
32
+ * List the current snapshots of every artifact of `kind`, newest activity first.
33
+ * Reads the append-only event log and folds each artifact's events with the
34
+ * provenance reducer (no snapshot-table writes, so it's safe on a read-only DB).
35
+ * Returns [] when the seed has no event log yet. Archived (rejected) artifacts
36
+ * are excluded unless `includeArchived` is set.
37
+ */
38
+ export function listArtifacts(seedPath, kind, opts = {}) {
39
+ const db = openReadonly(seedPath);
40
+ if (db === null)
41
+ return [];
42
+ try {
43
+ const rows = db
44
+ .prepare(`SELECT ${EVENT_COLUMNS} FROM events WHERE artifact_kind = ? ORDER BY ts, rowid`)
45
+ .all(kind);
46
+ const byArtifact = new Map();
47
+ for (const row of rows) {
48
+ const bucket = byArtifact.get(row.artifact_id);
49
+ if (bucket === undefined) {
50
+ byArtifact.set(row.artifact_id, { events: [rowToEvent(row)], lastTs: row.ts });
51
+ }
52
+ else {
53
+ bucket.events.push(rowToEvent(row));
54
+ bucket.lastTs = row.ts; // rows are ts-ordered, so the last seen is newest
55
+ }
56
+ }
57
+ const views = [];
58
+ for (const { events, lastTs } of byArtifact.values()) {
59
+ const snapshot = reduce(events);
60
+ if (snapshot === null)
61
+ continue;
62
+ if (snapshot.archived && opts.includeArchived !== true)
63
+ continue;
64
+ views.push({ ...snapshot, last_event_ts: lastTs });
65
+ }
66
+ // Newest activity first.
67
+ views.sort((a, b) => a.last_event_ts < b.last_event_ts ? 1 : a.last_event_ts > b.last_event_ts ? -1 : 0);
68
+ return views;
69
+ }
70
+ finally {
71
+ db.close();
72
+ }
73
+ }
74
+ /**
75
+ * Resolve a single artifact's current snapshot by ref — its human id
76
+ * (`H-001`, `C-slug`, `T-slug`, stored in the create payload's `id`) or a
77
+ * SHA256 artifact_id prefix. Returns null when the seed has no event log or no
78
+ * matching artifact.
79
+ */
80
+ export function getArtifact(seedPath, kind, ref) {
81
+ const db = openReadonly(seedPath);
82
+ if (db === null)
83
+ return null;
84
+ try {
85
+ let artifactId;
86
+ // Human id stored in the create event payload.
87
+ const byHuman = db
88
+ .prepare("SELECT artifact_id FROM events WHERE artifact_kind = ? AND action = 'create' AND json_extract(payload, '$.id') = ? ORDER BY ts, rowid LIMIT 1")
89
+ .get(kind, ref);
90
+ if (byHuman !== undefined) {
91
+ artifactId = byHuman.artifact_id;
92
+ }
93
+ else if (/^[a-f0-9]{8,64}$/i.test(ref)) {
94
+ const bySha = db
95
+ .prepare("SELECT artifact_id FROM events WHERE artifact_kind = ? AND action = 'create' AND artifact_id LIKE ? ORDER BY ts, rowid LIMIT 1")
96
+ .get(kind, `${ref.toLowerCase()}%`);
97
+ artifactId = bySha?.artifact_id;
98
+ }
99
+ if (artifactId === undefined)
100
+ return null;
101
+ const rows = db
102
+ .prepare(`SELECT ${EVENT_COLUMNS} FROM events WHERE artifact_id = ? ORDER BY ts, rowid`)
103
+ .all(artifactId);
104
+ if (rows.length === 0)
105
+ return null;
106
+ const snapshot = reduce(rows.map(rowToEvent));
107
+ if (snapshot === null)
108
+ return null;
109
+ return { ...snapshot, last_event_ts: rows[rows.length - 1]?.ts ?? '' };
110
+ }
111
+ finally {
112
+ db.close();
113
+ }
114
+ }
115
+ //# sourceMappingURL=reads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reads.js","sourceRoot":"","sources":["../../src/lib/reads.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface BlindRecodeResult {
2
+ codings: number;
3
+ highlights: number;
4
+ batch_id: string;
5
+ }
6
+ /**
7
+ * Record a researcher's INDEPENDENT (blind) codings for intercoder agreement.
8
+ *
9
+ * Each (highlight, code) becomes a researcher `link` event on a `coding` artifact,
10
+ * flagged `blind: true`, so `compost agreement` can tell genuine double-coding from
11
+ * reactive endorsement. The "blind" guarantee is procedural — the researcher codes
12
+ * without seeing the machine's codes; this just records the result. Idempotent at
13
+ * the metric level (duplicate (highlight, code) pairs collapse).
14
+ */
15
+ export declare function blindRecode(seedPath: string, input: {
16
+ assignments: Record<string, string[]>;
17
+ researcherId: string;
18
+ }): BlindRecodeResult;
19
+ //# sourceMappingURL=recode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recode.d.ts","sourceRoot":"","sources":["../../src/lib/recode.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACrE,iBAAiB,CA6BnB"}
@@ -0,0 +1,43 @@
1
+ import { CompostError } from '../errors.js';
2
+ import { artifactId, openSeedEvents } from './events.js';
3
+ /**
4
+ * Record a researcher's INDEPENDENT (blind) codings for intercoder agreement.
5
+ *
6
+ * Each (highlight, code) becomes a researcher `link` event on a `coding` artifact,
7
+ * flagged `blind: true`, so `compost agreement` can tell genuine double-coding from
8
+ * reactive endorsement. The "blind" guarantee is procedural — the researcher codes
9
+ * without seeing the machine's codes; this just records the result. Idempotent at
10
+ * the metric level (duplicate (highlight, code) pairs collapse).
11
+ */
12
+ export function blindRecode(seedPath, input) {
13
+ const events = openSeedEvents(seedPath);
14
+ const batchId = `blind-recode:${new Date().toISOString()}`;
15
+ try {
16
+ const rows = [];
17
+ for (const [highlight, codes] of Object.entries(input.assignments)) {
18
+ for (const code of new Set(codes)) {
19
+ rows.push({
20
+ artifact_kind: 'coding',
21
+ artifact_id: artifactId({ coder: 'researcher-blind', highlight, code }),
22
+ action: 'link',
23
+ actor_type: 'researcher',
24
+ actor_id: input.researcherId,
25
+ payload: { code, highlight, blind: true },
26
+ });
27
+ }
28
+ }
29
+ if (rows.length === 0) {
30
+ throw new CompostError('INVALID_INPUT', 'No codings to record (assignments were empty).');
31
+ }
32
+ events.appendBatch(rows, batchId);
33
+ return {
34
+ codings: rows.length,
35
+ highlights: Object.keys(input.assignments).length,
36
+ batch_id: batchId,
37
+ };
38
+ }
39
+ finally {
40
+ events.close();
41
+ }
42
+ }
43
+ //# sourceMappingURL=recode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recode.js","sourceRoot":"","sources":["../../src/lib/recode.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAQxD;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CACzB,QAAgB,EAChB,KAAsE;IAEtE,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,gBAAgB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAA;IAC1D,IAAI,CAAC;QACH,MAAM,IAAI,GAAiB,EAAE,CAAA;QAC7B,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YACnE,KAAK,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC;oBACR,aAAa,EAAE,QAAQ;oBACvB,WAAW,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;oBACvE,MAAM,EAAE,MAAM;oBACd,UAAU,EAAE,YAAY;oBACxB,QAAQ,EAAE,KAAK,CAAC,YAAY;oBAC5B,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;iBAC1C,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,YAAY,CAAC,eAAe,EAAE,gDAAgD,CAAC,CAAA;QAC3F,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACjC,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM;YACpB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM;YACjD,QAAQ,EAAE,OAAO;SAClB,CAAA;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAA;IAChB,CAAC;AACH,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { type AiInputRow } from '@they-juanreina/compost-provenance';
2
+ export interface RerunReport {
3
+ status: 'verified' | 'regenerated';
4
+ artifact_id: string;
5
+ artifact_kind: string;
6
+ create_event_id: string;
7
+ actor_type: string;
8
+ model: string | null;
9
+ /** Did the stored bundle hash back to the event's input_id? */
10
+ integrity_ok: boolean;
11
+ /** Regeneration (only with apply). */
12
+ regenerated_event_id?: string;
13
+ applied_model?: string;
14
+ diff?: PayloadDiff;
15
+ note?: string;
16
+ }
17
+ export interface PayloadDiff {
18
+ changed: boolean;
19
+ fields: Array<{
20
+ field: string;
21
+ before: unknown;
22
+ after: unknown;
23
+ }>;
24
+ }
25
+ /** Shallow field-level diff between two payload objects. */
26
+ export declare function diffPayload(before: unknown, after: unknown): PayloadDiff;
27
+ /** Regenerate an output from its captured inputs (model may be overridden).
28
+ * Returns the new artifact payload. Injected so the LLM/provider dependency is
29
+ * mockable; the CLI wires a default that calls the LLM adapter for `ai` bundles. */
30
+ export type Regenerator = (inputs: AiInputRow, ctx: {
31
+ actorType: string;
32
+ modelOverride?: string;
33
+ }) => Promise<Record<string, unknown>>;
34
+ export interface RerunOptions {
35
+ ref: string;
36
+ apply?: boolean;
37
+ modelOverride?: string;
38
+ regenerate?: Regenerator;
39
+ researcherId?: string;
40
+ }
41
+ /**
42
+ * Rerun an AI/agent generation from its captured inputs.
43
+ *
44
+ * Default (no apply): VERIFY — confirm the stored bundle hashes back to the
45
+ * event's input_id (the inputs are intact and reconstructable). With `apply`:
46
+ * REGENERATE via the injected generator, emit a new event chained to the original
47
+ * (parent_event), and diff the payloads. LLM regeneration is non-deterministic, so
48
+ * an `ai` diff is fuzzy; a deterministic `agent` reproduces exactly.
49
+ */
50
+ export declare function rerunEvent(seedPath: string, opts: RerunOptions): Promise<RerunReport>;
51
+ //# sourceMappingURL=rerun.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rerun.d.ts","sourceRoot":"","sources":["../../src/lib/rerun.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,oCAAoC,CAAA;AA8D1F,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,GAAG,aAAa,CAAA;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,+DAA+D;IAC/D,YAAY,EAAE,OAAO,CAAA;IACrB,sCAAsC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAClE;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,CAWxE;AAED;;oFAEoF;AACpF,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,KAC/C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAErC,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,WAAW,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA0G3F"}
@@ -0,0 +1,166 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { EventWriter, inputId } from '@they-juanreina/compost-provenance';
4
+ import Database from 'better-sqlite3';
5
+ import { CompostError } from '../errors.js';
6
+ import { HUMAN_REF_RE } from './artifacts.js';
7
+ /** Resolve an artifact ref (event ULID, human id, SHA prefix, or latest:<kind>) to
8
+ * its `create` event row. For a non-create event id, falls back to the artifact's
9
+ * create. Mirrors blame/endorse ref handling. */
10
+ function resolveCreateEvent(db, ref) {
11
+ const cols = 'id, artifact_kind, artifact_id, actor_type, model, input_id, payload';
12
+ // Direct event ULID.
13
+ if (/^[0-9A-HJKMNP-TV-Z]{26}$/.test(ref)) {
14
+ const row = db.prepare(`SELECT ${cols}, action FROM events WHERE id = ?`).get(ref);
15
+ if (row === undefined)
16
+ return undefined;
17
+ if (row.action === 'create')
18
+ return row;
19
+ return db
20
+ .prepare(`SELECT ${cols} FROM events WHERE artifact_id = ? AND action='create' ORDER BY ts, rowid LIMIT 1`)
21
+ .get(row.artifact_id);
22
+ }
23
+ // Human id (C-slug / H-NNN / T-slug) stored in create payload.id.
24
+ if (HUMAN_REF_RE.test(ref)) {
25
+ return db
26
+ .prepare(`SELECT ${cols} FROM events WHERE action='create' AND json_extract(payload, '$.id') = ? ORDER BY ts, rowid LIMIT 1`)
27
+ .get(ref);
28
+ }
29
+ // latest:<kind>=<seed>
30
+ const latest = /^latest:(\w+)=/.exec(ref);
31
+ if (latest) {
32
+ return db
33
+ .prepare(`SELECT ${cols} FROM events WHERE artifact_kind = ? AND action='create' ORDER BY ts DESC, rowid DESC LIMIT 1`)
34
+ .get(latest[1]);
35
+ }
36
+ // SHA256 prefix.
37
+ if (/^[a-f0-9]{8,64}$/i.test(ref)) {
38
+ return db
39
+ .prepare(`SELECT ${cols} FROM events WHERE artifact_id LIKE ? AND action='create' ORDER BY ts, rowid LIMIT 1`)
40
+ .get(`${ref.toLowerCase()}%`);
41
+ }
42
+ return undefined;
43
+ }
44
+ /** Shallow field-level diff between two payload objects. */
45
+ export function diffPayload(before, after) {
46
+ const a = (before ?? {});
47
+ const b = (after ?? {});
48
+ const keys = [...new Set([...Object.keys(a), ...Object.keys(b)])].sort();
49
+ const fields = [];
50
+ for (const field of keys) {
51
+ if (JSON.stringify(a[field]) !== JSON.stringify(b[field])) {
52
+ fields.push({ field, before: a[field], after: b[field] });
53
+ }
54
+ }
55
+ return { changed: fields.length > 0, fields };
56
+ }
57
+ /**
58
+ * Rerun an AI/agent generation from its captured inputs.
59
+ *
60
+ * Default (no apply): VERIFY — confirm the stored bundle hashes back to the
61
+ * event's input_id (the inputs are intact and reconstructable). With `apply`:
62
+ * REGENERATE via the injected generator, emit a new event chained to the original
63
+ * (parent_event), and diff the payloads. LLM regeneration is non-deterministic, so
64
+ * an `ai` diff is fuzzy; a deterministic `agent` reproduces exactly.
65
+ */
66
+ export async function rerunEvent(seedPath, opts) {
67
+ const eventsDb = join(seedPath, '.compost', 'events.sqlite');
68
+ if (!existsSync(eventsDb)) {
69
+ throw new CompostError('FILE_NOT_FOUND', 'No events.sqlite in seed; nothing to rerun.');
70
+ }
71
+ // Resolve target (read-only connection).
72
+ const rdb = new Database(eventsDb, { readonly: true, fileMustExist: true });
73
+ let target;
74
+ try {
75
+ target = resolveCreateEvent(rdb, opts.ref);
76
+ }
77
+ finally {
78
+ rdb.close();
79
+ }
80
+ if (target === undefined) {
81
+ throw new CompostError('FILE_NOT_FOUND', `No create event found for ref "${opts.ref}".`);
82
+ }
83
+ if (target.input_id === null) {
84
+ throw new CompostError('INVALID_INPUT', `Event ${target.id} has no captured inputs (input_id is NULL — pre-migration, or a hash-only host create). It cannot be rerun; only events whose inputs were captured are reconstructable.`);
85
+ }
86
+ // Load inputs + integrity-check via a writer connection (also used to append).
87
+ const writer = new EventWriter({ dbPath: eventsDb });
88
+ try {
89
+ const inputs = writer.readInputs(target.input_id);
90
+ if (inputs === undefined) {
91
+ throw new CompostError('INTERNAL', `input_id ${target.input_id} referenced by event ${target.id} is missing from ai_inputs.`);
92
+ }
93
+ const integrity_ok = inputId({
94
+ model: inputs.model,
95
+ params: inputs.params,
96
+ system_prompt: inputs.system_prompt,
97
+ prompt: inputs.prompt,
98
+ context: inputs.context,
99
+ }) === target.input_id;
100
+ const base = {
101
+ status: 'verified',
102
+ artifact_id: target.artifact_id,
103
+ artifact_kind: target.artifact_kind,
104
+ create_event_id: target.id,
105
+ actor_type: target.actor_type,
106
+ model: target.model,
107
+ integrity_ok,
108
+ };
109
+ if (opts.apply !== true) {
110
+ return {
111
+ ...base,
112
+ note: 'Verify-only. Pass --apply to regenerate the output under the (optionally overridden) model and diff it.',
113
+ };
114
+ }
115
+ if (opts.regenerate === undefined) {
116
+ throw new CompostError('CONFIG_ERROR', 'Regeneration is not wired for this actor type yet. Inputs are intact and reconstructable; --apply regeneration currently requires an injected generator (LLM path needs a configured provider).');
117
+ }
118
+ const newPayload = await opts.regenerate(inputs, {
119
+ actorType: target.actor_type,
120
+ ...(opts.modelOverride !== undefined ? { modelOverride: opts.modelOverride } : {}),
121
+ });
122
+ const appliedModel = opts.modelOverride ?? inputs.model;
123
+ // Emit the regenerated output, chained to the original create.
124
+ const rerunInputId = writer.recordInputs({
125
+ model: appliedModel,
126
+ params: inputs.params,
127
+ system_prompt: inputs.system_prompt,
128
+ prompt: inputs.prompt,
129
+ context: inputs.context,
130
+ });
131
+ const isAi = target.actor_type === 'ai';
132
+ const rerun = writer.appendEvent({
133
+ artifact_kind: target.artifact_kind,
134
+ artifact_id: target.artifact_id,
135
+ action: 'update',
136
+ actor_type: isAi ? 'ai' : 'agent',
137
+ actor_id: isAi ? appliedModel : `${target.model ?? 'agent'}`,
138
+ ...(isAi ? { model: appliedModel, prompt_hash: rerunInputId } : {}),
139
+ ...(!isAi ? { agent_name: 'rerun', agent_version: '0.1.0' } : {}),
140
+ input_id: rerunInputId,
141
+ parent_event: target.id,
142
+ batch_id: `rerun:${target.id}`,
143
+ payload: { rerun_of: target.id, ...newPayload },
144
+ });
145
+ return {
146
+ ...base,
147
+ status: 'regenerated',
148
+ regenerated_event_id: rerun.id,
149
+ applied_model: appliedModel,
150
+ diff: diffPayload(safeParse(target.payload), newPayload),
151
+ };
152
+ }
153
+ finally {
154
+ writer.close();
155
+ }
156
+ }
157
+ function safeParse(s) {
158
+ try {
159
+ const v = JSON.parse(s);
160
+ return v !== null && typeof v === 'object' ? v : {};
161
+ }
162
+ catch {
163
+ return {};
164
+ }
165
+ }
166
+ //# sourceMappingURL=rerun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rerun.js","sourceRoot":"","sources":["../../src/lib/rerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAmB,WAAW,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA;AAC1F,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAY7C;;iDAEiD;AACjD,SAAS,kBAAkB,CAAC,EAAqB,EAAE,GAAW;IAC5D,MAAM,IAAI,GAAG,sEAAsE,CAAA;IACnF,qBAAqB;IACrB,IAAI,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,IAAI,mCAAmC,CAAC,CAAC,GAAG,CAAC,GAAG,CAEpE,CAAA;QACb,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QACvC,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAA;QACvC,OAAO,EAAE;aACN,OAAO,CACN,UAAU,IAAI,mFAAmF,CAClG;aACA,GAAG,CAAC,GAAG,CAAC,WAAW,CAA0B,CAAA;IAClD,CAAC;IACD,kEAAkE;IAClE,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE;aACN,OAAO,CACN,UAAU,IAAI,qGAAqG,CACpH;aACA,GAAG,CAAC,GAAG,CAA0B,CAAA;IACtC,CAAC;IACD,uBAAuB;IACvB,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE;aACN,OAAO,CACN,UAAU,IAAI,+FAA+F,CAC9G;aACA,GAAG,CAAC,MAAM,CAAC,CAAC,CAAW,CAA0B,CAAA;IACtD,CAAC;IACD,iBAAiB;IACjB,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE;aACN,OAAO,CACN,UAAU,IAAI,sFAAsF,CACrG;aACA,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,GAAG,CAA0B,CAAA;IAC1D,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAuBD,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,MAAe,EAAE,KAAc;IACzD,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAA4B,CAAA;IACnD,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAA;IAClD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACxE,MAAM,MAAM,GAA0B,EAAE,CAAA;IACxC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;AAC/C,CAAC;AAkBD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,IAAkB;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;IAC5D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,6CAA6C,CAAC,CAAA;IACzF,CAAC;IAED,yCAAyC;IACzC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3E,IAAI,MAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5C,CAAC;YAAS,CAAC;QACT,GAAG,CAAC,KAAK,EAAE,CAAA;IACb,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,kCAAkC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,YAAY,CACpB,eAAe,EACf,SAAS,MAAM,CAAC,EAAE,yKAAyK,CAC5L,CAAA;IACH,CAAC;IAED,+EAA+E;IAC/E,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACjD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,YAAY,MAAM,CAAC,QAAQ,wBAAwB,MAAM,CAAC,EAAE,6BAA6B,CAC1F,CAAA;QACH,CAAC;QACD,MAAM,YAAY,GAChB,OAAO,CAAC;YACN,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,KAAK,MAAM,CAAC,QAAQ,CAAA;QAExB,MAAM,IAAI,GAAgB;YACxB,MAAM,EAAE,UAAU;YAClB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,eAAe,EAAE,MAAM,CAAC,EAAE;YAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,YAAY;SACb,CAAA;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO;gBACL,GAAG,IAAI;gBACP,IAAI,EAAE,yGAAyG;aAChH,CAAA;QACH,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,YAAY,CACpB,cAAc,EACd,iMAAiM,CAClM,CAAA;QACH,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAC/C,SAAS,EAAE,MAAM,CAAC,UAAU;YAC5B,GAAG,CAAC,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnF,CAAC,CAAA;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,KAAK,CAAA;QAEvD,+DAA+D;QAC/D,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;YACvC,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,KAAK,IAAI,CAAA;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;YAC/B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;YACjC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,EAAE;YAC5D,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,QAAQ,EAAE,YAAY;YACtB,YAAY,EAAE,MAAM,CAAC,EAAE;YACvB,QAAQ,EAAE,SAAS,MAAM,CAAC,EAAE,EAAE;YAC9B,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE;SAChD,CAAC,CAAA;QAEF,OAAO;YACL,GAAG,IAAI;YACP,MAAM,EAAE,aAAa;YACrB,oBAAoB,EAAE,KAAK,CAAC,EAAE;YAC9B,aAAa,EAAE,YAAY;YAC3B,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;SACzD,CAAA;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAA;IAChB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACvB,OAAO,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,CAA6B,CAAC,CAAC,CAAC,EAAE,CAAA;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC"}
@@ -5,10 +5,11 @@ import { type CompostConfig } from './config.js';
5
5
  * `compost chat` (retrieval + LLM synthesis). Extracted so the two commands
6
6
  * never diverge on how the corpus is loaded, chunked, and ranked.
7
7
  *
8
- * Retrieval is BM25-only today: HybridRetriever's dense slot is null because
9
- * nothing reads the LanceDB index the embed-worker writes (#137). Wiring
10
- * LanceDBRetriever into this shared path is a follow-up that upgrades both
11
- * `search` and `chat` ranking at once see the tracking issue.
8
+ * Retrieval is hybrid: when a LanceDB index and an embeddings provider are
9
+ * both present, BM25 dense results are fused via RRF (HybridRetriever's dense
10
+ * slot is filled by buildDenseRetriever, which reads the index the embed-worker
11
+ * writes). When either is missing it falls back to BM25-only. `search` and
12
+ * `chat` share this path, so both rank the same way.
12
13
  */
13
14
  export interface LoadedCorpus {
14
15
  chunks: Chunk[];
@@ -27,6 +28,9 @@ export interface RetrieveOptions {
27
28
  /** Dense retriever (LanceDB). When provided, retrieval is BM25 ∪ dense fused
28
29
  * via RRF. When null/omitted, BM25-only. Inject via buildDenseRetriever. */
29
30
  dense?: DenseRetriever | null;
31
+ /** Collapse near-duplicate chunks covering the same region before the topK cut
32
+ * (#170). Default true; set false for the raw fused ranking. */
33
+ dedupe?: boolean;
30
34
  }
31
35
  export interface RetrieveResult {
32
36
  retrieved: ScoredChunk[];
@@ -1 +1 @@
1
- {"version":3,"file":"retrieve.d.ts","sourceRoot":"","sources":["../../src/lib/retrieve.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,KAAK,EAGV,KAAK,cAAc,EACnB,KAAK,WAAW,EAGhB,KAAK,WAAW,EACjB,MAAM,mCAAmC,CAAA;AAG1C,OAAO,EAAE,KAAK,aAAa,EAAc,MAAM,aAAa,CAAA;AAE5D;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,QAAQ,EAAE,WAAW,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAoB7D;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;gFAC4E;IAC5E,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,aAAa,CAAA;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,cAAc,CAAC,CAWzB;AAWD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAyBhC"}
1
+ {"version":3,"file":"retrieve.d.ts","sourceRoot":"","sources":["../../src/lib/retrieve.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,KAAK,EAGV,KAAK,cAAc,EAEnB,KAAK,WAAW,EAGhB,KAAK,WAAW,EACjB,MAAM,mCAAmC,CAAA;AAG1C,OAAO,EAAE,KAAK,aAAa,EAAc,MAAM,aAAa,CAAA;AAE5D;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,QAAQ,EAAE,WAAW,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAoB7D;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;gFAC4E;IAC5E,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC7B;oEACgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,aAAa,CAAA;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,cAAc,CAAC,CAsBzB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAyBhC"}
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import { BM25Index, chunkTranscript, HybridRetriever, openLanceDBForRead, } from '@they-juanreina/compost-retrieval';
3
+ import { BM25Index, chunkTranscript, dedupeByRegion, HybridRetriever, openLanceDBForRead, } from '@they-juanreina/compost-retrieval';
4
4
  import { LLMAdapter } from '../llm/adapter.js';
5
5
  import { loadConfig } from './config.js';
6
6
  /**
@@ -42,20 +42,22 @@ export async function retrieveChunks(seedPath, query, opts = {}) {
42
42
  const mode = dense ? 'hybrid' : 'bm25';
43
43
  if (corpus.chunks.length === 0)
44
44
  return { retrieved: [], corpus, mode };
45
+ const topK = opts.topK ?? 8;
45
46
  const bm25 = new BM25Index();
46
47
  bm25.addAll(corpus.chunks);
47
48
  const retriever = new HybridRetriever(bm25, dense);
48
- const retrieved = await retriever.retrieve(query, { topK: opts.topK ?? 8 });
49
+ if (opts.dedupe === false) {
50
+ const retrieved = await retriever.retrieve(query, { topK });
51
+ return { retrieved, corpus, mode };
52
+ }
53
+ // Over-fetch a pool, collapse same-region near-duplicates (#170), then cut to
54
+ // topK — so top-k holds topK *distinct* regions, not the same phrase repeated
55
+ // as a solo utterance + several overlapping windows.
56
+ const pool = Math.max(topK * 5, 50);
57
+ const fused = await retriever.retrieve(query, { topK: pool });
58
+ const retrieved = dedupeByRegion(fused).slice(0, topK);
49
59
  return { retrieved, corpus, mode };
50
60
  }
51
- /** Embedding-vector dimension by model tag (mirrors the embed-worker's table). */
52
- const DIM_BY_MODEL = {
53
- 'bge-m3': 1024,
54
- 'bge-m3:q4_k_m': 1024,
55
- 'mxbai-embed-large': 1024,
56
- 'nomic-embed-text': 768,
57
- 'all-minilm': 384,
58
- };
59
61
  /**
60
62
  * Build a dense retriever for a seed, or return null when dense isn't available
61
63
  * — no LanceDB index yet, the native binary absent, or the embeddings provider
@@ -1 +1 @@
1
- {"version":3,"file":"retrieve.js","sourceRoot":"","sources":["../../src/lib/retrieve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EACL,SAAS,EAGT,eAAe,EAGf,eAAe,EACf,kBAAkB,GAEnB,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAsB,UAAU,EAAE,MAAM,aAAa,CAAA;AAmB5D;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAA;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAgB,IAAI,GAAG,EAAE,CAAA;IACvC,MAAM,SAAS,GAAY,EAAE,CAAA;IAC7B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;IAEvE,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,QAAQ;YAAE,SAAQ;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAA;QACzD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;YAAE,SAAQ;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAExD,CAAA;QACD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YACtC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QACzE,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;IACpE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;AAClD,CAAC;AAiBD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,KAAa,EACb,OAAwB,EAAE;IAE1B,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAA;IAChC,MAAM,IAAI,GAAkB,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAA;IACrD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IAEtE,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAA;IAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;IAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AACpC,CAAC;AAED,kFAAkF;AAClF,MAAM,YAAY,GAA2B;IAC3C,QAAQ,EAAE,IAAI;IACd,eAAe,EAAE,IAAI;IACrB,mBAAmB,EAAE,IAAI;IACzB,kBAAkB,EAAE,GAAG;IACvB,YAAY,EAAE,GAAG;CAClB,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,MAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAA;IACzD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEjC,IAAI,OAAmB,CAAA;IACvB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,EAAE,CAAS,EAAqB,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAC3B,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAChF,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;IAED,4EAA4E;IAC5E,8EAA8E;IAC9E,IAAI,CAAC;QACH,OAAO,MAAM,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"retrieve.js","sourceRoot":"","sources":["../../src/lib/retrieve.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.generated.d.ts","sourceRoot":"","sources":["../../src/lib/schemas.generated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAyDjD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAsDjD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA0KjD,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAmDnD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA+IjD,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA6drD,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO/D,CAAA"}
1
+ {"version":3,"file":"schemas.generated.d.ts","sourceRoot":"","sources":["../../src/lib/schemas.generated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAyDjD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAsDjD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA+KjD,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAmDnD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA+IjD,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAofrD,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO/D,CAAA"}
@@ -198,6 +198,11 @@ export const EVENTS_SCHEMA = {
198
198
  "type": "string",
199
199
  "description": "Required when actor_type=ai. The model that produced the suggestion (e.g. anthropic:claude-opus-4-7, ollama:llama3.1:8b)."
200
200
  },
201
+ "input_id": {
202
+ "type": "string",
203
+ "pattern": "^[a-f0-9]{64}$",
204
+ "description": "Content-address (sha256) of the persisted input bundle in the ai_inputs table that produced this event's output. Set on AI/agent generations whose inputs were captured; absent for researcher events and hash-only host-agent creates. Unlike prompt_hash (a one-way digest), the referenced bundle is reconstructable — it backs `compost rerun` and a PROV-O export's prov:used relations."
205
+ },
201
206
  "payload": {
202
207
  "description": "Action-specific JSON payload. The structure varies by (artifact_kind, action) pair and is validated separately by the CLI when serializing/deserializing.",
203
208
  "oneOf": [
@@ -517,6 +522,13 @@ export const TRANSCRIPT_SCHEMA = {
517
522
  "default": "session",
518
523
  "description": "session = recorded interview; document = legacy PDF/DOCX/PPTX/CSV normalized into a transcript-shaped doc."
519
524
  },
525
+ "status": {
526
+ "enum": [
527
+ "ok",
528
+ "needs_speaker_labels"
529
+ ],
530
+ "description": "Optional pipeline status. Absent ⇒ ok. The diarizer sets \"needs_speaker_labels\" when mean speaker-assignment confidence falls below its floor, queueing the session for human speaker labelling. Job-level failure (failed_transcription) is never written here — a failed run produces no transcript."
531
+ },
520
532
  "session_id": {
521
533
  "type": "string",
522
534
  "pattern": "^[A-Za-z0-9_-]+$",
@@ -667,6 +679,9 @@ export const TRANSCRIPT_SCHEMA = {
667
679
  "prosody": {
668
680
  "$ref": "#/$defs/prosody"
669
681
  },
682
+ "diarization": {
683
+ "$ref": "#/$defs/utteranceDiarization"
684
+ },
670
685
  "annotation": {
671
686
  "type": "string",
672
687
  "description": "Free-text editorial layer. May be human-authored, agent-authored, or AI-suggested. Provenance lives in .compost/events.sqlite — this field is a snapshot of current text only."
@@ -731,6 +746,19 @@ export const TRANSCRIPT_SCHEMA = {
731
746
  }
732
747
  }
733
748
  },
749
+ "utteranceDiarization": {
750
+ "type": "object",
751
+ "additionalProperties": false,
752
+ "description": "Per-utterance diarization metadata from the pyannote alignment. Distinct from prosody (acoustic hints); this records how the speaker_id was assigned.",
753
+ "properties": {
754
+ "confidence": {
755
+ "type": "number",
756
+ "minimum": 0,
757
+ "maximum": 1,
758
+ "description": "Fraction of this utterance's span overlapped by the winning speaker turn (0..1). 0.0 marks a nearest-turn fallback assignment (no verified overlap), which counts against the session's mean-confidence gate."
759
+ }
760
+ }
761
+ },
734
762
  "silence": {
735
763
  "type": "object",
736
764
  "required": [