@mcptoolshop/research-os 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -92,6 +92,23 @@ var init_errors = __esm({
92
92
  }
93
93
  });
94
94
 
95
+ // src/review/reviewer-options-schema.ts
96
+ import { z } from "zod";
97
+ var ReviewerOptionsSchema;
98
+ var init_reviewer_options_schema = __esm({
99
+ "src/review/reviewer-options-schema.ts"() {
100
+ "use strict";
101
+ ReviewerOptionsSchema = z.object({
102
+ num_ctx: z.number().int().positive().optional(),
103
+ temperature: z.number().min(0).max(2).optional(),
104
+ seed: z.number().int().optional(),
105
+ top_p: z.number().min(0).max(1).optional(),
106
+ top_k: z.number().int().nonnegative().optional(),
107
+ repeat_penalty: z.number().min(0).optional()
108
+ });
109
+ }
110
+ });
111
+
95
112
  // src/intake/schema.ts
96
113
  var schema_exports = {};
97
114
  __export(schema_exports, {
@@ -110,83 +127,85 @@ __export(schema_exports, {
110
127
  SectionStatusSchema: () => SectionStatusSchema,
111
128
  SourceFloorGateSchema: () => SourceFloorGateSchema
112
129
  });
113
- import { z } from "zod";
130
+ import { z as z2 } from "zod";
114
131
  var SectionStatusSchema, SectionSchema, SourceFloorGateSchema, ClaimIntegrityGateSchema, FreshnessGateSchema, ContradictionGateSchema, SectionBudgetGateSchema, GateConfigSchema, SectionScopedWaiverSchema, PrimarySourceWaiverSchema, FreshnessRequirementsSchema, ReviewProfilePresetSchema, DEFAULT_REVIEW_PROFILES, ResearchYamlSchema;
115
132
  var init_schema = __esm({
116
133
  "src/intake/schema.ts"() {
117
134
  "use strict";
118
- SectionStatusSchema = z.enum([
135
+ init_reviewer_options_schema();
136
+ SectionStatusSchema = z2.enum([
119
137
  "draft",
120
138
  "gathering",
121
139
  "gated",
122
140
  "reviewed",
123
141
  "frozen"
124
142
  ]);
125
- SectionSchema = z.object({
126
- id: z.string().regex(/^[0-9]{2}-[a-z0-9-]+$/, 'Section id must look like "01-landscape"'),
127
- purpose: z.string().min(1),
128
- max_time_minutes: z.number().int().positive().default(45),
129
- min_sources: z.number().int().nonnegative().default(8),
130
- primary_sources_required: z.number().int().nonnegative().default(2),
131
- contradictions_required: z.boolean().default(true),
143
+ SectionSchema = z2.object({
144
+ id: z2.string().regex(/^[0-9]{2}-[a-z0-9-]+$/, 'Section id must look like "01-landscape"'),
145
+ purpose: z2.string().min(1),
146
+ max_time_minutes: z2.number().int().positive().default(45),
147
+ min_sources: z2.number().int().nonnegative().default(8),
148
+ primary_sources_required: z2.number().int().nonnegative().default(2),
149
+ contradictions_required: z2.boolean().default(true),
132
150
  status: SectionStatusSchema.default("draft")
133
151
  });
134
- SourceFloorGateSchema = z.object({
135
- min_sources: z.number().int().nonnegative().default(8),
136
- min_independent_publishers: z.number().int().nonnegative().default(4),
137
- primary_sources_required: z.number().int().nonnegative().default(2),
138
- primary_source_waiver_allowed: z.boolean().default(true)
152
+ SourceFloorGateSchema = z2.object({
153
+ min_sources: z2.number().int().nonnegative().default(8),
154
+ min_independent_publishers: z2.number().int().nonnegative().default(4),
155
+ primary_sources_required: z2.number().int().nonnegative().default(2),
156
+ primary_source_waiver_allowed: z2.boolean().default(true)
139
157
  });
140
- ClaimIntegrityGateSchema = z.object({
141
- every_claim_needs_source: z.boolean().default(true),
142
- no_orphan_claims: z.boolean().default(true),
143
- no_source_cluster_monopoly: z.boolean().default(true)
158
+ ClaimIntegrityGateSchema = z2.object({
159
+ every_claim_needs_source: z2.boolean().default(true),
160
+ no_orphan_claims: z2.boolean().default(true),
161
+ no_source_cluster_monopoly: z2.boolean().default(true)
144
162
  });
145
- FreshnessGateSchema = z.object({
146
- required_for_current_topics: z.boolean().default(true),
147
- stale_source_policy: z.enum(["warn", "fail"]).default("warn")
163
+ FreshnessGateSchema = z2.object({
164
+ required_for_current_topics: z2.boolean().default(true),
165
+ stale_source_policy: z2.enum(["warn", "fail"]).default("warn")
148
166
  });
149
- ContradictionGateSchema = z.object({
150
- required: z.boolean().default(true),
151
- unresolved_contradictions_block_synthesis: z.boolean().default(true)
167
+ ContradictionGateSchema = z2.object({
168
+ required: z2.boolean().default(true),
169
+ unresolved_contradictions_block_synthesis: z2.boolean().default(true)
152
170
  });
153
- SectionBudgetGateSchema = z.object({
154
- max_time_minutes: z.number().int().positive().default(45),
155
- extension_requires_evidence: z.boolean().default(true)
171
+ SectionBudgetGateSchema = z2.object({
172
+ max_time_minutes: z2.number().int().positive().default(45),
173
+ extension_requires_evidence: z2.boolean().default(true)
156
174
  });
157
- GateConfigSchema = z.object({
175
+ GateConfigSchema = z2.object({
158
176
  source_floor: SourceFloorGateSchema.default({}),
159
177
  claim_integrity: ClaimIntegrityGateSchema.default({}),
160
178
  freshness: FreshnessGateSchema.default({}),
161
179
  contradiction: ContradictionGateSchema.default({}),
162
180
  section_budget: SectionBudgetGateSchema.default({})
163
181
  });
164
- SectionScopedWaiverSchema = z.object({
165
- section_id: z.string().regex(/^[0-9]{2}-[a-z0-9-]+$/, 'Section id must look like "01-landscape"'),
166
- scope: z.enum(["min_independent_publishers", "primary_sources_required"]),
167
- reason: z.string().min(1),
168
- compensating_controls: z.array(z.string()).min(1)
169
- });
170
- PrimarySourceWaiverSchema = z.object({
171
- status: z.enum(["none", "requested", "granted"]).default("none"),
172
- reason: z.string().optional(),
173
- compensating_controls: z.array(z.string()).default([]),
182
+ SectionScopedWaiverSchema = z2.object({
183
+ section_id: z2.string().regex(/^[0-9]{2}-[a-z0-9-]+$/, 'Section id must look like "01-landscape"'),
184
+ scope: z2.enum(["min_independent_publishers", "primary_sources_required"]),
185
+ reason: z2.string().min(1),
186
+ compensating_controls: z2.array(z2.string()).min(1)
187
+ });
188
+ PrimarySourceWaiverSchema = z2.object({
189
+ status: z2.enum(["none", "requested", "granted"]).default("none"),
190
+ reason: z2.string().optional(),
191
+ compensating_controls: z2.array(z2.string()).default([]),
174
192
  // Section-scoped waivers; each entry is its own waiver record. Independent
175
193
  // of the pack-level status/reason/compensating_controls fields above.
176
194
  // Defaults to [] for backward compatibility — existing packs unaffected.
177
- section_waivers: z.array(SectionScopedWaiverSchema).default([])
195
+ section_waivers: z2.array(SectionScopedWaiverSchema).default([])
178
196
  });
179
- FreshnessRequirementsSchema = z.object({
180
- required: z.boolean().default(true),
181
- max_source_age_months: z.number().int().positive().nullable().default(null)
197
+ FreshnessRequirementsSchema = z2.object({
198
+ required: z2.boolean().default(true),
199
+ max_source_age_months: z2.number().int().positive().nullable().default(null)
182
200
  });
183
- ReviewProfilePresetSchema = z.object({
184
- general_model: z.string().nullable().default(null),
185
- critic_model: z.string().nullable().default(null),
186
- review_window: z.number().int().positive().nullable().default(null),
187
- mode: z.enum(["general", "two_pass"]).default("two_pass"),
188
- status: z.enum(["calibrated_baseline", "experimental", "deprecated"]).default("experimental"),
189
- notes: z.string().nullable().default(null)
201
+ ReviewProfilePresetSchema = z2.object({
202
+ general_model: z2.string().nullable().default(null),
203
+ critic_model: z2.string().nullable().default(null),
204
+ review_window: z2.number().int().positive().nullable().default(null),
205
+ mode: z2.enum(["general", "two_pass"]).default("two_pass"),
206
+ status: z2.enum(["calibrated_baseline", "experimental", "deprecated"]).default("experimental"),
207
+ notes: z2.string().nullable().default(null),
208
+ reviewer_options: ReviewerOptionsSchema.optional()
190
209
  });
191
210
  DEFAULT_REVIEW_PROFILES = {
192
211
  // The dogfood-validated baseline. Section 03 of research-os-spec is the
@@ -200,27 +219,36 @@ var init_schema = __esm({
200
219
  mode: "two_pass",
201
220
  status: "calibrated_baseline",
202
221
  notes: "Calibrated baseline as of v0.1. 0% good-claim FPR on the seeded fixture; bad-claim any-flag recall 9/13 (69%). Smaller window required because hermes3:8b at 4-bit on a 5080 cannot complete 25-claim windows within a 3-minute budget."
222
+ },
223
+ "hermes-two-pass-deterministic": {
224
+ general_model: "hermes3:8b",
225
+ critic_model: "hermes3:8b",
226
+ review_window: 30,
227
+ mode: "two_pass",
228
+ status: "experimental",
229
+ notes: "Deterministic Hermes baseline (temperature=0, seed=7). seeded-v1 canonical receipt: failed (recurring per_category_any_flag_floor + decision_vocab_completeness \u2014 F-52, F-49). See calibration/reviewer-profiles/hermes-two-pass-deterministic/seeded-v1.md.",
230
+ reviewer_options: { temperature: 0, seed: 7 }
203
231
  }
204
232
  };
205
- ResearchYamlSchema = z.object({
206
- research_os_version: z.string(),
207
- created_at: z.string(),
208
- topic: z.string().min(10, "Topic must be at least 10 characters"),
209
- decision: z.string().default(""),
210
- audience: z.string().default("self"),
211
- desired_output: z.string().default(""),
212
- max_runtime_minutes: z.number().int().positive().default(240),
233
+ ResearchYamlSchema = z2.object({
234
+ research_os_version: z2.string(),
235
+ created_at: z2.string(),
236
+ topic: z2.string().min(10, "Topic must be at least 10 characters"),
237
+ decision: z2.string().default(""),
238
+ audience: z2.string().default("self"),
239
+ desired_output: z2.string().default(""),
240
+ max_runtime_minutes: z2.number().int().positive().default(240),
213
241
  freshness: FreshnessRequirementsSchema.default({}),
214
- excluded_sources: z.array(z.string()).default([]),
242
+ excluded_sources: z2.array(z2.string()).default([]),
215
243
  primary_source_waiver: PrimarySourceWaiverSchema.default({}),
216
- sections: z.array(SectionSchema).default([]),
244
+ sections: z2.array(SectionSchema).default([]),
217
245
  gates: GateConfigSchema.default({}),
218
246
  // Reviewer-profile presets baked into the pack so future review runs
219
247
  // (across any section in this pack) inherit the calibrated configuration
220
248
  // without rediscovering rig-specific timeouts and context issues. Override
221
249
  // with `--preset <name>` on `research-os review`.
222
- review_profiles: z.record(z.string(), ReviewProfilePresetSchema).default(() => ({ ...DEFAULT_REVIEW_PROFILES })),
223
- frozen_at: z.string().nullable().default(null)
250
+ review_profiles: z2.record(z2.string(), ReviewProfilePresetSchema).default(() => ({ ...DEFAULT_REVIEW_PROFILES })),
251
+ frozen_at: z2.string().nullable().default(null)
224
252
  });
225
253
  }
226
254
  });
@@ -364,21 +392,21 @@ var init_intake = __esm({
364
392
  });
365
393
 
366
394
  // src/sections/schema.ts
367
- import { z as z2 } from "zod";
395
+ import { z as z3 } from "zod";
368
396
  var SectionGatesYamlSchema;
369
397
  var init_schema2 = __esm({
370
398
  "src/sections/schema.ts"() {
371
399
  "use strict";
372
400
  init_schema();
373
- SectionGatesYamlSchema = z2.object({
374
- section_id: z2.string().regex(/^[0-9]{2}-[a-z0-9-]+$/, 'Section id must look like "01-landscape"'),
375
- purpose: z2.string().min(1),
401
+ SectionGatesYamlSchema = z3.object({
402
+ section_id: z3.string().regex(/^[0-9]{2}-[a-z0-9-]+$/, 'Section id must look like "01-landscape"'),
403
+ purpose: z3.string().min(1),
376
404
  status: SectionStatusSchema,
377
- created_at: z2.string(),
378
- max_time_minutes: z2.number().int().positive(),
379
- min_sources: z2.number().int().nonnegative(),
380
- primary_sources_required: z2.number().int().nonnegative(),
381
- contradictions_required: z2.boolean()
405
+ created_at: z3.string(),
406
+ max_time_minutes: z3.number().int().positive(),
407
+ min_sources: z3.number().int().nonnegative(),
408
+ primary_sources_required: z3.number().int().nonnegative(),
409
+ contradictions_required: z3.boolean()
382
410
  });
383
411
  }
384
412
  });
@@ -945,12 +973,12 @@ var init_extractors = __esm({
945
973
  });
946
974
 
947
975
  // src/sources/schema.ts
948
- import { z as z3 } from "zod";
976
+ import { z as z4 } from "zod";
949
977
  var SourceTypeSchema, RelevanceSchema, ExtractorNameSchema, FetchReceiptSchema, SourceCardSchema;
950
978
  var init_schema3 = __esm({
951
979
  "src/sources/schema.ts"() {
952
980
  "use strict";
953
- SourceTypeSchema = z3.enum([
981
+ SourceTypeSchema = z4.enum([
954
982
  "primary",
955
983
  "secondary",
956
984
  "forum",
@@ -958,51 +986,51 @@ var init_schema3 = __esm({
958
986
  "docs",
959
987
  "unknown"
960
988
  ]);
961
- RelevanceSchema = z3.enum(["high", "medium", "low", "unknown"]);
962
- ExtractorNameSchema = z3.enum(["heuristic", "ollama-intern"]);
963
- FetchReceiptSchema = z3.object({
964
- receipt_id: z3.string().regex(/^rcpt_[a-z0-9]+_\d+$/),
965
- source_id: z3.string().regex(/^src_[a-f0-9]{12}$/),
966
- section_id: z3.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
967
- requested_url: z3.string().url(),
968
- final_url: z3.string().url().nullable(),
969
- status: z3.number().int().nullable(),
970
- status_text: z3.string().nullable(),
971
- content_type: z3.string().nullable(),
972
- fetched_at: z3.string(),
973
- byte_count: z3.number().int().nonnegative().nullable(),
974
- sha256: z3.string().regex(/^[a-f0-9]{64}$/).nullable(),
975
- title: z3.string().nullable(),
976
- raw_text_path: z3.string().nullable(),
977
- fetch_outcome: z3.enum(["ok", "http_error", "network_error"]),
978
- fetch_error: z3.string().nullable(),
979
- extraction_outcome: z3.enum(["ok", "failed", "skipped"]),
989
+ RelevanceSchema = z4.enum(["high", "medium", "low", "unknown"]);
990
+ ExtractorNameSchema = z4.enum(["heuristic", "ollama-intern"]);
991
+ FetchReceiptSchema = z4.object({
992
+ receipt_id: z4.string().regex(/^rcpt_[a-z0-9]+_\d+$/),
993
+ source_id: z4.string().regex(/^src_[a-f0-9]{12}$/),
994
+ section_id: z4.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
995
+ requested_url: z4.string().url(),
996
+ final_url: z4.string().url().nullable(),
997
+ status: z4.number().int().nullable(),
998
+ status_text: z4.string().nullable(),
999
+ content_type: z4.string().nullable(),
1000
+ fetched_at: z4.string(),
1001
+ byte_count: z4.number().int().nonnegative().nullable(),
1002
+ sha256: z4.string().regex(/^[a-f0-9]{64}$/).nullable(),
1003
+ title: z4.string().nullable(),
1004
+ raw_text_path: z4.string().nullable(),
1005
+ fetch_outcome: z4.enum(["ok", "http_error", "network_error"]),
1006
+ fetch_error: z4.string().nullable(),
1007
+ extraction_outcome: z4.enum(["ok", "failed", "skipped"]),
980
1008
  extraction_extractor: ExtractorNameSchema.nullable(),
981
- extraction_error: z3.string().nullable()
982
- });
983
- SourceCardSchema = z3.object({
984
- source_id: z3.string().regex(/^src_[a-f0-9]{12}$/),
985
- receipt_id: z3.string().regex(/^rcpt_[a-z0-9]+_\d+$/),
986
- section_id: z3.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
987
- url: z3.string().url(),
988
- final_url: z3.string().url().nullable(),
989
- fetched_at: z3.string(),
990
- publisher: z3.string().nullable(),
991
- published_at: z3.string().nullable(),
992
- title: z3.string().min(1),
1009
+ extraction_error: z4.string().nullable()
1010
+ });
1011
+ SourceCardSchema = z4.object({
1012
+ source_id: z4.string().regex(/^src_[a-f0-9]{12}$/),
1013
+ receipt_id: z4.string().regex(/^rcpt_[a-z0-9]+_\d+$/),
1014
+ section_id: z4.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
1015
+ url: z4.string().url(),
1016
+ final_url: z4.string().url().nullable(),
1017
+ fetched_at: z4.string(),
1018
+ publisher: z4.string().nullable(),
1019
+ published_at: z4.string().nullable(),
1020
+ title: z4.string().min(1),
993
1021
  source_type: SourceTypeSchema,
994
1022
  relevance: RelevanceSchema,
995
- key_points: z3.array(z3.string()),
996
- limitations: z3.array(z3.string()),
997
- asserts: z3.string().min(1),
998
- scope: z3.string().nullable(),
999
- not: z3.string().nullable(),
1023
+ key_points: z4.array(z4.string()),
1024
+ limitations: z4.array(z4.string()),
1025
+ asserts: z4.string().min(1),
1026
+ scope: z4.string().nullable(),
1027
+ not: z4.string().nullable(),
1000
1028
  extracted_by: ExtractorNameSchema,
1001
- extracted_at: z3.string(),
1029
+ extracted_at: z4.string(),
1002
1030
  /** Rule that classified the URL. Added by Component B (v0.4). Optional for back-compat with pre-v0.4 cards. */
1003
- rule_hint: z3.string().optional(),
1031
+ rule_hint: z4.string().optional(),
1004
1032
  /** Precedence level of the rule that fired (2–6). Optional for back-compat with pre-v0.4 cards. */
1005
- precedence_level: z3.union([z3.literal(2), z3.literal(3), z3.literal(4), z3.literal(5), z3.literal(6)]).optional()
1033
+ precedence_level: z4.union([z4.literal(2), z4.literal(3), z4.literal(4), z4.literal(5), z4.literal(6)]).optional()
1006
1034
  });
1007
1035
  }
1008
1036
  });
@@ -1299,7 +1327,7 @@ var init_cards = __esm({
1299
1327
  });
1300
1328
 
1301
1329
  // src/sources/source-card-overrides-schema.ts
1302
- import { z as z4 } from "zod";
1330
+ import { z as z5 } from "zod";
1303
1331
  function validateSourceCardOverride(input) {
1304
1332
  return SourceCardOverrideSchema.parse(input);
1305
1333
  }
@@ -1308,20 +1336,20 @@ var init_source_card_overrides_schema = __esm({
1308
1336
  "src/sources/source-card-overrides-schema.ts"() {
1309
1337
  "use strict";
1310
1338
  init_schema3();
1311
- SourceCardOverrideSchema = z4.object({
1312
- source_id: z4.string().min(1, "source_id must be non-empty"),
1313
- url: z4.string().min(1, "url must be non-empty"),
1314
- previous_source_type: z4.string().nullable().optional(),
1339
+ SourceCardOverrideSchema = z5.object({
1340
+ source_id: z5.string().min(1, "source_id must be non-empty"),
1341
+ url: z5.string().min(1, "url must be non-empty"),
1342
+ previous_source_type: z5.string().nullable().optional(),
1315
1343
  new_source_type: SourceTypeSchema.nullable().optional(),
1316
- previous_publisher: z4.string().nullable().optional(),
1317
- new_publisher: z4.string().nullable().optional(),
1318
- reason: z4.string().refine((v) => v.trim().length > 0, { message: "reason must be non-empty after trim" }),
1319
- operator: z4.string().min(1, "operator must be non-empty"),
1320
- created_at: z4.string().refine((v) => isFinite(Date.parse(v)), {
1344
+ previous_publisher: z5.string().nullable().optional(),
1345
+ new_publisher: z5.string().nullable().optional(),
1346
+ reason: z5.string().refine((v) => v.trim().length > 0, { message: "reason must be non-empty after trim" }),
1347
+ operator: z5.string().min(1, "operator must be non-empty"),
1348
+ created_at: z5.string().refine((v) => isFinite(Date.parse(v)), {
1321
1349
  message: "created_at must be a valid ISO 8601 timestamp"
1322
1350
  }),
1323
- rule_hint: z4.string().nullable().optional(),
1324
- pack_version: z4.string().min(1, "pack_version must be non-empty")
1351
+ rule_hint: z5.string().nullable().optional(),
1352
+ pack_version: z5.string().min(1, "pack_version must be non-empty")
1325
1353
  }).refine(
1326
1354
  (obj) => obj.new_source_type != null && obj.new_source_type !== void 0 || obj.new_publisher != null && obj.new_publisher !== void 0,
1327
1355
  {
@@ -1462,23 +1490,23 @@ var init_gather = __esm({
1462
1490
  });
1463
1491
 
1464
1492
  // src/sources/excerpts/schema.ts
1465
- import { z as z5 } from "zod";
1493
+ import { z as z6 } from "zod";
1466
1494
  var EXCERPT_ID_PATTERN, ExcerptOriginSchema, ExcerptSchema;
1467
1495
  var init_schema4 = __esm({
1468
1496
  "src/sources/excerpts/schema.ts"() {
1469
1497
  "use strict";
1470
1498
  EXCERPT_ID_PATTERN = /^ex_[a-f0-9]{12}_\d{3,}$/;
1471
- ExcerptOriginSchema = z5.enum(["raw_text", "key_point"]);
1472
- ExcerptSchema = z5.object({
1473
- excerpt_id: z5.string().regex(EXCERPT_ID_PATTERN),
1474
- source_id: z5.string().regex(/^src_[a-f0-9]{12}$/),
1475
- source_hash: z5.string().regex(/^[a-f0-9]{64}$/).nullable(),
1476
- text: z5.string().min(1),
1477
- location_hint: z5.string().nullable(),
1478
- char_start: z5.number().int().nonnegative(),
1479
- char_end: z5.number().int().nonnegative(),
1499
+ ExcerptOriginSchema = z6.enum(["raw_text", "key_point"]);
1500
+ ExcerptSchema = z6.object({
1501
+ excerpt_id: z6.string().regex(EXCERPT_ID_PATTERN),
1502
+ source_id: z6.string().regex(/^src_[a-f0-9]{12}$/),
1503
+ source_hash: z6.string().regex(/^[a-f0-9]{64}$/).nullable(),
1504
+ text: z6.string().min(1),
1505
+ location_hint: z6.string().nullable(),
1506
+ char_start: z6.number().int().nonnegative(),
1507
+ char_end: z6.number().int().nonnegative(),
1480
1508
  origin: ExcerptOriginSchema,
1481
- created_at: z5.string()
1509
+ created_at: z6.string()
1482
1510
  });
1483
1511
  }
1484
1512
  });
@@ -2021,41 +2049,41 @@ var init_extractors2 = __esm({
2021
2049
  });
2022
2050
 
2023
2051
  // src/claims/schema.ts
2024
- import { z as z6 } from "zod";
2052
+ import { z as z7 } from "zod";
2025
2053
  var ConfidenceSchema, ClaimExtractorSchema, ReviewStateSchema, ClaimSchema;
2026
2054
  var init_schema5 = __esm({
2027
2055
  "src/claims/schema.ts"() {
2028
2056
  "use strict";
2029
2057
  init_schema4();
2030
- ConfidenceSchema = z6.enum(["low", "medium", "high"]);
2031
- ClaimExtractorSchema = z6.enum(["heuristic", "ollama-intern"]);
2032
- ReviewStateSchema = z6.enum([
2058
+ ConfidenceSchema = z7.enum(["low", "medium", "high"]);
2059
+ ClaimExtractorSchema = z7.enum(["heuristic", "ollama-intern"]);
2060
+ ReviewStateSchema = z7.enum([
2033
2061
  "candidate",
2034
2062
  "gated",
2035
2063
  "reviewed",
2036
2064
  "rejected",
2037
2065
  "accepted"
2038
2066
  ]);
2039
- ClaimSchema = z6.object({
2040
- claim_id: z6.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/),
2041
- section_id: z6.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
2042
- source_ids: z6.array(z6.string().regex(/^src_[a-f0-9]{12}$/)).min(1, "every claim must reference at least one source_id"),
2043
- source_hashes: z6.array(z6.string().regex(/^[a-f0-9]{64}$/)),
2044
- asserts: z6.string().min(1),
2045
- scope: z6.string().nullable(),
2046
- not: z6.string().nullable(),
2067
+ ClaimSchema = z7.object({
2068
+ claim_id: z7.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/),
2069
+ section_id: z7.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
2070
+ source_ids: z7.array(z7.string().regex(/^src_[a-f0-9]{12}$/)).min(1, "every claim must reference at least one source_id"),
2071
+ source_hashes: z7.array(z7.string().regex(/^[a-f0-9]{64}$/)),
2072
+ asserts: z7.string().min(1),
2073
+ scope: z7.string().nullable(),
2074
+ not: z7.string().nullable(),
2047
2075
  // Span-first extraction: the model picks excerpt IDs from the deterministic
2048
2076
  // ledger; research-os copies the literal text into evidence_excerpt. Models
2049
2077
  // may interpret source spans; they may not author evidence spans.
2050
2078
  // Allowed empty for legacy claims that pre-date span-first extraction —
2051
2079
  // those should be re-extracted; new writes always populate at least one ID.
2052
- evidence_excerpt_ids: z6.array(z6.string().regex(EXCERPT_ID_PATTERN)).default([]),
2053
- evidence_excerpt: z6.string().min(1),
2054
- evidence_location: z6.string().nullable(),
2080
+ evidence_excerpt_ids: z7.array(z7.string().regex(EXCERPT_ID_PATTERN)).default([]),
2081
+ evidence_excerpt: z7.string().min(1),
2082
+ evidence_location: z7.string().nullable(),
2055
2083
  confidence: ConfidenceSchema,
2056
2084
  extractor: ClaimExtractorSchema,
2057
- extraction_method: z6.string().min(1),
2058
- created_at: z6.string(),
2085
+ extraction_method: z7.string().min(1),
2086
+ created_at: z7.string(),
2059
2087
  review_state: ReviewStateSchema
2060
2088
  });
2061
2089
  }
@@ -2333,53 +2361,53 @@ var init_extract = __esm({
2333
2361
  });
2334
2362
 
2335
2363
  // src/claims/density/schema.ts
2336
- import { z as z7 } from "zod";
2364
+ import { z as z8 } from "zod";
2337
2365
  var PerSourceDensitySchema, NearDuplicateClusterSchema, DensityFlagSchema, ClaimDensityAuditSchema;
2338
2366
  var init_schema6 = __esm({
2339
2367
  "src/claims/density/schema.ts"() {
2340
2368
  "use strict";
2341
- PerSourceDensitySchema = z7.object({
2342
- source_id: z7.string().regex(/^src_[a-f0-9]{12}$/),
2343
- publisher: z7.string().nullable(),
2344
- source_word_count: z7.number().int().nonnegative(),
2345
- claim_count: z7.number().int().nonnegative(),
2346
- claims_per_1k_words: z7.number(),
2347
- share_of_section: z7.number(),
2369
+ PerSourceDensitySchema = z8.object({
2370
+ source_id: z8.string().regex(/^src_[a-f0-9]{12}$/),
2371
+ publisher: z8.string().nullable(),
2372
+ source_word_count: z8.number().int().nonnegative(),
2373
+ claim_count: z8.number().int().nonnegative(),
2374
+ claims_per_1k_words: z8.number(),
2375
+ share_of_section: z8.number(),
2348
2376
  // 0..1
2349
- weak_scope_count: z7.number().int().nonnegative(),
2350
- generic_scope_count: z7.number().int().nonnegative()
2377
+ weak_scope_count: z8.number().int().nonnegative(),
2378
+ generic_scope_count: z8.number().int().nonnegative()
2351
2379
  });
2352
- NearDuplicateClusterSchema = z7.object({
2353
- representative_assert: z7.string(),
2354
- member_count: z7.number().int().nonnegative(),
2355
- claim_ids: z7.array(z7.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/))
2380
+ NearDuplicateClusterSchema = z8.object({
2381
+ representative_assert: z8.string(),
2382
+ member_count: z8.number().int().nonnegative(),
2383
+ claim_ids: z8.array(z8.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/))
2356
2384
  });
2357
- DensityFlagSchema = z7.object({
2358
- type: z7.enum([
2385
+ DensityFlagSchema = z8.object({
2386
+ type: z8.enum([
2359
2387
  "source_dominance",
2360
2388
  "high_per_word_density",
2361
2389
  "large_near_duplicate_cluster",
2362
2390
  "weak_scope_majority"
2363
2391
  ]),
2364
- severity: z7.enum(["info", "warn", "block"]),
2365
- message: z7.string(),
2366
- affects_source_ids: z7.array(z7.string().regex(/^src_[a-f0-9]{12}$/)).default([]),
2367
- affects_claim_ids: z7.array(z7.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/)).default([])
2392
+ severity: z8.enum(["info", "warn", "block"]),
2393
+ message: z8.string(),
2394
+ affects_source_ids: z8.array(z8.string().regex(/^src_[a-f0-9]{12}$/)).default([]),
2395
+ affects_claim_ids: z8.array(z8.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/)).default([])
2368
2396
  });
2369
- ClaimDensityAuditSchema = z7.object({
2370
- audit_id: z7.string().regex(/^cda_[0-9]+_[a-z0-9-]+$/),
2371
- section_id: z7.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
2372
- audited_at: z7.string(),
2373
- research_os_version: z7.string(),
2374
- candidate_claim_count: z7.number().int().nonnegative(),
2375
- source_count: z7.number().int().nonnegative(),
2376
- total_source_word_count: z7.number().int().nonnegative(),
2377
- claims_per_1k_words: z7.number(),
2378
- weak_scope_count: z7.number().int().nonnegative(),
2379
- generic_scope_count: z7.number().int().nonnegative(),
2380
- per_source: z7.array(PerSourceDensitySchema),
2381
- near_duplicate_clusters: z7.array(NearDuplicateClusterSchema),
2382
- flags: z7.array(DensityFlagSchema)
2397
+ ClaimDensityAuditSchema = z8.object({
2398
+ audit_id: z8.string().regex(/^cda_[0-9]+_[a-z0-9-]+$/),
2399
+ section_id: z8.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
2400
+ audited_at: z8.string(),
2401
+ research_os_version: z8.string(),
2402
+ candidate_claim_count: z8.number().int().nonnegative(),
2403
+ source_count: z8.number().int().nonnegative(),
2404
+ total_source_word_count: z8.number().int().nonnegative(),
2405
+ claims_per_1k_words: z8.number(),
2406
+ weak_scope_count: z8.number().int().nonnegative(),
2407
+ generic_scope_count: z8.number().int().nonnegative(),
2408
+ per_source: z8.array(PerSourceDensitySchema),
2409
+ near_duplicate_clusters: z8.array(NearDuplicateClusterSchema),
2410
+ flags: z8.array(DensityFlagSchema)
2383
2411
  });
2384
2412
  }
2385
2413
  });
@@ -2696,12 +2724,12 @@ var init_claims = __esm({
2696
2724
  });
2697
2725
 
2698
2726
  // src/contradictions/schema.ts
2699
- import { z as z8 } from "zod";
2727
+ import { z as z9 } from "zod";
2700
2728
  var ContradictionTypeSchema, SeveritySchema, OverlapAssessmentSchema, ContradictionDetectorSchema, ContradictionStatusSchema, ContradictionConfidenceSchema, ContradictionSchema;
2701
2729
  var init_schema7 = __esm({
2702
2730
  "src/contradictions/schema.ts"() {
2703
2731
  "use strict";
2704
- ContradictionTypeSchema = z8.enum([
2732
+ ContradictionTypeSchema = z9.enum([
2705
2733
  "direct_conflict",
2706
2734
  "scope_conflict",
2707
2735
  "temporal_conflict",
@@ -2709,37 +2737,37 @@ var init_schema7 = __esm({
2709
2737
  "evidence_conflict",
2710
2738
  "overgeneralization_risk"
2711
2739
  ]);
2712
- SeveritySchema = z8.enum(["low", "medium", "high", "blocking"]);
2713
- OverlapAssessmentSchema = z8.enum([
2740
+ SeveritySchema = z9.enum(["low", "medium", "high", "blocking"]);
2741
+ OverlapAssessmentSchema = z9.enum([
2714
2742
  "fully_overlapping",
2715
2743
  "partially_overlapping",
2716
2744
  "non_overlapping",
2717
2745
  "unknown"
2718
2746
  ]);
2719
- ContradictionDetectorSchema = z8.enum(["heuristic", "ollama-intern"]);
2720
- ContradictionStatusSchema = z8.enum([
2747
+ ContradictionDetectorSchema = z9.enum(["heuristic", "ollama-intern"]);
2748
+ ContradictionStatusSchema = z9.enum([
2721
2749
  "unresolved",
2722
2750
  "reconciled",
2723
2751
  "preserved_deliberately",
2724
2752
  "rejected"
2725
2753
  ]);
2726
- ContradictionConfidenceSchema = z8.enum(["low", "medium", "high"]);
2727
- ContradictionSchema = z8.object({
2728
- contradiction_id: z8.string().regex(/^cnt_[a-f0-9]{12}_(heuristic|ollama_intern)$/),
2729
- section_id: z8.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
2730
- claim_ids: z8.array(z8.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/)).length(2, "contradictions are pair-wise in v0.1"),
2731
- source_ids: z8.array(z8.string().regex(/^src_[a-f0-9]{12}$/)).min(1),
2754
+ ContradictionConfidenceSchema = z9.enum(["low", "medium", "high"]);
2755
+ ContradictionSchema = z9.object({
2756
+ contradiction_id: z9.string().regex(/^cnt_[a-f0-9]{12}_(heuristic|ollama_intern)$/),
2757
+ section_id: z9.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
2758
+ claim_ids: z9.array(z9.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/)).length(2, "contradictions are pair-wise in v0.1"),
2759
+ source_ids: z9.array(z9.string().regex(/^src_[a-f0-9]{12}$/)).min(1),
2732
2760
  type: ContradictionTypeSchema,
2733
- summary: z8.string().min(1),
2734
- scope_analysis: z8.string(),
2761
+ summary: z9.string().min(1),
2762
+ scope_analysis: z9.string(),
2735
2763
  overlap_assessment: OverlapAssessmentSchema,
2736
2764
  severity: SeveritySchema,
2737
2765
  confidence: ContradictionConfidenceSchema,
2738
2766
  detector: ContradictionDetectorSchema,
2739
- detection_method: z8.string().min(1),
2740
- evidence: z8.string(),
2767
+ detection_method: z9.string().min(1),
2768
+ evidence: z9.string(),
2741
2769
  status: ContradictionStatusSchema,
2742
- created_at: z8.string()
2770
+ created_at: z9.string()
2743
2771
  });
2744
2772
  }
2745
2773
  });
@@ -3181,12 +3209,12 @@ var init_markdown = __esm({
3181
3209
  });
3182
3210
 
3183
3211
  // src/triage/schema.ts
3184
- import { z as z9 } from "zod";
3212
+ import { z as z10 } from "zod";
3185
3213
  var TriageDecisionSchema, ClaimTriageSchema, TriageSummarySchema;
3186
3214
  var init_schema8 = __esm({
3187
3215
  "src/triage/schema.ts"() {
3188
3216
  "use strict";
3189
- TriageDecisionSchema = z9.enum([
3217
+ TriageDecisionSchema = z10.enum([
3190
3218
  // Passes triage and is forwarded to review.
3191
3219
  "selected_for_review",
3192
3220
  // Parked: kept on the canonical ledger as research truth, but not advanced.
@@ -3198,36 +3226,36 @@ var init_schema8 = __esm({
3198
3226
  "needs_scope_repair",
3199
3227
  "needs_human_review"
3200
3228
  ]);
3201
- ClaimTriageSchema = z9.object({
3202
- triage_id: z9.string().regex(/^tri_[a-f0-9]{12}$/),
3203
- claim_id: z9.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/),
3204
- section_id: z9.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3229
+ ClaimTriageSchema = z10.object({
3230
+ triage_id: z10.string().regex(/^tri_[a-f0-9]{12}$/),
3231
+ claim_id: z10.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/),
3232
+ section_id: z10.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3205
3233
  decision: TriageDecisionSchema,
3206
- reason: z9.string().min(1),
3234
+ reason: z10.string().min(1),
3207
3235
  // Rank among selected_for_review claims (1 = highest priority). null for
3208
3236
  // any non-selected decision.
3209
- rank: z9.number().int().positive().nullable(),
3237
+ rank: z10.number().int().positive().nullable(),
3210
3238
  // Quality score [0..1] used to sort. Stable. Higher = better.
3211
- quality_score: z9.number().min(0).max(1),
3212
- triage_method: z9.string().min(1),
3213
- created_at: z9.string()
3214
- });
3215
- TriageSummarySchema = z9.object({
3216
- summary_id: z9.string().regex(/^tris_[0-9]+_[a-z0-9-]+$/),
3217
- section_id: z9.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3218
- triaged_at: z9.string(),
3219
- research_os_version: z9.string(),
3220
- triage_method: z9.string(),
3221
- candidate_claims: z9.number().int().nonnegative(),
3222
- decisions: z9.record(TriageDecisionSchema, z9.number().int().nonnegative()),
3223
- per_source_cap: z9.number().int().positive(),
3224
- duplicate_clusters_collapsed: z9.number().int().nonnegative(),
3225
- selected_count: z9.number().int().nonnegative(),
3226
- selected_per_source: z9.array(
3227
- z9.object({
3228
- source_id: z9.string().regex(/^src_[a-f0-9]{12}$/),
3229
- selected: z9.number().int().nonnegative(),
3230
- total: z9.number().int().nonnegative()
3239
+ quality_score: z10.number().min(0).max(1),
3240
+ triage_method: z10.string().min(1),
3241
+ created_at: z10.string()
3242
+ });
3243
+ TriageSummarySchema = z10.object({
3244
+ summary_id: z10.string().regex(/^tris_[0-9]+_[a-z0-9-]+$/),
3245
+ section_id: z10.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3246
+ triaged_at: z10.string(),
3247
+ research_os_version: z10.string(),
3248
+ triage_method: z10.string(),
3249
+ candidate_claims: z10.number().int().nonnegative(),
3250
+ decisions: z10.record(TriageDecisionSchema, z10.number().int().nonnegative()),
3251
+ per_source_cap: z10.number().int().positive(),
3252
+ duplicate_clusters_collapsed: z10.number().int().nonnegative(),
3253
+ selected_count: z10.number().int().nonnegative(),
3254
+ selected_per_source: z10.array(
3255
+ z10.object({
3256
+ source_id: z10.string().regex(/^src_[a-f0-9]{12}$/),
3257
+ selected: z10.number().int().nonnegative(),
3258
+ total: z10.number().int().nonnegative()
3231
3259
  })
3232
3260
  )
3233
3261
  });
@@ -3724,23 +3752,23 @@ var init_map = __esm({
3724
3752
  });
3725
3753
 
3726
3754
  // src/contradictions/resolution-schema.ts
3727
- import { z as z10 } from "zod";
3755
+ import { z as z11 } from "zod";
3728
3756
  var ResolutionStatusSchema, ContradictionResolutionSchema;
3729
3757
  var init_resolution_schema = __esm({
3730
3758
  "src/contradictions/resolution-schema.ts"() {
3731
3759
  "use strict";
3732
- ResolutionStatusSchema = z10.enum([
3760
+ ResolutionStatusSchema = z11.enum([
3733
3761
  "unresolved",
3734
3762
  "resolved",
3735
3763
  "preserved",
3736
3764
  "rejected"
3737
3765
  ]);
3738
- ContradictionResolutionSchema = z10.object({
3739
- contradiction_id: z10.string().min(1),
3766
+ ContradictionResolutionSchema = z11.object({
3767
+ contradiction_id: z11.string().min(1),
3740
3768
  status: ResolutionStatusSchema,
3741
- reason: z10.string().min(4),
3742
- resolved_at: z10.string().min(1),
3743
- resolved_by: z10.string().min(1)
3769
+ reason: z11.string().min(4),
3770
+ resolved_at: z11.string().min(1),
3771
+ resolved_by: z11.string().min(1)
3744
3772
  });
3745
3773
  }
3746
3774
  });
@@ -3857,12 +3885,13 @@ var init_contradictions = __esm({
3857
3885
  });
3858
3886
 
3859
3887
  // src/review/schema.ts
3860
- import { z as z11 } from "zod";
3888
+ import { z as z12 } from "zod";
3861
3889
  var FindingCategorySchema, FindingSeveritySchema, ReviewerNameSchema, ReviewDecisionSchema, ReviewConfidenceSchema, ReviewFindingSchema, ClaimReviewSchema, ReviewSnapshotSchema;
3862
3890
  var init_schema9 = __esm({
3863
3891
  "src/review/schema.ts"() {
3864
3892
  "use strict";
3865
- FindingCategorySchema = z11.enum([
3893
+ init_reviewer_options_schema();
3894
+ FindingCategorySchema = z12.enum([
3866
3895
  "unsupported_claim",
3867
3896
  "ungrounded_excerpt",
3868
3897
  "stale_claim",
@@ -3889,9 +3918,9 @@ var init_schema9 = __esm({
3889
3918
  // a low-value claim can appear in a perfectly-sized section.
3890
3919
  "valid_but_low_value"
3891
3920
  ]);
3892
- FindingSeveritySchema = z11.enum(["info", "warn", "block"]);
3893
- ReviewerNameSchema = z11.enum(["heuristic", "ollama-intern"]);
3894
- ReviewDecisionSchema = z11.enum([
3921
+ FindingSeveritySchema = z12.enum(["info", "warn", "block"]);
3922
+ ReviewerNameSchema = z12.enum(["heuristic", "ollama-intern"]);
3923
+ ReviewDecisionSchema = z12.enum([
3895
3924
  "accepted_for_synthesis",
3896
3925
  "rejected",
3897
3926
  "needs_scope_repair",
@@ -3899,43 +3928,48 @@ var init_schema9 = __esm({
3899
3928
  "needs_contradiction_mapping",
3900
3929
  "needs_human_review"
3901
3930
  ]);
3902
- ReviewConfidenceSchema = z11.enum(["low", "medium", "high"]);
3903
- ReviewFindingSchema = z11.object({
3904
- finding_id: z11.string().regex(/^fnd_[a-f0-9]{12}$/),
3905
- section_id: z11.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3906
- claim_ids: z11.array(z11.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/)),
3907
- source_ids: z11.array(z11.string().regex(/^src_[a-f0-9]{12}$/)),
3931
+ ReviewConfidenceSchema = z12.enum(["low", "medium", "high"]);
3932
+ ReviewFindingSchema = z12.object({
3933
+ finding_id: z12.string().regex(/^fnd_[a-f0-9]{12}$/),
3934
+ section_id: z12.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3935
+ claim_ids: z12.array(z12.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/)),
3936
+ source_ids: z12.array(z12.string().regex(/^src_[a-f0-9]{12}$/)),
3908
3937
  category: FindingCategorySchema,
3909
3938
  severity: FindingSeveritySchema,
3910
- summary: z11.string().min(1),
3911
- evidence: z11.string(),
3912
- required_action: z11.string(),
3939
+ summary: z12.string().min(1),
3940
+ evidence: z12.string(),
3941
+ required_action: z12.string(),
3913
3942
  reviewer: ReviewerNameSchema,
3914
- review_method: z11.string().min(1),
3943
+ review_method: z12.string().min(1),
3915
3944
  confidence: ReviewConfidenceSchema,
3916
- created_at: z11.string()
3945
+ created_at: z12.string()
3917
3946
  });
3918
- ClaimReviewSchema = z11.object({
3919
- claim_id: z11.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/),
3947
+ ClaimReviewSchema = z12.object({
3948
+ claim_id: z12.string().regex(/^clm_[a-f0-9]{12}_(heuristic|ollama_intern)_\d+$/),
3920
3949
  decision: ReviewDecisionSchema,
3921
- reason: z11.string().min(1),
3922
- finding_ids: z11.array(z11.string()),
3950
+ reason: z12.string().min(1),
3951
+ finding_ids: z12.array(z12.string()),
3923
3952
  reviewer: ReviewerNameSchema,
3924
- review_method: z11.string().min(1),
3925
- created_at: z11.string()
3926
- });
3927
- ReviewSnapshotSchema = z11.object({
3928
- section_id: z11.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3953
+ review_method: z12.string().min(1),
3954
+ created_at: z12.string(),
3955
+ // v0.5: optional profile lineage. Additive-optional — pre-v0.5 records
3956
+ // without this field parse cleanly. Frozen packs unaffected (Zod .optional()
3957
+ // with no .default() leaves absent keys absent on round-trip).
3958
+ profile: z12.string().optional()
3959
+ });
3960
+ ReviewSnapshotSchema = z12.object({
3961
+ section_id: z12.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
3929
3962
  reviewer: ReviewerNameSchema,
3930
- review_method: z11.string(),
3931
- reviewed_at: z11.string(),
3932
- candidate_claims: z11.number().int().nonnegative(),
3933
- findings: z11.array(ReviewFindingSchema),
3934
- claim_reviews: z11.array(ClaimReviewSchema),
3935
- decision_counts: z11.record(ReviewDecisionSchema, z11.number().int().nonnegative()),
3936
- severity_counts: z11.record(FindingSeveritySchema, z11.number().int().nonnegative()),
3937
- llm_findings_rejected_ungrounded: z11.number().int().nonnegative(),
3938
- promoted_to_reviewed: z11.boolean()
3963
+ review_method: z12.string(),
3964
+ reviewed_at: z12.string(),
3965
+ candidate_claims: z12.number().int().nonnegative(),
3966
+ findings: z12.array(ReviewFindingSchema),
3967
+ claim_reviews: z12.array(ClaimReviewSchema),
3968
+ decision_counts: z12.record(ReviewDecisionSchema, z12.number().int().nonnegative()),
3969
+ severity_counts: z12.record(FindingSeveritySchema, z12.number().int().nonnegative()),
3970
+ llm_findings_rejected_ungrounded: z12.number().int().nonnegative(),
3971
+ promoted_to_reviewed: z12.boolean(),
3972
+ reviewer_options: ReviewerOptionsSchema.optional()
3939
3973
  });
3940
3974
  }
3941
3975
  });
@@ -4823,12 +4857,12 @@ var init_markdown2 = __esm({
4823
4857
  });
4824
4858
 
4825
4859
  // src/gates/schema.ts
4826
- import { z as z12 } from "zod";
4860
+ import { z as z13 } from "zod";
4827
4861
  var GateFamilySchema, GateCheckStatusSchema, VerdictSchema, GateCheckResultSchema, WaiverApplicationSchema, SectionGateResultSchema;
4828
4862
  var init_schema10 = __esm({
4829
4863
  "src/gates/schema.ts"() {
4830
4864
  "use strict";
4831
- GateFamilySchema = z12.enum([
4865
+ GateFamilySchema = z13.enum([
4832
4866
  "source_floor",
4833
4867
  "claim_integrity",
4834
4868
  "scope_integrity",
@@ -4838,85 +4872,85 @@ var init_schema10 = __esm({
4838
4872
  "waivers",
4839
4873
  "accepted_claim_floor"
4840
4874
  ]);
4841
- GateCheckStatusSchema = z12.enum([
4875
+ GateCheckStatusSchema = z13.enum([
4842
4876
  "pass",
4843
4877
  "warn",
4844
4878
  "fail",
4845
4879
  "pass_with_waiver",
4846
4880
  "warn_with_waiver"
4847
4881
  ]);
4848
- VerdictSchema = z12.enum(["pass", "warn", "fail", "blocked"]);
4849
- GateCheckResultSchema = z12.object({
4882
+ VerdictSchema = z13.enum(["pass", "warn", "fail", "blocked"]);
4883
+ GateCheckResultSchema = z13.object({
4850
4884
  family: GateFamilySchema,
4851
- check: z12.string().min(1),
4885
+ check: z13.string().min(1),
4852
4886
  status: GateCheckStatusSchema,
4853
- detail: z12.string(),
4854
- evidence: z12.array(z12.string()),
4855
- blocks_synthesis: z12.boolean()
4887
+ detail: z13.string(),
4888
+ evidence: z13.array(z13.string()),
4889
+ blocks_synthesis: z13.boolean()
4856
4890
  });
4857
- WaiverApplicationSchema = z12.object({
4891
+ WaiverApplicationSchema = z13.object({
4858
4892
  family: GateFamilySchema,
4859
- check: z12.string().min(1),
4860
- reason: z12.string().min(1),
4861
- compensating_controls: z12.array(z12.string()),
4893
+ check: z13.string().min(1),
4894
+ reason: z13.string().min(1),
4895
+ compensating_controls: z13.array(z13.string()),
4862
4896
  original_status: GateCheckStatusSchema,
4863
4897
  new_status: GateCheckStatusSchema
4864
4898
  });
4865
- SectionGateResultSchema = z12.object({
4866
- section_id: z12.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
4899
+ SectionGateResultSchema = z13.object({
4900
+ section_id: z13.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
4867
4901
  verdict: VerdictSchema,
4868
- summary: z12.string(),
4869
- checked_at: z12.string(),
4870
- synthesis_eligible: z12.boolean(),
4871
- gate_results: z12.array(GateCheckResultSchema),
4872
- failures: z12.array(GateCheckResultSchema),
4873
- warnings: z12.array(GateCheckResultSchema),
4874
- waivers_applied: z12.array(WaiverApplicationSchema),
4875
- blocking_reasons: z12.array(z12.string()),
4876
- claim_counts: z12.object({
4877
- total: z12.number().int().nonnegative(),
4878
- candidate: z12.number().int().nonnegative(),
4879
- with_evidence_excerpt: z12.number().int().nonnegative(),
4880
- with_source_hashes: z12.number().int().nonnegative(),
4881
- with_scope: z12.number().int().nonnegative(),
4882
- with_not: z12.number().int().nonnegative(),
4883
- universal_scope_null: z12.number().int().nonnegative(),
4884
- orphans: z12.number().int().nonnegative()
4902
+ summary: z13.string(),
4903
+ checked_at: z13.string(),
4904
+ synthesis_eligible: z13.boolean(),
4905
+ gate_results: z13.array(GateCheckResultSchema),
4906
+ failures: z13.array(GateCheckResultSchema),
4907
+ warnings: z13.array(GateCheckResultSchema),
4908
+ waivers_applied: z13.array(WaiverApplicationSchema),
4909
+ blocking_reasons: z13.array(z13.string()),
4910
+ claim_counts: z13.object({
4911
+ total: z13.number().int().nonnegative(),
4912
+ candidate: z13.number().int().nonnegative(),
4913
+ with_evidence_excerpt: z13.number().int().nonnegative(),
4914
+ with_source_hashes: z13.number().int().nonnegative(),
4915
+ with_scope: z13.number().int().nonnegative(),
4916
+ with_not: z13.number().int().nonnegative(),
4917
+ universal_scope_null: z13.number().int().nonnegative(),
4918
+ orphans: z13.number().int().nonnegative()
4885
4919
  }),
4886
- source_counts: z12.object({
4887
- total: z12.number().int().nonnegative(),
4888
- primary: z12.number().int().nonnegative(),
4889
- secondary: z12.number().int().nonnegative(),
4890
- forum: z12.number().int().nonnegative(),
4891
- benchmark: z12.number().int().nonnegative(),
4892
- docs: z12.number().int().nonnegative(),
4893
- unknown: z12.number().int().nonnegative(),
4894
- independent_publishers: z12.number().int().nonnegative(),
4895
- failed_fetches: z12.number().int().nonnegative(),
4896
- section_primary: z12.number().int().nonnegative(),
4897
- section_independent_publishers: z12.number().int().nonnegative()
4920
+ source_counts: z13.object({
4921
+ total: z13.number().int().nonnegative(),
4922
+ primary: z13.number().int().nonnegative(),
4923
+ secondary: z13.number().int().nonnegative(),
4924
+ forum: z13.number().int().nonnegative(),
4925
+ benchmark: z13.number().int().nonnegative(),
4926
+ docs: z13.number().int().nonnegative(),
4927
+ unknown: z13.number().int().nonnegative(),
4928
+ independent_publishers: z13.number().int().nonnegative(),
4929
+ failed_fetches: z13.number().int().nonnegative(),
4930
+ section_primary: z13.number().int().nonnegative().optional().default(0),
4931
+ section_independent_publishers: z13.number().int().nonnegative().optional().default(0)
4898
4932
  }),
4899
- contradiction_counts: z12.object({
4900
- total: z12.number().int().nonnegative(),
4901
- unresolved: z12.number().int().nonnegative(),
4902
- blocking: z12.number().int().nonnegative(),
4903
- by_type: z12.record(z12.string(), z12.number().int().nonnegative())
4933
+ contradiction_counts: z13.object({
4934
+ total: z13.number().int().nonnegative(),
4935
+ unresolved: z13.number().int().nonnegative(),
4936
+ blocking: z13.number().int().nonnegative(),
4937
+ by_type: z13.record(z13.string(), z13.number().int().nonnegative())
4904
4938
  }),
4905
- freshness_summary: z12.object({
4906
- policy_required: z12.boolean(),
4907
- max_source_age_months: z12.number().int().nullable(),
4908
- stale_source_policy: z12.enum(["warn", "fail"]),
4909
- stale_count: z12.number().int().nonnegative(),
4910
- unknown_date_count: z12.number().int().nonnegative()
4939
+ freshness_summary: z13.object({
4940
+ policy_required: z13.boolean(),
4941
+ max_source_age_months: z13.number().int().nullable(),
4942
+ stale_source_policy: z13.enum(["warn", "fail"]),
4943
+ stale_count: z13.number().int().nonnegative(),
4944
+ unknown_date_count: z13.number().int().nonnegative()
4911
4945
  }),
4912
- scope_integrity_summary: z12.object({
4913
- universal_claims: z12.number().int().nonnegative(),
4914
- scoped_claims: z12.number().int().nonnegative(),
4915
- with_not_constraint: z12.number().int().nonnegative(),
4916
- overgen_risks_total: z12.number().int().nonnegative(),
4917
- overgen_risks_blocking: z12.number().int().nonnegative()
4946
+ scope_integrity_summary: z13.object({
4947
+ universal_claims: z13.number().int().nonnegative(),
4948
+ scoped_claims: z13.number().int().nonnegative(),
4949
+ with_not_constraint: z13.number().int().nonnegative(),
4950
+ overgen_risks_total: z13.number().int().nonnegative(),
4951
+ overgen_risks_blocking: z13.number().int().nonnegative()
4918
4952
  }),
4919
- next_actions: z12.array(z12.string())
4953
+ next_actions: z13.array(z13.string())
4920
4954
  });
4921
4955
  }
4922
4956
  });
@@ -5253,7 +5287,7 @@ var init_gates = __esm({
5253
5287
  import { existsSync as existsSync13 } from "fs";
5254
5288
  import { mkdir as mkdir11, readFile as readFile13, writeFile as writeFile11 } from "fs/promises";
5255
5289
  import { join as join14 } from "path";
5256
- import { z as z13 } from "zod";
5290
+ import { z as z14 } from "zod";
5257
5291
  function reviewActivePath(packPath, sectionId) {
5258
5292
  return join14(packPath, "sections", sectionId, "review-active.json");
5259
5293
  }
@@ -5283,22 +5317,22 @@ var init_profiles = __esm({
5283
5317
  "src/review/profiles.ts"() {
5284
5318
  "use strict";
5285
5319
  DEFAULT_PROFILE = "default";
5286
- PromotionCalibrationSummarySchema = z13.object({
5287
- fixture: z13.string().nullable().default(null),
5288
- good_false_positive_rate: z13.string().nullable().default(null),
5289
- bad_any_flag_recall: z13.string().nullable().default(null),
5290
- strict_category_recall: z13.string().nullable().default(null),
5291
- unsupported_claim_recall: z13.string().nullable().default(null),
5292
- notes: z13.string().nullable().default(null)
5293
- });
5294
- ReviewActiveSchema = z13.object({
5295
- active_profile: z13.string().min(1),
5296
- promoted_at: z13.string(),
5297
- promoted_method: z13.string(),
5298
- promoted_reviewer: z13.string(),
5320
+ PromotionCalibrationSummarySchema = z14.object({
5321
+ fixture: z14.string().nullable().default(null),
5322
+ good_false_positive_rate: z14.string().nullable().default(null),
5323
+ bad_any_flag_recall: z14.string().nullable().default(null),
5324
+ strict_category_recall: z14.string().nullable().default(null),
5325
+ unsupported_claim_recall: z14.string().nullable().default(null),
5326
+ notes: z14.string().nullable().default(null)
5327
+ });
5328
+ ReviewActiveSchema = z14.object({
5329
+ active_profile: z14.string().min(1),
5330
+ promoted_at: z14.string(),
5331
+ promoted_method: z14.string(),
5332
+ promoted_reviewer: z14.string(),
5299
5333
  // Free-text reason the profile was promoted. Recorded once at promotion
5300
5334
  // time; not derived from artifacts. Required.
5301
- promotion_reason: z13.string().min(8).default("promoted via review-promote without an explicit reason"),
5335
+ promotion_reason: z14.string().min(8).default("promoted via review-promote without an explicit reason"),
5302
5336
  // Optional calibration evidence captured at promotion time so downstream
5303
5337
  // consumers can see WHY the reviewer was trusted.
5304
5338
  calibration_summary: PromotionCalibrationSummarySchema.nullable().default(null)
@@ -5646,6 +5680,7 @@ var init_ollama_intern4 = __esm({
5646
5680
  "src/review/reviewers/ollama-intern.ts"() {
5647
5681
  "use strict";
5648
5682
  init_ollama_intern();
5683
+ init_reviewer_options_schema();
5649
5684
  DEFAULT_HOST4 = "http://localhost:11434";
5650
5685
  DEFAULT_MODEL4 = "hermes3:8b";
5651
5686
  DEFAULT_TIMEOUT_MS3 = 18e4;
@@ -5734,6 +5769,7 @@ Return ONE JSON object: {"findings": [...]}.`;
5734
5769
  timeoutMs;
5735
5770
  claimsPerWindow;
5736
5771
  fetchImpl;
5772
+ reviewerOptions;
5737
5773
  constructor(config = {}) {
5738
5774
  this.host = normalizeOllamaHost(config.host ?? process.env.OLLAMA_HOST ?? DEFAULT_HOST4);
5739
5775
  this.model = config.model ?? process.env.OLLAMA_INTERN_MODEL ?? DEFAULT_MODEL4;
@@ -5742,6 +5778,7 @@ Return ONE JSON object: {"findings": [...]}.`;
5742
5778
  const envWindow = process.env.OLLAMA_INTERN_REVIEW_WINDOW;
5743
5779
  this.claimsPerWindow = config.claimsPerWindow ?? (envWindow ? parseInt(envWindow, 10) || DEFAULT_CLAIMS_PER_WINDOW : DEFAULT_CLAIMS_PER_WINDOW);
5744
5780
  this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
5781
+ this.reviewerOptions = config.reviewer_options ? ReviewerOptionsSchema.parse(config.reviewer_options) : void 0;
5745
5782
  }
5746
5783
  async available() {
5747
5784
  try {
@@ -5794,7 +5831,17 @@ ${claimsBlock}`;
5794
5831
  // native window; review prompts with 20+ claims exceed that and
5795
5832
  // get silently truncated, which drops claim_ids and confuses the
5796
5833
  // model. Explicitly request 8K so paged windows fit cleanly.
5797
- options: { num_ctx: 8192 },
5834
+ // Additional sampling params (temperature, seed, etc.) are merged
5835
+ // from reviewerOptions when set. Use !== undefined throughout —
5836
+ // temperature: 0 is valid and must not be dropped by truthiness.
5837
+ options: {
5838
+ num_ctx: this.reviewerOptions?.num_ctx ?? 8192,
5839
+ ...this.reviewerOptions?.temperature !== void 0 && { temperature: this.reviewerOptions.temperature },
5840
+ ...this.reviewerOptions?.seed !== void 0 && { seed: this.reviewerOptions.seed },
5841
+ ...this.reviewerOptions?.top_p !== void 0 && { top_p: this.reviewerOptions.top_p },
5842
+ ...this.reviewerOptions?.top_k !== void 0 && { top_k: this.reviewerOptions.top_k },
5843
+ ...this.reviewerOptions?.repeat_penalty !== void 0 && { repeat_penalty: this.reviewerOptions.repeat_penalty }
5844
+ },
5798
5845
  messages: [
5799
5846
  {
5800
5847
  role: "system",
@@ -5925,7 +5972,7 @@ function pickHighestPriority(decisions) {
5925
5972
  return "accepted_for_synthesis";
5926
5973
  }
5927
5974
  function deriveClaimReviews(args) {
5928
- const { claims, findings, reviewer, reviewMethod, activeSectionWaivers } = args;
5975
+ const { claims, findings, reviewer, reviewMethod, activeSectionWaivers, profile } = args;
5929
5976
  const reviews = [];
5930
5977
  const now = (/* @__PURE__ */ new Date()).toISOString();
5931
5978
  const monopolyWaived = Array.isArray(activeSectionWaivers) && activeSectionWaivers.some((w) => w.scope === "min_independent_publishers");
@@ -5940,7 +5987,8 @@ function deriveClaimReviews(args) {
5940
5987
  finding_ids: [],
5941
5988
  reviewer,
5942
5989
  review_method: reviewMethod,
5943
- created_at: now
5990
+ created_at: now,
5991
+ ...profile !== void 0 ? { profile } : {}
5944
5992
  });
5945
5993
  continue;
5946
5994
  }
@@ -5974,7 +6022,8 @@ function deriveClaimReviews(args) {
5974
6022
  finding_ids: claimFindings.map((f) => f.finding_id),
5975
6023
  reviewer,
5976
6024
  review_method: reviewMethod,
5977
- created_at: now
6025
+ created_at: now,
6026
+ ...profile !== void 0 ? { profile } : {}
5978
6027
  });
5979
6028
  }
5980
6029
  return reviews;
@@ -6043,6 +6092,16 @@ function renderReviewMarkdown(snapshot) {
6043
6092
  lines.push("");
6044
6093
  lines.push("> Adversarial review judges research integrity. It does not synthesize, rewrite source truth, or erase extraction history. Decisions below are review truth \u2014 claims.jsonl is unchanged.");
6045
6094
  lines.push("");
6095
+ const opts = snapshot.reviewer_options;
6096
+ if (opts && Object.keys(opts).length > 0) {
6097
+ lines.push("## Reviewer options");
6098
+ lines.push("");
6099
+ const KEY_ORDER = ["num_ctx", "temperature", "seed", "top_p", "top_k", "repeat_penalty"];
6100
+ for (const key of KEY_ORDER) {
6101
+ if (opts[key] !== void 0) lines.push(`- ${key}: ${opts[key]}`);
6102
+ }
6103
+ lines.push("");
6104
+ }
6046
6105
  lines.push("## Effective decisions");
6047
6106
  lines.push("");
6048
6107
  const decisions = snapshot.decision_counts;
@@ -6410,7 +6469,8 @@ async function runMultiPassReview(args) {
6410
6469
  drafts: merged,
6411
6470
  llmFindingsRejected,
6412
6471
  profile: args.options.profile ?? DEFAULT_PROFILE,
6413
- research: args.research
6472
+ research: args.research,
6473
+ reviewer_options: args.options.reviewer_options
6414
6474
  });
6415
6475
  }
6416
6476
  async function reviewWithSpecificReviewer(args) {
@@ -6439,7 +6499,8 @@ async function reviewWithSpecificReviewer(args) {
6439
6499
  drafts: result.drafts,
6440
6500
  llmFindingsRejected: 0,
6441
6501
  profile: args.options.profile ?? DEFAULT_PROFILE,
6442
- research: args.research
6502
+ research: args.research,
6503
+ reviewer_options: args.options.reviewer_options
6443
6504
  });
6444
6505
  }
6445
6506
  async function finalizeReview(args) {
@@ -6470,7 +6531,8 @@ async function finalizeReview(args) {
6470
6531
  findings: dedupedFindings,
6471
6532
  reviewer: args.reviewer,
6472
6533
  reviewMethod: args.reviewMethod,
6473
- activeSectionWaivers
6534
+ activeSectionWaivers,
6535
+ profile: args.profile !== DEFAULT_PROFILE ? args.profile : void 0
6474
6536
  });
6475
6537
  const decisionCounts = {
6476
6538
  accepted_for_synthesis: 0,
@@ -6498,7 +6560,8 @@ async function finalizeReview(args) {
6498
6560
  decision_counts: decisionCounts,
6499
6561
  severity_counts: severityCounts,
6500
6562
  llm_findings_rejected_ungrounded: args.llmFindingsRejected,
6501
- promoted_to_reviewed: promoted
6563
+ promoted_to_reviewed: promoted,
6564
+ reviewer_options: args.reviewer_options
6502
6565
  });
6503
6566
  const profDir = profileDir(args.packPath, args.sectionId, args.profile);
6504
6567
  await mkdir12(profDir, { recursive: true });
@@ -7543,8 +7606,8 @@ async function syncRepoKnowledge(options) {
7543
7606
  };
7544
7607
  }
7545
7608
  const exportResult = await exportRepoKnowledge({ packPath });
7546
- const { readFile: readFile26 } = await import("fs/promises");
7547
- const text = await readFile26(exportResult.outPath, "utf8");
7609
+ const { readFile: readFile27 } = await import("fs/promises");
7610
+ const text = await readFile27(exportResult.outPath, "utf8");
7548
7611
  const facts = text.split(/\r?\n/).filter((l) => l.trim().length > 0).map((l) => JSON.parse(l));
7549
7612
  try {
7550
7613
  const r = await rk.ingestFacts({ facts, namespace: "research-os" });
@@ -7584,26 +7647,26 @@ var init_indexer = __esm({
7584
7647
  });
7585
7648
 
7586
7649
  // src/dispositions/schema.ts
7587
- import { z as z14 } from "zod";
7650
+ import { z as z15 } from "zod";
7588
7651
  var ClaimSynthesisDispositionStatusSchema, ClaimSynthesisDispositionSchema;
7589
7652
  var init_schema12 = __esm({
7590
7653
  "src/dispositions/schema.ts"() {
7591
7654
  "use strict";
7592
- ClaimSynthesisDispositionStatusSchema = z14.enum([
7655
+ ClaimSynthesisDispositionStatusSchema = z15.enum([
7593
7656
  "parked_not_for_synthesis",
7594
7657
  "preserved_for_human_note",
7595
7658
  "needs_human_review_excluded",
7596
7659
  "out_of_bounds_regression_fixture"
7597
7660
  ]);
7598
- ClaimSynthesisDispositionSchema = z14.object({
7599
- claim_id: z14.string().min(1),
7600
- section_id: z14.string().min(1),
7661
+ ClaimSynthesisDispositionSchema = z15.object({
7662
+ claim_id: z15.string().min(1),
7663
+ section_id: z15.string().min(1),
7601
7664
  status: ClaimSynthesisDispositionStatusSchema,
7602
- reason: z14.string().min(4),
7603
- decided_by: z14.string().min(1),
7604
- authorized_by: z14.string().min(1),
7605
- source: z14.string().min(1),
7606
- created_at: z14.string().min(1)
7665
+ reason: z15.string().min(4),
7666
+ decided_by: z15.string().min(1),
7667
+ authorized_by: z15.string().min(1),
7668
+ source: z15.string().min(1),
7669
+ created_at: z15.string().min(1)
7607
7670
  });
7608
7671
  }
7609
7672
  });
@@ -7934,91 +7997,91 @@ var init_derive = __esm({
7934
7997
  });
7935
7998
 
7936
7999
  // src/cowork/schema.ts
7937
- import { z as z15 } from "zod";
8000
+ import { z as z16 } from "zod";
7938
8001
  var HandoffModeSchema, IndexStatusSchema, ProvenanceSummarySchema, SectionStateSchema, WaiverEntrySchema, GateVerdictEntrySchema, ReviewDecisionCountSchema, CoworkHandoffPayloadSchema;
7939
8002
  var init_schema13 = __esm({
7940
8003
  "src/cowork/schema.ts"() {
7941
8004
  "use strict";
7942
- HandoffModeSchema = z15.enum([
8005
+ HandoffModeSchema = z16.enum([
7943
8006
  "repair_required",
7944
8007
  "synthesis_ready",
7945
8008
  "human_review_required"
7946
8009
  ]);
7947
- IndexStatusSchema = z15.enum(["present", "missing"]);
7948
- ProvenanceSummarySchema = z15.object({
7949
- accepted_count: z15.number().int().nonnegative(),
7950
- rejected_count: z15.number().int().nonnegative(),
7951
- triage_parked_count: z15.number().int().nonnegative(),
7952
- needs_review_undispositioned_count: z15.number().int().nonnegative(),
7953
- dispositioned_count: z15.number().int().nonnegative(),
7954
- dispositioned_breakdown: z15.object({
7955
- parked_not_for_synthesis: z15.number().int().nonnegative(),
7956
- preserved_for_human_note: z15.number().int().nonnegative(),
7957
- needs_human_review_excluded: z15.number().int().nonnegative(),
7958
- out_of_bounds_regression_fixture: z15.number().int().nonnegative()
8010
+ IndexStatusSchema = z16.enum(["present", "missing"]);
8011
+ ProvenanceSummarySchema = z16.object({
8012
+ accepted_count: z16.number().int().nonnegative(),
8013
+ rejected_count: z16.number().int().nonnegative(),
8014
+ triage_parked_count: z16.number().int().nonnegative(),
8015
+ needs_review_undispositioned_count: z16.number().int().nonnegative(),
8016
+ dispositioned_count: z16.number().int().nonnegative(),
8017
+ dispositioned_breakdown: z16.object({
8018
+ parked_not_for_synthesis: z16.number().int().nonnegative(),
8019
+ preserved_for_human_note: z16.number().int().nonnegative(),
8020
+ needs_human_review_excluded: z16.number().int().nonnegative(),
8021
+ out_of_bounds_regression_fixture: z16.number().int().nonnegative()
7959
8022
  }),
7960
- active_repair_blockers: z15.number().int().nonnegative(),
7961
- active_unresolved_contradictions: z15.number().int().nonnegative(),
7962
- waivers_active: z15.array(z15.string()),
7963
- overrides_applied_count: z15.number().int().nonnegative()
7964
- });
7965
- SectionStateSchema = z15.object({
7966
- section_id: z15.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
7967
- purpose: z15.string(),
7968
- status: z15.string(),
7969
- has_gate_run: z15.boolean(),
7970
- has_review_run: z15.boolean(),
7971
- gate_verdict: z15.string().nullable(),
7972
- synthesis_eligible: z15.boolean(),
7973
- accepted_claim_ids: z15.array(z15.string()),
7974
- repair_claim_ids: z15.array(z15.string()),
7975
- rejected_claim_ids: z15.array(z15.string()),
7976
- dispositioned_claim_ids: z15.array(z15.string()).default([]),
7977
- candidate_claims_total: z15.number().int().nonnegative(),
7978
- unresolved_contradiction_ids: z15.array(z15.string()),
7979
- blocking_reasons: z15.array(z15.string()),
7980
- active_blockers: z15.array(z15.string()).default([]),
7981
- blocking_contradictions_unresolved: z15.number().int().nonnegative(),
8023
+ active_repair_blockers: z16.number().int().nonnegative(),
8024
+ active_unresolved_contradictions: z16.number().int().nonnegative(),
8025
+ waivers_active: z16.array(z16.string()),
8026
+ overrides_applied_count: z16.number().int().nonnegative()
8027
+ });
8028
+ SectionStateSchema = z16.object({
8029
+ section_id: z16.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
8030
+ purpose: z16.string(),
8031
+ status: z16.string(),
8032
+ has_gate_run: z16.boolean(),
8033
+ has_review_run: z16.boolean(),
8034
+ gate_verdict: z16.string().nullable(),
8035
+ synthesis_eligible: z16.boolean(),
8036
+ accepted_claim_ids: z16.array(z16.string()),
8037
+ repair_claim_ids: z16.array(z16.string()),
8038
+ rejected_claim_ids: z16.array(z16.string()),
8039
+ dispositioned_claim_ids: z16.array(z16.string()).default([]),
8040
+ candidate_claims_total: z16.number().int().nonnegative(),
8041
+ unresolved_contradiction_ids: z16.array(z16.string()),
8042
+ blocking_reasons: z16.array(z16.string()),
8043
+ active_blockers: z16.array(z16.string()).default([]),
8044
+ blocking_contradictions_unresolved: z16.number().int().nonnegative(),
7982
8045
  provenance_summary: ProvenanceSummarySchema.optional()
7983
8046
  });
7984
- WaiverEntrySchema = z15.object({
7985
- scope: z15.enum(["pack", "gate"]),
7986
- family: z15.string(),
7987
- reason: z15.string(),
7988
- compensating_controls: z15.array(z15.string()),
7989
- applied_to: z15.string()
7990
- });
7991
- GateVerdictEntrySchema = z15.object({
7992
- section_id: z15.string(),
7993
- verdict: z15.string(),
7994
- synthesis_eligible: z15.boolean()
7995
- });
7996
- ReviewDecisionCountSchema = z15.object({
7997
- section_id: z15.string(),
7998
- decision: z15.string(),
7999
- count: z15.number().int().nonnegative()
8000
- });
8001
- CoworkHandoffPayloadSchema = z15.object({
8002
- pack_id: z15.string(),
8003
- pack_topic: z15.string(),
8004
- generated_at: z15.string(),
8047
+ WaiverEntrySchema = z16.object({
8048
+ scope: z16.enum(["pack", "gate"]),
8049
+ family: z16.string(),
8050
+ reason: z16.string(),
8051
+ compensating_controls: z16.array(z16.string()),
8052
+ applied_to: z16.string()
8053
+ });
8054
+ GateVerdictEntrySchema = z16.object({
8055
+ section_id: z16.string(),
8056
+ verdict: z16.string(),
8057
+ synthesis_eligible: z16.boolean()
8058
+ });
8059
+ ReviewDecisionCountSchema = z16.object({
8060
+ section_id: z16.string(),
8061
+ decision: z16.string(),
8062
+ count: z16.number().int().nonnegative()
8063
+ });
8064
+ CoworkHandoffPayloadSchema = z16.object({
8065
+ pack_id: z16.string(),
8066
+ pack_topic: z16.string(),
8067
+ generated_at: z16.string(),
8005
8068
  mode: HandoffModeSchema,
8006
- synthesis_allowed: z15.boolean(),
8007
- summary: z15.string(),
8008
- sections: z15.array(SectionStateSchema),
8009
- accepted_claim_ids: z15.array(z15.string()),
8010
- repair_claim_ids: z15.array(z15.string()),
8011
- blocked_claim_ids: z15.array(z15.string()),
8012
- dispositioned_claim_ids: z15.array(z15.string()).default([]),
8013
- unresolved_contradiction_ids: z15.array(z15.string()),
8014
- waivers: z15.array(WaiverEntrySchema),
8015
- gate_verdicts: z15.array(GateVerdictEntrySchema),
8016
- review_decisions: z15.array(ReviewDecisionCountSchema),
8017
- recommended_next_actions: z15.array(z15.string()),
8018
- allowed_write_paths: z15.array(z15.string()),
8019
- forbidden_actions: z15.array(z15.string()),
8069
+ synthesis_allowed: z16.boolean(),
8070
+ summary: z16.string(),
8071
+ sections: z16.array(SectionStateSchema),
8072
+ accepted_claim_ids: z16.array(z16.string()),
8073
+ repair_claim_ids: z16.array(z16.string()),
8074
+ blocked_claim_ids: z16.array(z16.string()),
8075
+ dispositioned_claim_ids: z16.array(z16.string()).default([]),
8076
+ unresolved_contradiction_ids: z16.array(z16.string()),
8077
+ waivers: z16.array(WaiverEntrySchema),
8078
+ gate_verdicts: z16.array(GateVerdictEntrySchema),
8079
+ review_decisions: z16.array(ReviewDecisionCountSchema),
8080
+ recommended_next_actions: z16.array(z16.string()),
8081
+ allowed_write_paths: z16.array(z16.string()),
8082
+ forbidden_actions: z16.array(z16.string()),
8020
8083
  index_status: IndexStatusSchema,
8021
- warnings: z15.array(z15.string())
8084
+ warnings: z16.array(z16.string())
8022
8085
  });
8023
8086
  }
8024
8087
  });
@@ -8568,86 +8631,86 @@ var init_derive2 = __esm({
8568
8631
  });
8569
8632
 
8570
8633
  // src/synth/schema.ts
8571
- import { z as z16 } from "zod";
8634
+ import { z as z17 } from "zod";
8572
8635
  var SectionAcceptedSummarySchema, ClaimClusterSchema, SharedSourceSchema, ScopeOverlapSchema, CrossSectionContradictionRefSchema, WaiverDependencySchema, AllowedSynthesisInputSchema, ForbiddenInputSchema, CrossSectionMapSchema;
8573
8636
  var init_schema14 = __esm({
8574
8637
  "src/synth/schema.ts"() {
8575
8638
  "use strict";
8576
- SectionAcceptedSummarySchema = z16.object({
8577
- section_id: z16.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
8578
- purpose: z16.string(),
8579
- status: z16.string(),
8580
- accepted_claim_ids: z16.array(z16.string()),
8581
- excluded_reason: z16.string().nullable()
8582
- });
8583
- ClaimClusterSchema = z16.object({
8584
- cluster_id: z16.string(),
8585
- shared_source_ids: z16.array(z16.string()),
8586
- member_claim_ids: z16.array(z16.string()).min(1),
8587
- spans_sections: z16.array(z16.string())
8588
- });
8589
- SharedSourceSchema = z16.object({
8590
- source_id: z16.string(),
8591
- publisher: z16.string().nullable(),
8592
- source_type: z16.string(),
8593
- used_by_claim_ids: z16.array(z16.string()),
8594
- spans_sections: z16.array(z16.string())
8595
- });
8596
- ScopeOverlapSchema = z16.object({
8597
- claim_a: z16.string(),
8598
- claim_b: z16.string(),
8599
- scope_a: z16.string().nullable(),
8600
- scope_b: z16.string().nullable(),
8601
- jaccard: z16.number().min(0).max(1),
8602
- cross_section: z16.boolean(),
8603
- warning: z16.string()
8604
- });
8605
- CrossSectionContradictionRefSchema = z16.object({
8606
- contradiction_id: z16.string(),
8607
- claim_ids: z16.array(z16.string()),
8608
- sections: z16.array(z16.string()),
8609
- type: z16.string(),
8610
- severity: z16.string(),
8611
- status: z16.string()
8612
- });
8613
- WaiverDependencySchema = z16.object({
8614
- scope: z16.enum(["pack", "gate"]),
8615
- family: z16.string(),
8616
- reason: z16.string(),
8617
- compensating_controls: z16.array(z16.string()),
8618
- applied_to: z16.string(),
8619
- must_disclose_in: z16.enum(["decision-brief.md", "final-report.md", "both"])
8639
+ SectionAcceptedSummarySchema = z17.object({
8640
+ section_id: z17.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
8641
+ purpose: z17.string(),
8642
+ status: z17.string(),
8643
+ accepted_claim_ids: z17.array(z17.string()),
8644
+ excluded_reason: z17.string().nullable()
8620
8645
  });
8621
- AllowedSynthesisInputSchema = z16.object({
8622
- claim_id: z16.string(),
8623
- section_id: z16.string(),
8624
- artifact_path: z16.string(),
8625
- asserts: z16.string(),
8626
- scope: z16.string().nullable(),
8627
- not: z16.string().nullable(),
8628
- source_ids: z16.array(z16.string())
8629
- });
8630
- ForbiddenInputSchema = z16.object({
8631
- claim_id: z16.string(),
8632
- section_id: z16.string(),
8633
- decision: z16.string(),
8634
- reason: z16.string()
8646
+ ClaimClusterSchema = z17.object({
8647
+ cluster_id: z17.string(),
8648
+ shared_source_ids: z17.array(z17.string()),
8649
+ member_claim_ids: z17.array(z17.string()).min(1),
8650
+ spans_sections: z17.array(z17.string())
8635
8651
  });
8636
- CrossSectionMapSchema = z16.object({
8637
- pack_id: z16.string(),
8638
- pack_topic: z16.string(),
8639
- pack_decision: z16.string(),
8640
- generated_at: z16.string(),
8641
- accepted_claim_ids: z16.array(z16.string()),
8642
- sections: z16.array(SectionAcceptedSummarySchema),
8643
- claim_clusters: z16.array(ClaimClusterSchema),
8644
- shared_sources: z16.array(SharedSourceSchema),
8645
- scope_overlaps: z16.array(ScopeOverlapSchema),
8646
- cross_section_contradictions: z16.array(CrossSectionContradictionRefSchema),
8647
- waiver_dependencies: z16.array(WaiverDependencySchema),
8648
- open_questions: z16.array(z16.string()),
8649
- allowed_synthesis_inputs: z16.array(AllowedSynthesisInputSchema),
8650
- forbidden_inputs: z16.array(ForbiddenInputSchema)
8652
+ SharedSourceSchema = z17.object({
8653
+ source_id: z17.string(),
8654
+ publisher: z17.string().nullable(),
8655
+ source_type: z17.string(),
8656
+ used_by_claim_ids: z17.array(z17.string()),
8657
+ spans_sections: z17.array(z17.string())
8658
+ });
8659
+ ScopeOverlapSchema = z17.object({
8660
+ claim_a: z17.string(),
8661
+ claim_b: z17.string(),
8662
+ scope_a: z17.string().nullable(),
8663
+ scope_b: z17.string().nullable(),
8664
+ jaccard: z17.number().min(0).max(1),
8665
+ cross_section: z17.boolean(),
8666
+ warning: z17.string()
8667
+ });
8668
+ CrossSectionContradictionRefSchema = z17.object({
8669
+ contradiction_id: z17.string(),
8670
+ claim_ids: z17.array(z17.string()),
8671
+ sections: z17.array(z17.string()),
8672
+ type: z17.string(),
8673
+ severity: z17.string(),
8674
+ status: z17.string()
8675
+ });
8676
+ WaiverDependencySchema = z17.object({
8677
+ scope: z17.enum(["pack", "gate"]),
8678
+ family: z17.string(),
8679
+ reason: z17.string(),
8680
+ compensating_controls: z17.array(z17.string()),
8681
+ applied_to: z17.string(),
8682
+ must_disclose_in: z17.enum(["decision-brief.md", "final-report.md", "both"])
8683
+ });
8684
+ AllowedSynthesisInputSchema = z17.object({
8685
+ claim_id: z17.string(),
8686
+ section_id: z17.string(),
8687
+ artifact_path: z17.string(),
8688
+ asserts: z17.string(),
8689
+ scope: z17.string().nullable(),
8690
+ not: z17.string().nullable(),
8691
+ source_ids: z17.array(z17.string())
8692
+ });
8693
+ ForbiddenInputSchema = z17.object({
8694
+ claim_id: z17.string(),
8695
+ section_id: z17.string(),
8696
+ decision: z17.string(),
8697
+ reason: z17.string()
8698
+ });
8699
+ CrossSectionMapSchema = z17.object({
8700
+ pack_id: z17.string(),
8701
+ pack_topic: z17.string(),
8702
+ pack_decision: z17.string(),
8703
+ generated_at: z17.string(),
8704
+ accepted_claim_ids: z17.array(z17.string()),
8705
+ sections: z17.array(SectionAcceptedSummarySchema),
8706
+ claim_clusters: z17.array(ClaimClusterSchema),
8707
+ shared_sources: z17.array(SharedSourceSchema),
8708
+ scope_overlaps: z17.array(ScopeOverlapSchema),
8709
+ cross_section_contradictions: z17.array(CrossSectionContradictionRefSchema),
8710
+ waiver_dependencies: z17.array(WaiverDependencySchema),
8711
+ open_questions: z17.array(z17.string()),
8712
+ allowed_synthesis_inputs: z17.array(AllowedSynthesisInputSchema),
8713
+ forbidden_inputs: z17.array(ForbiddenInputSchema)
8651
8714
  });
8652
8715
  }
8653
8716
  });
@@ -9815,179 +9878,179 @@ var init_aggregate = __esm({
9815
9878
  });
9816
9879
 
9817
9880
  // src/audit/schema.ts
9818
- import { z as z17 } from "zod";
9881
+ import { z as z18 } from "zod";
9819
9882
  var PackVerdictSchema, HandoffModeSchema2, OrphanClaimRowSchema, StaleSourceRowSchema, WeakSourceRowSchema, UnresolvedContradictionRowSchema, ScopeWideningRiskRowSchema, SourceDiversityGapRowSchema, SynthesisReadinessRowSchema, PackAuditPayloadSchema;
9820
9883
  var init_schema15 = __esm({
9821
9884
  "src/audit/schema.ts"() {
9822
9885
  "use strict";
9823
- PackVerdictSchema = z17.enum([
9886
+ PackVerdictSchema = z18.enum([
9824
9887
  "ready_for_synthesis",
9825
9888
  "repair_required",
9826
9889
  "human_review_required",
9827
9890
  "blocked"
9828
9891
  ]);
9829
- HandoffModeSchema2 = z17.enum([
9892
+ HandoffModeSchema2 = z18.enum([
9830
9893
  "repair_required",
9831
9894
  "synthesis_ready",
9832
9895
  "human_review_required",
9833
9896
  "unknown"
9834
9897
  ]);
9835
- OrphanClaimRowSchema = z17.object({
9836
- claim_id: z17.string(),
9837
- section_id: z17.string(),
9838
- reason: z17.enum([
9898
+ OrphanClaimRowSchema = z18.object({
9899
+ claim_id: z18.string(),
9900
+ section_id: z18.string(),
9901
+ reason: z18.enum([
9839
9902
  "missing_source_card",
9840
9903
  "missing_source_hash",
9841
9904
  "missing_evidence_excerpt",
9842
9905
  "unresolvable_source_id"
9843
9906
  ]),
9844
- details: z17.string(),
9845
- artifact_path: z17.string()
9846
- });
9847
- StaleSourceRowSchema = z17.object({
9848
- source_id: z17.string(),
9849
- section_id: z17.string(),
9850
- publisher: z17.string().nullable(),
9851
- reason: z17.enum(["too_old", "missing_date", "unparseable_date"]),
9852
- details: z17.string(),
9853
- artifact_path: z17.string(),
9854
- policy: z17.object({
9855
- required: z17.boolean(),
9856
- max_source_age_months: z17.number().int().nullable(),
9857
- stale_source_policy: z17.enum(["warn", "fail"])
9907
+ details: z18.string(),
9908
+ artifact_path: z18.string()
9909
+ });
9910
+ StaleSourceRowSchema = z18.object({
9911
+ source_id: z18.string(),
9912
+ section_id: z18.string(),
9913
+ publisher: z18.string().nullable(),
9914
+ reason: z18.enum(["too_old", "missing_date", "unparseable_date"]),
9915
+ details: z18.string(),
9916
+ artifact_path: z18.string(),
9917
+ policy: z18.object({
9918
+ required: z18.boolean(),
9919
+ max_source_age_months: z18.number().int().nullable(),
9920
+ stale_source_policy: z18.enum(["warn", "fail"])
9858
9921
  })
9859
9922
  });
9860
- WeakSourceRowSchema = z17.object({
9861
- reason: z17.enum([
9923
+ WeakSourceRowSchema = z18.object({
9924
+ reason: z18.enum([
9862
9925
  "source_cluster_monopoly",
9863
9926
  "low_independent_publishers",
9864
9927
  "missing_primary_source",
9865
9928
  "excessive_type_imbalance",
9866
9929
  "failed_fetches_reducing_floor"
9867
9930
  ]),
9868
- section_id: z17.string(),
9869
- details: z17.string(),
9870
- evidence_ids: z17.array(z17.string()),
9871
- artifact_path: z17.string()
9872
- });
9873
- UnresolvedContradictionRowSchema = z17.object({
9874
- contradiction_id: z17.string(),
9875
- section_id: z17.string(),
9876
- type: z17.string(),
9877
- severity: z17.string(),
9878
- status: z17.string(),
9879
- claim_ids: z17.array(z17.string()),
9880
- artifact_path: z17.string()
9881
- });
9882
- ScopeWideningRiskRowSchema = z17.object({
9883
- reason: z17.enum([
9931
+ section_id: z18.string(),
9932
+ details: z18.string(),
9933
+ evidence_ids: z18.array(z18.string()),
9934
+ artifact_path: z18.string()
9935
+ });
9936
+ UnresolvedContradictionRowSchema = z18.object({
9937
+ contradiction_id: z18.string(),
9938
+ section_id: z18.string(),
9939
+ type: z18.string(),
9940
+ severity: z18.string(),
9941
+ status: z18.string(),
9942
+ claim_ids: z18.array(z18.string()),
9943
+ artifact_path: z18.string()
9944
+ });
9945
+ ScopeWideningRiskRowSchema = z18.object({
9946
+ reason: z18.enum([
9884
9947
  "overgeneralization_finding",
9885
9948
  "scope_null_in_use",
9886
9949
  "missing_not_flagged",
9887
9950
  "contextual_to_universal_risk"
9888
9951
  ]),
9889
- claim_id: z17.string(),
9890
- section_id: z17.string(),
9891
- details: z17.string(),
9892
- artifact_path: z17.string()
9952
+ claim_id: z18.string(),
9953
+ section_id: z18.string(),
9954
+ details: z18.string(),
9955
+ artifact_path: z18.string()
9893
9956
  });
9894
- SourceDiversityGapRowSchema = z17.object({
9895
- reason: z17.enum([
9957
+ SourceDiversityGapRowSchema = z18.object({
9958
+ reason: z18.enum([
9896
9959
  "section_publisher_monopoly",
9897
9960
  "low_section_publisher_count",
9898
9961
  "cross_section_publisher_overlap",
9899
9962
  "section_has_no_sources"
9900
9963
  ]),
9901
- section_id: z17.string(),
9902
- details: z17.string(),
9903
- evidence_ids: z17.array(z17.string())
9904
- });
9905
- SynthesisReadinessRowSchema = z17.object({
9906
- section_id: z17.string(),
9907
- purpose: z17.string(),
9908
- status: z17.string(),
9909
- has_gate_run: z17.boolean(),
9910
- has_review_run: z17.boolean(),
9911
- gate_verdict: z17.string().nullable(),
9912
- synthesis_eligible: z17.boolean(),
9913
- candidate_claims: z17.number().int().nonnegative(),
9914
- accepted_claims: z17.number().int().nonnegative(),
9915
- repair_claims: z17.number().int().nonnegative(),
9916
- rejected_claims: z17.number().int().nonnegative(),
9917
- dispositioned_claims: z17.number().int().nonnegative(),
9918
- blocking_reasons: z17.array(z17.string()),
9964
+ section_id: z18.string(),
9965
+ details: z18.string(),
9966
+ evidence_ids: z18.array(z18.string())
9967
+ });
9968
+ SynthesisReadinessRowSchema = z18.object({
9969
+ section_id: z18.string(),
9970
+ purpose: z18.string(),
9971
+ status: z18.string(),
9972
+ has_gate_run: z18.boolean(),
9973
+ has_review_run: z18.boolean(),
9974
+ gate_verdict: z18.string().nullable(),
9975
+ synthesis_eligible: z18.boolean(),
9976
+ candidate_claims: z18.number().int().nonnegative(),
9977
+ accepted_claims: z18.number().int().nonnegative(),
9978
+ repair_claims: z18.number().int().nonnegative(),
9979
+ rejected_claims: z18.number().int().nonnegative(),
9980
+ dispositioned_claims: z18.number().int().nonnegative(),
9981
+ blocking_reasons: z18.array(z18.string()),
9919
9982
  cowork_handoff_mode: HandoffModeSchema2,
9920
- workspace_allowed: z17.boolean()
9983
+ workspace_allowed: z18.boolean()
9921
9984
  });
9922
- PackAuditPayloadSchema = z17.object({
9923
- pack_id: z17.string(),
9924
- pack_topic: z17.string(),
9925
- generated_at: z17.string(),
9985
+ PackAuditPayloadSchema = z18.object({
9986
+ pack_id: z18.string(),
9987
+ pack_topic: z18.string(),
9988
+ generated_at: z18.string(),
9926
9989
  verdict: PackVerdictSchema,
9927
- synthesis_allowed: z17.boolean(),
9928
- section_summaries: z17.array(SynthesisReadinessRowSchema),
9929
- claim_summary: z17.object({
9930
- total: z17.number().int().nonnegative(),
9931
- candidate: z17.number().int().nonnegative(),
9932
- accepted_for_synthesis: z17.number().int().nonnegative(),
9933
- rejected: z17.number().int().nonnegative(),
9934
- needs_repair: z17.number().int().nonnegative(),
9935
- dispositioned: z17.number().int().nonnegative(),
9936
- no_review: z17.number().int().nonnegative(),
9937
- with_evidence_excerpt: z17.number().int().nonnegative(),
9938
- with_source_hashes: z17.number().int().nonnegative(),
9939
- scope_null: z17.number().int().nonnegative(),
9940
- not_null: z17.number().int().nonnegative(),
9941
- orphans: z17.number().int().nonnegative()
9990
+ synthesis_allowed: z18.boolean(),
9991
+ section_summaries: z18.array(SynthesisReadinessRowSchema),
9992
+ claim_summary: z18.object({
9993
+ total: z18.number().int().nonnegative(),
9994
+ candidate: z18.number().int().nonnegative(),
9995
+ accepted_for_synthesis: z18.number().int().nonnegative(),
9996
+ rejected: z18.number().int().nonnegative(),
9997
+ needs_repair: z18.number().int().nonnegative(),
9998
+ dispositioned: z18.number().int().nonnegative(),
9999
+ no_review: z18.number().int().nonnegative(),
10000
+ with_evidence_excerpt: z18.number().int().nonnegative(),
10001
+ with_source_hashes: z18.number().int().nonnegative(),
10002
+ scope_null: z18.number().int().nonnegative(),
10003
+ not_null: z18.number().int().nonnegative(),
10004
+ orphans: z18.number().int().nonnegative()
9942
10005
  }),
9943
- source_summary: z17.object({
9944
- total: z17.number().int().nonnegative(),
9945
- primary: z17.number().int().nonnegative(),
9946
- secondary: z17.number().int().nonnegative(),
9947
- forum: z17.number().int().nonnegative(),
9948
- benchmark: z17.number().int().nonnegative(),
9949
- docs: z17.number().int().nonnegative(),
9950
- unknown: z17.number().int().nonnegative(),
9951
- independent_publishers: z17.number().int().nonnegative(),
9952
- failed_fetches: z17.number().int().nonnegative(),
9953
- sections_with_sources: z17.number().int().nonnegative(),
9954
- sections_without_sources: z17.number().int().nonnegative()
10006
+ source_summary: z18.object({
10007
+ total: z18.number().int().nonnegative(),
10008
+ primary: z18.number().int().nonnegative(),
10009
+ secondary: z18.number().int().nonnegative(),
10010
+ forum: z18.number().int().nonnegative(),
10011
+ benchmark: z18.number().int().nonnegative(),
10012
+ docs: z18.number().int().nonnegative(),
10013
+ unknown: z18.number().int().nonnegative(),
10014
+ independent_publishers: z18.number().int().nonnegative(),
10015
+ failed_fetches: z18.number().int().nonnegative(),
10016
+ sections_with_sources: z18.number().int().nonnegative(),
10017
+ sections_without_sources: z18.number().int().nonnegative()
9955
10018
  }),
9956
- contradiction_summary: z17.object({
9957
- total: z17.number().int().nonnegative(),
9958
- unresolved: z17.number().int().nonnegative(),
9959
- blocking: z17.number().int().nonnegative(),
9960
- reconciled: z17.number().int().nonnegative(),
9961
- preserved_deliberately: z17.number().int().nonnegative(),
9962
- rejected: z17.number().int().nonnegative(),
9963
- by_type: z17.record(z17.string(), z17.number().int().nonnegative()),
9964
- sections_with_clean_ledger: z17.number().int().nonnegative()
10019
+ contradiction_summary: z18.object({
10020
+ total: z18.number().int().nonnegative(),
10021
+ unresolved: z18.number().int().nonnegative(),
10022
+ blocking: z18.number().int().nonnegative(),
10023
+ reconciled: z18.number().int().nonnegative(),
10024
+ preserved_deliberately: z18.number().int().nonnegative(),
10025
+ rejected: z18.number().int().nonnegative(),
10026
+ by_type: z18.record(z18.string(), z18.number().int().nonnegative()),
10027
+ sections_with_clean_ledger: z18.number().int().nonnegative()
9965
10028
  }),
9966
- review_summary: z17.object({
9967
- sections_with_review_run: z17.number().int().nonnegative(),
9968
- sections_without_review_run: z17.number().int().nonnegative(),
9969
- decision_counts: z17.record(z17.string(), z17.number().int().nonnegative()),
9970
- blocking_findings: z17.number().int().nonnegative()
10029
+ review_summary: z18.object({
10030
+ sections_with_review_run: z18.number().int().nonnegative(),
10031
+ sections_without_review_run: z18.number().int().nonnegative(),
10032
+ decision_counts: z18.record(z18.string(), z18.number().int().nonnegative()),
10033
+ blocking_findings: z18.number().int().nonnegative()
9971
10034
  }),
9972
- waiver_summary: z17.object({
9973
- total: z17.number().int().nonnegative(),
9974
- invalid: z17.number().int().nonnegative(),
9975
- by_family: z17.record(z17.string(), z17.number().int().nonnegative())
10035
+ waiver_summary: z18.object({
10036
+ total: z18.number().int().nonnegative(),
10037
+ invalid: z18.number().int().nonnegative(),
10038
+ by_family: z18.record(z18.string(), z18.number().int().nonnegative())
9976
10039
  }),
9977
- readiness_summary: z17.object({
9978
- total_sections: z17.number().int().nonnegative(),
9979
- ready_sections: z17.number().int().nonnegative(),
9980
- repair_sections: z17.number().int().nonnegative(),
9981
- blocked_sections: z17.number().int().nonnegative(),
9982
- no_gate_sections: z17.number().int().nonnegative(),
9983
- no_review_sections: z17.number().int().nonnegative(),
10040
+ readiness_summary: z18.object({
10041
+ total_sections: z18.number().int().nonnegative(),
10042
+ ready_sections: z18.number().int().nonnegative(),
10043
+ repair_sections: z18.number().int().nonnegative(),
10044
+ blocked_sections: z18.number().int().nonnegative(),
10045
+ no_gate_sections: z18.number().int().nonnegative(),
10046
+ no_review_sections: z18.number().int().nonnegative(),
9984
10047
  cowork_handoff_mode: HandoffModeSchema2,
9985
- workspace_allowed: z17.boolean()
10048
+ workspace_allowed: z18.boolean()
9986
10049
  }),
9987
- audit_files: z17.array(z17.string()),
9988
- blocking_reasons: z17.array(z17.string()),
9989
- warnings: z17.array(z17.string()),
9990
- next_actions: z17.array(z17.string())
10050
+ audit_files: z18.array(z18.string()),
10051
+ blocking_reasons: z18.array(z18.string()),
10052
+ warnings: z18.array(z18.string()),
10053
+ next_actions: z18.array(z18.string())
9991
10054
  });
9992
10055
  }
9993
10056
  });
@@ -10654,79 +10717,79 @@ var init_markdown7 = __esm({
10654
10717
  });
10655
10718
 
10656
10719
  // src/freeze/schema.ts
10657
- import { z as z18 } from "zod";
10720
+ import { z as z19 } from "zod";
10658
10721
  var ArtifactHashSchema, IntegrityCheckSchema, FreezeReceiptPayloadSchema, FreezeRefusalPayloadSchema;
10659
10722
  var init_schema16 = __esm({
10660
10723
  "src/freeze/schema.ts"() {
10661
10724
  "use strict";
10662
- ArtifactHashSchema = z18.object({
10663
- path: z18.string(),
10664
- sha256: z18.string().regex(/^[a-f0-9]{64}$/),
10665
- bytes: z18.number().int().nonnegative()
10666
- });
10667
- IntegrityCheckSchema = z18.object({
10668
- name: z18.string().min(1),
10669
- passed: z18.boolean(),
10670
- detail: z18.string()
10671
- });
10672
- FreezeReceiptPayloadSchema = z18.object({
10673
- pack_id: z18.string(),
10674
- pack_topic: z18.string(),
10675
- frozen_at: z18.string(),
10676
- verdict: z18.literal("frozen"),
10677
- pack_audit_hash: z18.string().regex(/^[a-f0-9]{64}$/),
10678
- handoff_hash: z18.string().regex(/^[a-f0-9]{64}$/),
10679
- synthesis_hashes: z18.array(ArtifactHashSchema),
10680
- canonical_artifact_hashes: z18.array(ArtifactHashSchema),
10681
- accepted_claim_ids: z18.array(z18.string()),
10682
- cited_claim_ids: z18.array(z18.string()),
10683
- uncited_accepted_claim_ids: z18.array(z18.string()),
10684
- unresolved_contradictions: z18.array(
10685
- z18.object({
10686
- contradiction_id: z18.string(),
10687
- section_id: z18.string(),
10688
- type: z18.string(),
10689
- severity: z18.string(),
10690
- status: z18.string(),
10691
- disclosed_in: z18.array(z18.string())
10725
+ ArtifactHashSchema = z19.object({
10726
+ path: z19.string(),
10727
+ sha256: z19.string().regex(/^[a-f0-9]{64}$/),
10728
+ bytes: z19.number().int().nonnegative()
10729
+ });
10730
+ IntegrityCheckSchema = z19.object({
10731
+ name: z19.string().min(1),
10732
+ passed: z19.boolean(),
10733
+ detail: z19.string()
10734
+ });
10735
+ FreezeReceiptPayloadSchema = z19.object({
10736
+ pack_id: z19.string(),
10737
+ pack_topic: z19.string(),
10738
+ frozen_at: z19.string(),
10739
+ verdict: z19.literal("frozen"),
10740
+ pack_audit_hash: z19.string().regex(/^[a-f0-9]{64}$/),
10741
+ handoff_hash: z19.string().regex(/^[a-f0-9]{64}$/),
10742
+ synthesis_hashes: z19.array(ArtifactHashSchema),
10743
+ canonical_artifact_hashes: z19.array(ArtifactHashSchema),
10744
+ accepted_claim_ids: z19.array(z19.string()),
10745
+ cited_claim_ids: z19.array(z19.string()),
10746
+ uncited_accepted_claim_ids: z19.array(z19.string()),
10747
+ unresolved_contradictions: z19.array(
10748
+ z19.object({
10749
+ contradiction_id: z19.string(),
10750
+ section_id: z19.string(),
10751
+ type: z19.string(),
10752
+ severity: z19.string(),
10753
+ status: z19.string(),
10754
+ disclosed_in: z19.array(z19.string())
10692
10755
  })
10693
10756
  ),
10694
- waivers_disclosed: z18.array(
10695
- z18.object({
10696
- family: z18.string(),
10697
- applied_to: z18.string(),
10698
- reason: z18.string(),
10699
- compensating_controls: z18.array(z18.string()),
10700
- disclosed_in: z18.array(z18.string())
10757
+ waivers_disclosed: z19.array(
10758
+ z19.object({
10759
+ family: z19.string(),
10760
+ applied_to: z19.string(),
10761
+ reason: z19.string(),
10762
+ compensating_controls: z19.array(z19.string()),
10763
+ disclosed_in: z19.array(z19.string())
10701
10764
  })
10702
10765
  ),
10703
- sections: z18.array(
10704
- z18.object({
10705
- section_id: z18.string(),
10706
- status: z18.string(),
10707
- accepted_claims: z18.number().int().nonnegative(),
10708
- sources: z18.number().int().nonnegative(),
10709
- contradictions: z18.number().int().nonnegative()
10766
+ sections: z19.array(
10767
+ z19.object({
10768
+ section_id: z19.string(),
10769
+ status: z19.string(),
10770
+ accepted_claims: z19.number().int().nonnegative(),
10771
+ sources: z19.number().int().nonnegative(),
10772
+ contradictions: z19.number().int().nonnegative()
10710
10773
  })
10711
10774
  ),
10712
- source_count: z18.number().int().nonnegative(),
10713
- claim_count: z18.number().int().nonnegative(),
10714
- contradiction_count: z18.number().int().nonnegative(),
10715
- review_finding_count: z18.number().int().nonnegative(),
10716
- gate_result_count: z18.number().int().nonnegative(),
10717
- integrity_checks: z18.array(IntegrityCheckSchema)
10718
- });
10719
- FreezeRefusalPayloadSchema = z18.object({
10720
- pack_id: z18.string(),
10721
- pack_topic: z18.string(),
10722
- checked_at: z18.string(),
10723
- verdict: z18.literal("refused"),
10724
- reasons: z18.array(z18.string()),
10725
- blocking_reasons: z18.array(z18.string()),
10726
- missing_artifacts: z18.array(z18.string()),
10727
- invalid_artifacts: z18.array(z18.object({ path: z18.string(), error: z18.string() })),
10728
- next_actions: z18.array(z18.string()),
10729
- would_freeze: z18.literal(false)
10775
+ source_count: z19.number().int().nonnegative(),
10776
+ claim_count: z19.number().int().nonnegative(),
10777
+ contradiction_count: z19.number().int().nonnegative(),
10778
+ review_finding_count: z19.number().int().nonnegative(),
10779
+ gate_result_count: z19.number().int().nonnegative(),
10780
+ integrity_checks: z19.array(IntegrityCheckSchema)
10781
+ });
10782
+ FreezeRefusalPayloadSchema = z19.object({
10783
+ pack_id: z19.string(),
10784
+ pack_topic: z19.string(),
10785
+ checked_at: z19.string(),
10786
+ verdict: z19.literal("refused"),
10787
+ reasons: z19.array(z19.string()),
10788
+ blocking_reasons: z19.array(z19.string()),
10789
+ missing_artifacts: z19.array(z19.string()),
10790
+ invalid_artifacts: z19.array(z19.object({ path: z19.string(), error: z19.string() })),
10791
+ next_actions: z19.array(z19.string()),
10792
+ would_freeze: z19.literal(false)
10730
10793
  });
10731
10794
  }
10732
10795
  });
@@ -11200,35 +11263,35 @@ var init_freeze = __esm({
11200
11263
  });
11201
11264
 
11202
11265
  // src/invalidate/schema.ts
11203
- import { z as z19 } from "zod";
11266
+ import { z as z20 } from "zod";
11204
11267
  var ArchivedArtifactSchema, SectionStatusChangeSchema, InvalidationReceiptSchema;
11205
11268
  var init_schema17 = __esm({
11206
11269
  "src/invalidate/schema.ts"() {
11207
11270
  "use strict";
11208
- ArchivedArtifactSchema = z19.object({
11209
- src: z19.string(),
11271
+ ArchivedArtifactSchema = z20.object({
11272
+ src: z20.string(),
11210
11273
  // path relative to packPath, before archival
11211
- dst: z19.string()
11274
+ dst: z20.string()
11212
11275
  // path relative to packPath, after archival
11213
11276
  });
11214
- SectionStatusChangeSchema = z19.object({
11215
- section_id: z19.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11216
- before: z19.string(),
11217
- after: z19.string()
11277
+ SectionStatusChangeSchema = z20.object({
11278
+ section_id: z20.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11279
+ before: z20.string(),
11280
+ after: z20.string()
11218
11281
  });
11219
- InvalidationReceiptSchema = z19.object({
11220
- receipt_id: z19.string().regex(/^inv_[0-9]+_[a-z0-9-]+$/),
11221
- contract_label: z19.string().min(1),
11222
- superseded_contract: z19.string().min(1).nullable(),
11223
- new_contract: z19.string().min(1),
11224
- reason: z19.string().min(8),
11225
- invalidated_at: z19.string(),
11226
- research_os_version: z19.string(),
11227
- affected_sections: z19.array(z19.string().regex(/^[0-9]{2}-[a-z0-9-]+$/)),
11228
- archived_artifacts: z19.array(ArchivedArtifactSchema),
11229
- section_status_changes: z19.array(SectionStatusChangeSchema),
11230
- frozen_at_cleared: z19.boolean(),
11231
- notes: z19.string().nullable()
11282
+ InvalidationReceiptSchema = z20.object({
11283
+ receipt_id: z20.string().regex(/^inv_[0-9]+_[a-z0-9-]+$/),
11284
+ contract_label: z20.string().min(1),
11285
+ superseded_contract: z20.string().min(1).nullable(),
11286
+ new_contract: z20.string().min(1),
11287
+ reason: z20.string().min(8),
11288
+ invalidated_at: z20.string(),
11289
+ research_os_version: z20.string(),
11290
+ affected_sections: z20.array(z20.string().regex(/^[0-9]{2}-[a-z0-9-]+$/)),
11291
+ archived_artifacts: z20.array(ArchivedArtifactSchema),
11292
+ section_status_changes: z20.array(SectionStatusChangeSchema),
11293
+ frozen_at_cleared: z20.boolean(),
11294
+ notes: z20.string().nullable()
11232
11295
  });
11233
11296
  }
11234
11297
  });
@@ -11494,7 +11557,7 @@ var init_run9 = __esm({
11494
11557
  import { existsSync as existsSync26 } from "fs";
11495
11558
  import { mkdir as mkdir20, rename as rename2, writeFile as writeFile20 } from "fs/promises";
11496
11559
  import { dirname as dirname7, join as join26, posix as posix2, relative as relative4, resolve as resolve21, sep as sep2 } from "path";
11497
- import { z as z20 } from "zod";
11560
+ import { z as z21 } from "zod";
11498
11561
  function posixify2(p) {
11499
11562
  return p.split(sep2).join("/");
11500
11563
  }
@@ -11626,15 +11689,15 @@ var init_review2 = __esm({
11626
11689
  init_errors();
11627
11690
  init_src();
11628
11691
  init_schema17();
11629
- ReviewInvalidationReceiptSchema = z20.object({
11630
- receipt_id: z20.string().regex(/^invr_[0-9]+_[a-z0-9-]+$/),
11631
- section_id: z20.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11632
- contract_label: z20.string().min(1),
11633
- reason: z20.string().min(8),
11634
- invalidated_at: z20.string(),
11635
- research_os_version: z20.string(),
11636
- archived_artifacts: z20.array(ArchivedArtifactSchema),
11637
- notes: z20.string().nullable()
11692
+ ReviewInvalidationReceiptSchema = z21.object({
11693
+ receipt_id: z21.string().regex(/^invr_[0-9]+_[a-z0-9-]+$/),
11694
+ section_id: z21.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11695
+ contract_label: z21.string().min(1),
11696
+ reason: z21.string().min(8),
11697
+ invalidated_at: z21.string(),
11698
+ research_os_version: z21.string(),
11699
+ archived_artifacts: z21.array(ArchivedArtifactSchema),
11700
+ notes: z21.string().nullable()
11638
11701
  });
11639
11702
  }
11640
11703
  });
@@ -11659,17 +11722,17 @@ var init_triage = __esm({
11659
11722
  });
11660
11723
 
11661
11724
  // src/discover/schema.ts
11662
- import { z as z21 } from "zod";
11725
+ import { z as z22 } from "zod";
11663
11726
  var DiscoveryCandidateStatusSchema, SourceTypeGuessSchema, DiscoveryCandidateSchema, DiscoverySummarySchema;
11664
11727
  var init_schema18 = __esm({
11665
11728
  "src/discover/schema.ts"() {
11666
11729
  "use strict";
11667
- DiscoveryCandidateStatusSchema = z21.enum([
11730
+ DiscoveryCandidateStatusSchema = z22.enum([
11668
11731
  "candidate",
11669
11732
  "approved",
11670
11733
  "rejected"
11671
11734
  ]);
11672
- SourceTypeGuessSchema = z21.enum([
11735
+ SourceTypeGuessSchema = z22.enum([
11673
11736
  "primary",
11674
11737
  "docs",
11675
11738
  "paper",
@@ -11679,36 +11742,36 @@ var init_schema18 = __esm({
11679
11742
  "benchmark",
11680
11743
  "unknown"
11681
11744
  ]);
11682
- DiscoveryCandidateSchema = z21.object({
11683
- candidate_id: z21.string().regex(/^disc_[a-f0-9]{12}$/),
11684
- section_id: z21.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11685
- url: z21.string().url(),
11686
- title: z21.string().min(1),
11687
- publisher: z21.string().nullable(),
11745
+ DiscoveryCandidateSchema = z22.object({
11746
+ candidate_id: z22.string().regex(/^disc_[a-f0-9]{12}$/),
11747
+ section_id: z22.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11748
+ url: z22.string().url(),
11749
+ title: z22.string().min(1),
11750
+ publisher: z22.string().nullable(),
11688
11751
  source_type_guess: SourceTypeGuessSchema,
11689
- why_relevant: z21.string().min(1),
11752
+ why_relevant: z22.string().min(1),
11690
11753
  // The free-text query that produced this candidate (for traceability).
11691
- query: z21.string().min(1),
11754
+ query: z22.string().min(1),
11692
11755
  // Lower rank = more central. Stable per-(query, provider) ordering.
11693
- rank: z21.number().int().positive(),
11694
- discovered_at: z21.string(),
11756
+ rank: z22.number().int().positive(),
11757
+ discovered_at: z22.string(),
11695
11758
  // 'candidate' | 'approved' | 'rejected'. Append-only: new entries with
11696
11759
  // same candidate_id supersede older ones; the latest entry's status wins.
11697
11760
  status: DiscoveryCandidateStatusSchema,
11698
- discovered_by: z21.string().min(1),
11699
- reason: z21.string().nullable().default(null)
11761
+ discovered_by: z22.string().min(1),
11762
+ reason: z22.string().nullable().default(null)
11700
11763
  });
11701
- DiscoverySummarySchema = z21.object({
11702
- summary_id: z21.string().regex(/^disum_[0-9]+_[a-z0-9-]+$/),
11703
- section_id: z21.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11704
- ran_at: z21.string(),
11705
- research_os_version: z21.string(),
11706
- query: z21.string().min(1),
11707
- provider: z21.string().min(1),
11708
- candidates_proposed: z21.number().int().nonnegative(),
11709
- candidates_validated: z21.number().int().nonnegative(),
11710
- candidates_rejected_invalid_url: z21.number().int().nonnegative(),
11711
- warnings: z21.array(z21.string())
11764
+ DiscoverySummarySchema = z22.object({
11765
+ summary_id: z22.string().regex(/^disum_[0-9]+_[a-z0-9-]+$/),
11766
+ section_id: z22.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
11767
+ ran_at: z22.string(),
11768
+ research_os_version: z22.string(),
11769
+ query: z22.string().min(1),
11770
+ provider: z22.string().min(1),
11771
+ candidates_proposed: z22.number().int().nonnegative(),
11772
+ candidates_validated: z22.number().int().nonnegative(),
11773
+ candidates_rejected_invalid_url: z22.number().int().nonnegative(),
11774
+ warnings: z22.array(z22.string())
11712
11775
  });
11713
11776
  }
11714
11777
  });
@@ -12192,88 +12255,88 @@ var init_src = __esm({
12192
12255
  init_triage();
12193
12256
  init_discover();
12194
12257
  init_errors();
12195
- RESEARCH_OS_VERSION = "0.4.0";
12258
+ RESEARCH_OS_VERSION = "0.6.0";
12196
12259
  }
12197
12260
  });
12198
12261
 
12199
12262
  // src/section_report/schema.ts
12200
- import { z as z22 } from "zod";
12263
+ import { z as z23 } from "zod";
12201
12264
  var SectionReportSourcesSchema, SectionReportExtractionSchema, SectionReportContradictionsSchema, SectionReportReviewSchema, SectionReportAcceptanceSchema, SectionReportSchema;
12202
12265
  var init_schema19 = __esm({
12203
12266
  "src/section_report/schema.ts"() {
12204
12267
  "use strict";
12205
- SectionReportSourcesSchema = z22.object({
12206
- fetched_ok: z22.number().int().nonnegative(),
12207
- source_cards: z22.number().int().nonnegative(),
12208
- publishers: z22.array(z22.string()),
12209
- primary_source_waiver: z22.object({
12210
- status: z22.enum(["none", "requested", "granted"]),
12211
- reason: z22.string().nullable(),
12212
- compensating_controls: z22.array(z22.string())
12268
+ SectionReportSourcesSchema = z23.object({
12269
+ fetched_ok: z23.number().int().nonnegative(),
12270
+ source_cards: z23.number().int().nonnegative(),
12271
+ publishers: z23.array(z23.string()),
12272
+ primary_source_waiver: z23.object({
12273
+ status: z23.enum(["none", "requested", "granted"]),
12274
+ reason: z23.string().nullable(),
12275
+ compensating_controls: z23.array(z23.string())
12213
12276
  })
12214
12277
  });
12215
- SectionReportExtractionSchema = z22.object({
12216
- candidate_claims: z22.number().int().nonnegative(),
12217
- claims_per_source: z22.array(
12218
- z22.object({
12219
- source_id: z22.string(),
12220
- claims: z22.number().int().nonnegative()
12278
+ SectionReportExtractionSchema = z23.object({
12279
+ candidate_claims: z23.number().int().nonnegative(),
12280
+ claims_per_source: z23.array(
12281
+ z23.object({
12282
+ source_id: z23.string(),
12283
+ claims: z23.number().int().nonnegative()
12221
12284
  })
12222
12285
  ),
12223
- claims_per_1k_words: z22.number(),
12224
- excerpt_pages_processed: z22.number().int().nonnegative().nullable(),
12225
- excerpt_id_failures: z22.number().int().nonnegative().nullable(),
12226
- malformed_extractor_outputs: z22.number().int().nonnegative().nullable(),
12227
- near_duplicate_clusters: z22.number().int().nonnegative(),
12228
- weak_scope_count: z22.number().int().nonnegative(),
12229
- generic_scope_count: z22.number().int().nonnegative(),
12230
- density_flags: z22.number().int().nonnegative()
12231
- });
12232
- SectionReportContradictionsSchema = z22.object({
12233
- pairs_compared: z22.number().int().nonnegative().nullable(),
12234
- contradiction_candidates: z22.number().int().nonnegative(),
12235
- overgeneralization_risks: z22.number().int().nonnegative()
12236
- });
12237
- SectionReportReviewSchema = z22.object({
12238
- reviewed: z22.boolean(),
12239
- accepted_for_synthesis: z22.number().int().nonnegative(),
12240
- needs_scope_repair: z22.number().int().nonnegative(),
12241
- needs_source_repair: z22.number().int().nonnegative(),
12242
- needs_contradiction_mapping: z22.number().int().nonnegative(),
12243
- rejected: z22.number().int().nonnegative(),
12244
- needs_human_review: z22.number().int().nonnegative(),
12245
- rejection_or_repair_by_category: z22.array(
12246
- z22.object({
12247
- category: z22.string(),
12248
- count: z22.number().int().nonnegative()
12286
+ claims_per_1k_words: z23.number(),
12287
+ excerpt_pages_processed: z23.number().int().nonnegative().nullable(),
12288
+ excerpt_id_failures: z23.number().int().nonnegative().nullable(),
12289
+ malformed_extractor_outputs: z23.number().int().nonnegative().nullable(),
12290
+ near_duplicate_clusters: z23.number().int().nonnegative(),
12291
+ weak_scope_count: z23.number().int().nonnegative(),
12292
+ generic_scope_count: z23.number().int().nonnegative(),
12293
+ density_flags: z23.number().int().nonnegative()
12294
+ });
12295
+ SectionReportContradictionsSchema = z23.object({
12296
+ pairs_compared: z23.number().int().nonnegative().nullable(),
12297
+ contradiction_candidates: z23.number().int().nonnegative(),
12298
+ overgeneralization_risks: z23.number().int().nonnegative()
12299
+ });
12300
+ SectionReportReviewSchema = z23.object({
12301
+ reviewed: z23.boolean(),
12302
+ accepted_for_synthesis: z23.number().int().nonnegative(),
12303
+ needs_scope_repair: z23.number().int().nonnegative(),
12304
+ needs_source_repair: z23.number().int().nonnegative(),
12305
+ needs_contradiction_mapping: z23.number().int().nonnegative(),
12306
+ rejected: z23.number().int().nonnegative(),
12307
+ needs_human_review: z23.number().int().nonnegative(),
12308
+ rejection_or_repair_by_category: z23.array(
12309
+ z23.object({
12310
+ category: z23.string(),
12311
+ count: z23.number().int().nonnegative()
12249
12312
  })
12250
12313
  )
12251
12314
  });
12252
- SectionReportAcceptanceSchema = z22.object({
12253
- candidate_claims: z22.number().int().nonnegative(),
12254
- accepted_for_synthesis: z22.number().int().nonnegative(),
12255
- acceptance_ratio: z22.number(),
12315
+ SectionReportAcceptanceSchema = z23.object({
12316
+ candidate_claims: z23.number().int().nonnegative(),
12317
+ accepted_for_synthesis: z23.number().int().nonnegative(),
12318
+ acceptance_ratio: z23.number(),
12256
12319
  // 0..1
12257
- accepted_per_source: z22.number(),
12320
+ accepted_per_source: z23.number(),
12258
12321
  // accepted / source_count, 0 if no sources
12259
- accepted_per_1k_words: z22.number(),
12260
- top_rejection_category: z22.string().nullable(),
12261
- claim_overproduction_fired: z22.boolean(),
12262
- synthesis_ready: z22.boolean()
12263
- });
12264
- SectionReportSchema = z22.object({
12265
- report_id: z22.string().regex(/^secrep_[0-9]+_[a-z0-9-]+$/),
12266
- section_id: z22.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
12267
- reported_at: z22.string(),
12268
- research_os_version: z22.string(),
12269
- status: z22.string(),
12322
+ accepted_per_1k_words: z23.number(),
12323
+ top_rejection_category: z23.string().nullable(),
12324
+ claim_overproduction_fired: z23.boolean(),
12325
+ synthesis_ready: z23.boolean()
12326
+ });
12327
+ SectionReportSchema = z23.object({
12328
+ report_id: z23.string().regex(/^secrep_[0-9]+_[a-z0-9-]+$/),
12329
+ section_id: z23.string().regex(/^[0-9]{2}-[a-z0-9-]+$/),
12330
+ reported_at: z23.string(),
12331
+ research_os_version: z23.string(),
12332
+ status: z23.string(),
12270
12333
  sources: SectionReportSourcesSchema,
12271
12334
  extraction: SectionReportExtractionSchema,
12272
12335
  contradictions: SectionReportContradictionsSchema,
12273
12336
  review: SectionReportReviewSchema,
12274
12337
  acceptance: SectionReportAcceptanceSchema,
12275
- gate_verdict: z22.string().nullable(),
12276
- gate_synthesis_eligible: z22.boolean().nullable()
12338
+ gate_verdict: z23.string().nullable(),
12339
+ gate_synthesis_eligible: z23.boolean().nullable()
12277
12340
  });
12278
12341
  }
12279
12342
  });
@@ -12636,7 +12699,7 @@ import { createHash as createHash11 } from "crypto";
12636
12699
  import { readFileSync, existsSync as existsSync29 } from "fs";
12637
12700
  import { join as join29 } from "path";
12638
12701
  import { parse as parseYaml } from "yaml";
12639
- import { z as z24 } from "zod";
12702
+ import { z as z25 } from "zod";
12640
12703
 
12641
12704
  // src/closure-ledger/effective-accepted.ts
12642
12705
  function getEffectiveDecisionMap(reviews) {
@@ -12681,38 +12744,38 @@ function findIncompatibleDecisions(reviews) {
12681
12744
  }
12682
12745
 
12683
12746
  // src/pack/publish/schema.ts
12684
- import { z as z23 } from "zod";
12685
- var SectionSummarySchema = z23.object({
12686
- id: z23.string().min(1),
12687
- accepted_claims: z23.number().int().min(0),
12688
- gate: z23.enum(["pass", "warn", "fail", "blocked", "pass_with_waiver"]),
12689
- synthesis_eligible: z23.boolean()
12690
- });
12691
- var TotalsSchema = z23.object({
12692
- sections: z23.number().int().min(1),
12693
- accepted_claims: z23.number().int().min(0),
12694
- dispositioned: z23.number().int().min(0),
12695
- unresolved_contradictions: z23.number().int().min(0),
12696
- preserved_contradiction_records: z23.number().int().min(0).optional()
12697
- });
12698
- var PackManifestSchema = z23.object({
12699
- name: z23.string().min(1),
12700
- topic: z23.string().min(1),
12701
- frozen_at: z23.string().datetime(),
12702
- research_os_version: z23.string().min(1),
12703
- sections: z23.array(SectionSummarySchema).min(1),
12747
+ import { z as z24 } from "zod";
12748
+ var SectionSummarySchema = z24.object({
12749
+ id: z24.string().min(1),
12750
+ accepted_claims: z24.number().int().min(0),
12751
+ gate: z24.enum(["pass", "warn", "fail", "blocked", "pass_with_waiver"]),
12752
+ synthesis_eligible: z24.boolean()
12753
+ });
12754
+ var TotalsSchema = z24.object({
12755
+ sections: z24.number().int().min(1),
12756
+ accepted_claims: z24.number().int().min(0),
12757
+ dispositioned: z24.number().int().min(0),
12758
+ unresolved_contradictions: z24.number().int().min(0),
12759
+ preserved_contradiction_records: z24.number().int().min(0).optional()
12760
+ });
12761
+ var PackManifestSchema = z24.object({
12762
+ name: z24.string().min(1),
12763
+ topic: z24.string().min(1),
12764
+ frozen_at: z24.string().datetime(),
12765
+ research_os_version: z24.string().min(1),
12766
+ sections: z24.array(SectionSummarySchema).min(1),
12704
12767
  totals: TotalsSchema,
12705
- freeze_receipt_sha256: z23.string().regex(/^[a-f0-9]{64}$/, "Must be a 64-char hex sha256"),
12706
- operator_notes: z23.string().default("")
12768
+ freeze_receipt_sha256: z24.string().regex(/^[a-f0-9]{64}$/, "Must be a 64-char hex sha256"),
12769
+ operator_notes: z24.string().default("")
12707
12770
  });
12708
12771
 
12709
12772
  // src/pack/publish/manifest.ts
12710
12773
  init_src();
12711
- var GateResultMinimalSchema = z24.object({
12712
- verdict: z24.enum(["pass", "warn", "fail", "blocked"]),
12713
- synthesis_eligible: z24.boolean()
12774
+ var GateResultMinimalSchema = z25.object({
12775
+ verdict: z25.enum(["pass", "warn", "fail", "blocked"]),
12776
+ synthesis_eligible: z25.boolean()
12714
12777
  });
12715
- var ClaimIdOnlySchema = z24.object({ claim_id: z24.string() });
12778
+ var ClaimIdOnlySchema = z25.object({ claim_id: z25.string() });
12716
12779
  function sha256Bytes(buf) {
12717
12780
  return createHash11("sha256").update(buf).digest("hex");
12718
12781
  }
@@ -13406,6 +13469,117 @@ async function applySourceCardOverrides(packPath, fromFile) {
13406
13469
  // src/cli.ts
13407
13470
  init_errors();
13408
13471
  init_src();
13472
+
13473
+ // src/calibration/lookup.ts
13474
+ import { existsSync as existsSync33 } from "fs";
13475
+ import { readFile as readFile26 } from "fs/promises";
13476
+ import { join as join34 } from "path";
13477
+
13478
+ // src/calibration/receipt-schema.ts
13479
+ init_reviewer_options_schema();
13480
+ import { z as z26 } from "zod";
13481
+ var StatusLabelSchema = z26.enum([
13482
+ "trusted_baseline",
13483
+ "conditional_pass",
13484
+ "failed",
13485
+ "comparison_only"
13486
+ ]);
13487
+ var ArchitectureSchema = z26.enum(["single-pass", "two-pass"]);
13488
+ var RecallSchema = z26.object({
13489
+ matched: z26.number().int().nonnegative(),
13490
+ total: z26.number().int().nonnegative(),
13491
+ ratio: z26.number().min(0).max(1)
13492
+ });
13493
+ var PerCategoryRecallSchema = z26.record(z26.string(), RecallSchema);
13494
+ var PassFailSchema = z26.object({
13495
+ fp_ceiling: z26.enum(["PASS", "FAIL"]),
13496
+ any_flag_recall_floor: z26.enum(["PASS", "FAIL"]),
13497
+ per_category_any_flag_floor: z26.enum(["PASS", "FAIL"]),
13498
+ strict_recall_floor: z26.enum(["PASS", "FAIL"]),
13499
+ decision_vocab_completeness: z26.enum(["PASS", "FAIL"]),
13500
+ latency_soft: z26.enum(["PASS", "WARN"]),
13501
+ latency_hard: z26.enum(["PASS", "FAIL"]),
13502
+ empty_or_malformed: z26.enum(["PASS", "FAIL"]),
13503
+ overall: z26.enum(["PASS", "FAIL"])
13504
+ });
13505
+ var DecisionVocabBarSchema = z26.object({
13506
+ architecture: ArchitectureSchema,
13507
+ required: z26.number().int().positive(),
13508
+ produced: z26.number().int().nonnegative(),
13509
+ passed: z26.boolean()
13510
+ });
13511
+ var CalibrationReceiptSchema = z26.object({
13512
+ schema_version: z26.literal(1),
13513
+ profile_name: z26.string(),
13514
+ status: StatusLabelSchema,
13515
+ model: z26.string(),
13516
+ architecture: ArchitectureSchema,
13517
+ fixture: z26.string(),
13518
+ fixture_total_claims: z26.number().int().positive(),
13519
+ fixture_good_claims: z26.number().int().nonnegative(),
13520
+ fixture_bad_claims: z26.number().int().nonnegative(),
13521
+ calibrated_at: z26.string(),
13522
+ research_os_version: z26.string(),
13523
+ runtime_ms: z26.number().int().nonnegative(),
13524
+ good_fp_count: z26.number().int().nonnegative(),
13525
+ any_flag_recall: RecallSchema,
13526
+ strict_recall: RecallSchema,
13527
+ per_category_any_flag: PerCategoryRecallSchema,
13528
+ per_category_strict: PerCategoryRecallSchema,
13529
+ decision_vocabulary: z26.record(z26.string(), z26.number().int().nonnegative()),
13530
+ decisions_produced_count: z26.number().int().nonnegative(),
13531
+ decision_vocab_bar: DecisionVocabBarSchema,
13532
+ unreachable_decisions: z26.array(z26.string()),
13533
+ empty_or_malformed_responses: z26.number().int().nonnegative(),
13534
+ pass_fail: PassFailSchema,
13535
+ notes: z26.array(z26.string()),
13536
+ reviewer_options: ReviewerOptionsSchema.optional()
13537
+ });
13538
+
13539
+ // src/calibration/receipt.ts
13540
+ function receiptToCalibrationSummary(receipt) {
13541
+ const fp = receipt.good_fp_count;
13542
+ const fpTotal = receipt.fixture_good_claims;
13543
+ const fpPct = fpTotal > 0 ? Math.round(fp / fpTotal * 100) : 0;
13544
+ const af = receipt.any_flag_recall;
13545
+ const sr = receipt.strict_recall;
13546
+ const unsupported = receipt.per_category_any_flag["unsupported_claim"];
13547
+ return {
13548
+ fixture: receipt.fixture,
13549
+ good_false_positive_rate: `${fp}/${fpTotal} (${fpPct}%)`,
13550
+ bad_any_flag_recall: `${af.matched}/${af.total} (${Math.round(af.ratio * 100)}%)`,
13551
+ strict_category_recall: `${sr.matched}/${sr.total} (${Math.round(sr.ratio * 100)}%)`,
13552
+ unsupported_claim_recall: unsupported ? `${unsupported.matched}/${unsupported.total} (${Math.round(unsupported.ratio * 100)}%)` : null,
13553
+ notes: `status=${receipt.status} model=${receipt.model} arch=${receipt.architecture} overall=${receipt.pass_fail.overall} decisions=${receipt.decisions_produced_count}/6`
13554
+ };
13555
+ }
13556
+
13557
+ // src/calibration/lookup.ts
13558
+ async function loadReceiptForPack(packDir, profile) {
13559
+ const receiptPath = receiptPathForPack(packDir, profile);
13560
+ if (!existsSync33(receiptPath)) return null;
13561
+ let raw;
13562
+ try {
13563
+ raw = JSON.parse(await readFile26(receiptPath, "utf8"));
13564
+ } catch (err) {
13565
+ throw new Error(
13566
+ `Invalid calibration receipt at ${receiptPath}: ${err.message}`,
13567
+ { cause: err }
13568
+ );
13569
+ }
13570
+ const result = CalibrationReceiptSchema.safeParse(raw);
13571
+ if (!result.success) {
13572
+ throw new Error(
13573
+ `Invalid calibration receipt at ${receiptPath}: ${result.error.message}`
13574
+ );
13575
+ }
13576
+ return receiptToCalibrationSummary(result.data);
13577
+ }
13578
+ function receiptPathForPack(packDir, profile) {
13579
+ return join34(packDir, "calibration", "reviewer-profiles", profile, "seeded-v1.json");
13580
+ }
13581
+
13582
+ // src/cli.ts
13409
13583
  function reportError(err) {
13410
13584
  if (err instanceof ResearchOSError) {
13411
13585
  process.stderr.write(`research-os: ${err.code}: ${err.message}
@@ -14020,22 +14194,26 @@ program.command("review").description("Run the adversarial reviewer pass; emits
14020
14194
  const criticModel = opts.criticModel ?? baseModel ?? preset?.critic_model ?? void 0;
14021
14195
  const reviewWindow = opts.reviewWindow ?? preset?.review_window ?? void 0;
14022
14196
  const twoPass = Boolean(opts.twoPassLlm) || (preset?.mode === "two_pass" ? true : false);
14197
+ const reviewerOptions = preset?.reviewer_options ?? void 0;
14023
14198
  const reviewers = opts.heuristicOnly ? [new HeuristicReviewer()] : twoPass ? [
14024
14199
  new OllamaInternReviewer({
14025
14200
  mode: "general",
14026
14201
  model: generalModel ?? void 0,
14027
- claimsPerWindow: reviewWindow
14202
+ claimsPerWindow: reviewWindow,
14203
+ reviewer_options: reviewerOptions
14028
14204
  }),
14029
14205
  new OllamaInternReviewer({
14030
14206
  mode: "narrow_critic",
14031
14207
  model: criticModel ?? void 0,
14032
- claimsPerWindow: reviewWindow
14208
+ claimsPerWindow: reviewWindow,
14209
+ reviewer_options: reviewerOptions
14033
14210
  }),
14034
14211
  new HeuristicReviewer()
14035
14212
  ] : reviewWindow || opts.llmPaged || baseModel || generalModel ? [
14036
14213
  new OllamaInternReviewer({
14037
14214
  model: generalModel ?? void 0,
14038
- claimsPerWindow: reviewWindow
14215
+ claimsPerWindow: reviewWindow,
14216
+ reviewer_options: reviewerOptions
14039
14217
  }),
14040
14218
  new HeuristicReviewer()
14041
14219
  ] : void 0;
@@ -14045,7 +14223,8 @@ program.command("review").description("Run the adversarial reviewer pass; emits
14045
14223
  reviewers,
14046
14224
  triagedOnly: opts.triagedOnly,
14047
14225
  multiPass: twoPass,
14048
- profile: opts.profile
14226
+ profile: opts.profile,
14227
+ reviewer_options: reviewerOptions
14049
14228
  });
14050
14229
  process.stdout.write(`review complete
14051
14230
  `);
@@ -14435,7 +14614,8 @@ program.command("review-promote").description(
14435
14614
  false
14436
14615
  ).action(async (section, opts) => {
14437
14616
  try {
14438
- const calibration = opts.calibrationFixture || opts.goodFp || opts.anyFlagRecall || opts.strictCatRecall || opts.unsupportedRecall || opts.calibrationNotes ? {
14617
+ const explicitCalibration = opts.calibrationFixture || opts.goodFp || opts.anyFlagRecall || opts.strictCatRecall || opts.unsupportedRecall || opts.calibrationNotes;
14618
+ let calibration = explicitCalibration ? {
14439
14619
  fixture: opts.calibrationFixture ?? null,
14440
14620
  good_false_positive_rate: opts.goodFp ?? null,
14441
14621
  bad_any_flag_recall: opts.anyFlagRecall ?? null,
@@ -14443,6 +14623,16 @@ program.command("review-promote").description(
14443
14623
  unsupported_claim_recall: opts.unsupportedRecall ?? null,
14444
14624
  notes: opts.calibrationNotes ?? null
14445
14625
  } : null;
14626
+ if (!explicitCalibration) {
14627
+ const summary = await loadReceiptForPack(opts.pack, opts.profile);
14628
+ if (summary !== null) {
14629
+ calibration = summary;
14630
+ process.stdout.write(
14631
+ ` [auto] calibration_summary populated from ${receiptPathForPack(opts.pack, opts.profile)}
14632
+ `
14633
+ );
14634
+ }
14635
+ }
14446
14636
  const result = await promote({
14447
14637
  sectionId: section,
14448
14638
  packPath: opts.pack,