onto-mcp 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/.onto/authority/core-lens-registry.yaml +134 -0
  2. package/.onto/authority/core-lexicon.yaml +1562 -0
  3. package/.onto/authority/diagnostic-codes.yaml +94 -0
  4. package/.onto/domains/accounting/competency_qs.md +384 -0
  5. package/.onto/domains/accounting/concepts.md +186 -0
  6. package/.onto/domains/accounting/conciseness_rules.md +160 -0
  7. package/.onto/domains/accounting/dependency_rules.md +239 -0
  8. package/.onto/domains/accounting/domain_scope.md +213 -0
  9. package/.onto/domains/accounting/extension_cases.md +416 -0
  10. package/.onto/domains/accounting/logic_rules.md +226 -0
  11. package/.onto/domains/accounting/structure_spec.md +298 -0
  12. package/.onto/domains/accounting-kr/competency_qs.md +562 -0
  13. package/.onto/domains/accounting-kr/concepts.md +187 -0
  14. package/.onto/domains/accounting-kr/conciseness_rules.md +125 -0
  15. package/.onto/domains/accounting-kr/dependency_rules.md +93 -0
  16. package/.onto/domains/accounting-kr/domain_scope.md +140 -0
  17. package/.onto/domains/accounting-kr/extension_cases.md +343 -0
  18. package/.onto/domains/accounting-kr/logic_rules.md +160 -0
  19. package/.onto/domains/accounting-kr/structure_spec.md +85 -0
  20. package/.onto/domains/business/competency_qs.md +263 -0
  21. package/.onto/domains/business/concepts.md +200 -0
  22. package/.onto/domains/business/conciseness_rules.md +135 -0
  23. package/.onto/domains/business/dependency_rules.md +113 -0
  24. package/.onto/domains/business/domain_scope.md +240 -0
  25. package/.onto/domains/business/extension_cases.md +249 -0
  26. package/.onto/domains/business/logic_rules.md +134 -0
  27. package/.onto/domains/business/structure_spec.md +114 -0
  28. package/.onto/domains/finance/competency_qs.md +362 -0
  29. package/.onto/domains/finance/concepts.md +194 -0
  30. package/.onto/domains/finance/conciseness_rules.md +155 -0
  31. package/.onto/domains/finance/dependency_rules.md +171 -0
  32. package/.onto/domains/finance/domain_scope.md +215 -0
  33. package/.onto/domains/finance/extension_cases.md +350 -0
  34. package/.onto/domains/finance/logic_rules.md +191 -0
  35. package/.onto/domains/finance/structure_spec.md +182 -0
  36. package/.onto/domains/llm-native-development/competency_qs.md +430 -0
  37. package/.onto/domains/llm-native-development/concepts.md +242 -0
  38. package/.onto/domains/llm-native-development/conciseness_rules.md +163 -0
  39. package/.onto/domains/llm-native-development/dependency_rules.md +216 -0
  40. package/.onto/domains/llm-native-development/domain_scope.md +197 -0
  41. package/.onto/domains/llm-native-development/extension_cases.md +474 -0
  42. package/.onto/domains/llm-native-development/logic_rules.md +123 -0
  43. package/.onto/domains/llm-native-development/prompt_interface.md +49 -0
  44. package/.onto/domains/llm-native-development/structure_spec.md +245 -0
  45. package/.onto/domains/market-intelligence/competency_qs.md +274 -0
  46. package/.onto/domains/market-intelligence/concepts.md +233 -0
  47. package/.onto/domains/market-intelligence/conciseness_rules.md +165 -0
  48. package/.onto/domains/market-intelligence/dependency_rules.md +197 -0
  49. package/.onto/domains/market-intelligence/domain_scope.md +231 -0
  50. package/.onto/domains/market-intelligence/extension_cases.md +425 -0
  51. package/.onto/domains/market-intelligence/logic_rules.md +247 -0
  52. package/.onto/domains/market-intelligence/structure_spec.md +209 -0
  53. package/.onto/domains/ontology/competency_qs.md +394 -0
  54. package/.onto/domains/ontology/concepts.md +172 -0
  55. package/.onto/domains/ontology/conciseness_rules.md +134 -0
  56. package/.onto/domains/ontology/dependency_rules.md +125 -0
  57. package/.onto/domains/ontology/domain_scope.md +114 -0
  58. package/.onto/domains/ontology/extension_cases.md +501 -0
  59. package/.onto/domains/ontology/logic_rules.md +114 -0
  60. package/.onto/domains/ontology/problem_framing_profile.md +67 -0
  61. package/.onto/domains/ontology/structure_spec.md +115 -0
  62. package/.onto/domains/palantir-foundry/RESEARCH_NOTES.md +911 -0
  63. package/.onto/domains/palantir-foundry/competency_qs.md +191 -0
  64. package/.onto/domains/palantir-foundry/competitive_comparison.md +329 -0
  65. package/.onto/domains/palantir-foundry/concepts.md +197 -0
  66. package/.onto/domains/palantir-foundry/conciseness_rules.md +245 -0
  67. package/.onto/domains/palantir-foundry/dependency_rules.md +135 -0
  68. package/.onto/domains/palantir-foundry/domain_scope.md +395 -0
  69. package/.onto/domains/palantir-foundry/extension_cases.md +210 -0
  70. package/.onto/domains/palantir-foundry/logic_rules.md +172 -0
  71. package/.onto/domains/palantir-foundry/structure_spec.md +291 -0
  72. package/.onto/domains/software-engineering/competency_qs.md +538 -0
  73. package/.onto/domains/software-engineering/concepts.md +238 -0
  74. package/.onto/domains/software-engineering/conciseness_rules.md +167 -0
  75. package/.onto/domains/software-engineering/dependency_rules.md +216 -0
  76. package/.onto/domains/software-engineering/domain_scope.md +183 -0
  77. package/.onto/domains/software-engineering/extension_cases.md +551 -0
  78. package/.onto/domains/software-engineering/logic_rules.md +240 -0
  79. package/.onto/domains/software-engineering/problem_framing_profile.md +68 -0
  80. package/.onto/domains/software-engineering/structure_spec.md +185 -0
  81. package/.onto/domains/ui-design/competency_qs.md +567 -0
  82. package/.onto/domains/ui-design/concepts.md +194 -0
  83. package/.onto/domains/ui-design/conciseness_rules.md +190 -0
  84. package/.onto/domains/ui-design/dependency_rules.md +323 -0
  85. package/.onto/domains/ui-design/domain_scope.md +340 -0
  86. package/.onto/domains/ui-design/extension_cases.md +563 -0
  87. package/.onto/domains/ui-design/logic_rules.md +349 -0
  88. package/.onto/domains/ui-design/structure_spec.md +252 -0
  89. package/.onto/domains/visual-design/competency_qs.md +472 -0
  90. package/.onto/domains/visual-design/concepts.md +147 -0
  91. package/.onto/domains/visual-design/conciseness_rules.md +186 -0
  92. package/.onto/domains/visual-design/dependency_rules.md +282 -0
  93. package/.onto/domains/visual-design/domain_scope.md +290 -0
  94. package/.onto/domains/visual-design/extension_cases.md +480 -0
  95. package/.onto/domains/visual-design/logic_rules.md +232 -0
  96. package/.onto/domains/visual-design/structure_spec.md +213 -0
  97. package/.onto/principles/llm-native-development-guideline.md +401 -0
  98. package/.onto/principles/llm-runtime-interface-principles.md +665 -0
  99. package/.onto/principles/non-specialist-communication-guideline.md +74 -0
  100. package/.onto/principles/ontology-as-code-guideline.md +243 -0
  101. package/.onto/principles/ontology-as-code-naming-charter.md +130 -0
  102. package/.onto/principles/product-locality-principle.md +129 -0
  103. package/.onto/principles/productization-charter.md +569 -0
  104. package/.onto/processes/evolve/material-kind-adapter-contract.md +113 -0
  105. package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +366 -0
  106. package/.onto/processes/reconstruct/source-profile-contract.md +107 -0
  107. package/.onto/processes/reconstruct/source-profiles/code.md +72 -0
  108. package/.onto/processes/reconstruct/source-profiles/database.md +74 -0
  109. package/.onto/processes/reconstruct/source-profiles/document.md +71 -0
  110. package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +79 -0
  111. package/.onto/processes/review/binding-contract.md +270 -0
  112. package/.onto/processes/review/execution-preparation-artifacts.md +281 -0
  113. package/.onto/processes/review/interpretation-contract.md +245 -0
  114. package/.onto/processes/review/issue-stance-deliberation-contract.md +761 -0
  115. package/.onto/processes/review/lens-prompt-contract.md +402 -0
  116. package/.onto/processes/review/lens-registry.md +127 -0
  117. package/.onto/processes/review/pre-dispatch-contracts.md +428 -0
  118. package/.onto/processes/review/productized-live-path.md +398 -0
  119. package/.onto/processes/review/prompt-execution-runner-contract.md +187 -0
  120. package/.onto/processes/review/record-contract.md +427 -0
  121. package/.onto/processes/review/record-field-mapping.md +337 -0
  122. package/.onto/processes/review/review-context-manifest-contract.md +356 -0
  123. package/.onto/processes/review/review-execution-ux-contract.md +809 -0
  124. package/.onto/processes/review/review-target-profile-contract.md +259 -0
  125. package/.onto/processes/review/shared-phenomenon-contract.md +129 -0
  126. package/.onto/processes/review/synthesize-prompt-contract.md +343 -0
  127. package/.onto/processes/shared/target-material-kind-contract.md +198 -0
  128. package/.onto/roles/axiology.md +81 -0
  129. package/.onto/roles/conciseness.md +36 -0
  130. package/.onto/roles/coverage.md +34 -0
  131. package/.onto/roles/dependency.md +37 -0
  132. package/.onto/roles/evolution.md +35 -0
  133. package/.onto/roles/logic.md +104 -0
  134. package/.onto/roles/pragmatics.md +32 -0
  135. package/.onto/roles/semantics.md +36 -0
  136. package/.onto/roles/structure.md +33 -0
  137. package/.onto/roles/synthesize.md +92 -0
  138. package/AGENTS.md +240 -0
  139. package/CLAUDE.md +39 -0
  140. package/README.md +287 -0
  141. package/bin/onto +92 -0
  142. package/dist/cli.js +101 -0
  143. package/dist/core-api/reconstruct-api.js +222 -0
  144. package/dist/core-api/review-api.js +1271 -0
  145. package/dist/core-runtime/cli/assemble-review-record.js +431 -0
  146. package/dist/core-runtime/cli/bootstrap-review-binding.js +186 -0
  147. package/dist/core-runtime/cli/codex-nested-dispatch.js +226 -0
  148. package/dist/core-runtime/cli/codex-nested-dispatch.test.js +390 -0
  149. package/dist/core-runtime/cli/codex-nested-teamlead-executor.js +464 -0
  150. package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +335 -0
  151. package/dist/core-runtime/cli/codex-review-unit-executor.js +228 -0
  152. package/dist/core-runtime/cli/complete-review-session.js +64 -0
  153. package/dist/core-runtime/cli/complexity-assessment.js +153 -0
  154. package/dist/core-runtime/cli/coordinator-helpers.js +583 -0
  155. package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +167 -0
  156. package/dist/core-runtime/cli/coordinator-state-machine.js +794 -0
  157. package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +615 -0
  158. package/dist/core-runtime/cli/e2e-start-review-session.test.js +312 -0
  159. package/dist/core-runtime/cli/health.js +44 -0
  160. package/dist/core-runtime/cli/inline-http-review-unit-executor.js +656 -0
  161. package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +567 -0
  162. package/dist/core-runtime/cli/materialize-review-execution-preparation.js +104 -0
  163. package/dist/core-runtime/cli/materialize-review-prompt-packets.js +952 -0
  164. package/dist/core-runtime/cli/migrate-session-roots.js +118 -0
  165. package/dist/core-runtime/cli/mock-review-unit-executor.js +285 -0
  166. package/dist/core-runtime/cli/onto-tools.js +369 -0
  167. package/dist/core-runtime/cli/prepare-review-session.js +272 -0
  168. package/dist/core-runtime/cli/render-review-final-output.js +350 -0
  169. package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +106 -0
  170. package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +268 -0
  171. package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +136 -0
  172. package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +201 -0
  173. package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +192 -0
  174. package/dist/core-runtime/cli/review-invoke.js +2030 -0
  175. package/dist/core-runtime/cli/run-review-prompt-execution.js +2152 -0
  176. package/dist/core-runtime/cli/session-root-guard.js +168 -0
  177. package/dist/core-runtime/cli/spawn-watcher.js +173 -0
  178. package/dist/core-runtime/cli/spawn-watcher.test.js +457 -0
  179. package/dist/core-runtime/cli/start-review-session.js +68 -0
  180. package/dist/core-runtime/cli/strip-wrapping-code-fence.js +56 -0
  181. package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +79 -0
  182. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +412 -0
  183. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +351 -0
  184. package/dist/core-runtime/cli/topology-executor-mapping.js +139 -0
  185. package/dist/core-runtime/cli/topology-executor-mapping.test.js +173 -0
  186. package/dist/core-runtime/cli/write-review-interpretation.js +81 -0
  187. package/dist/core-runtime/config/onto-config-cli.js +278 -0
  188. package/dist/core-runtime/config/onto-config-key-path.js +288 -0
  189. package/dist/core-runtime/config/onto-config-key-path.test.js +195 -0
  190. package/dist/core-runtime/config/onto-config-preview.js +108 -0
  191. package/dist/core-runtime/config/onto-config-preview.test.js +132 -0
  192. package/dist/core-runtime/discovery/config-chain.js +118 -0
  193. package/dist/core-runtime/discovery/config-chain.test.js +103 -0
  194. package/dist/core-runtime/discovery/config-profile.js +199 -0
  195. package/dist/core-runtime/discovery/config-profile.test.js +233 -0
  196. package/dist/core-runtime/discovery/host-detection.js +33 -0
  197. package/dist/core-runtime/discovery/host-detection.test.js +186 -0
  198. package/dist/core-runtime/discovery/installation-paths.js +21 -0
  199. package/dist/core-runtime/discovery/installation-paths.test.js +65 -0
  200. package/dist/core-runtime/discovery/lens-registry.js +60 -0
  201. package/dist/core-runtime/discovery/lens-registry.test.js +81 -0
  202. package/dist/core-runtime/discovery/onto-home.js +71 -0
  203. package/dist/core-runtime/discovery/path-normalization.js +28 -0
  204. package/dist/core-runtime/discovery/path-normalization.test.js +22 -0
  205. package/dist/core-runtime/discovery/plugin-path.js +72 -0
  206. package/dist/core-runtime/discovery/plugin-path.test.js +95 -0
  207. package/dist/core-runtime/discovery/project-root.js +47 -0
  208. package/dist/core-runtime/discovery/settings-chain.js +353 -0
  209. package/dist/core-runtime/discovery/walk-up.js +17 -0
  210. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +344 -0
  211. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +915 -0
  212. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +564 -0
  213. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +708 -0
  214. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +165 -0
  215. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +227 -0
  216. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +59 -0
  217. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +205 -0
  218. package/dist/core-runtime/evolve/adapters/methodology/adapter.js +16 -0
  219. package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +9 -0
  220. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +298 -0
  221. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +70 -0
  222. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +46 -0
  223. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +73 -0
  224. package/dist/core-runtime/evolve/adapters/registry.js +47 -0
  225. package/dist/core-runtime/evolve/adapters/registry.test.js +67 -0
  226. package/dist/core-runtime/evolve/cli.js +256 -0
  227. package/dist/core-runtime/evolve/commands/align.js +194 -0
  228. package/dist/core-runtime/evolve/commands/align.test.js +82 -0
  229. package/dist/core-runtime/evolve/commands/apply.js +161 -0
  230. package/dist/core-runtime/evolve/commands/apply.test.js +138 -0
  231. package/dist/core-runtime/evolve/commands/close.js +39 -0
  232. package/dist/core-runtime/evolve/commands/close.test.js +99 -0
  233. package/dist/core-runtime/evolve/commands/defer.js +40 -0
  234. package/dist/core-runtime/evolve/commands/defer.test.js +134 -0
  235. package/dist/core-runtime/evolve/commands/draft.js +323 -0
  236. package/dist/core-runtime/evolve/commands/draft.test.js +178 -0
  237. package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +208 -0
  238. package/dist/core-runtime/evolve/commands/error-messages.js +125 -0
  239. package/dist/core-runtime/evolve/commands/error-messages.test.js +167 -0
  240. package/dist/core-runtime/evolve/commands/propose-align.js +222 -0
  241. package/dist/core-runtime/evolve/commands/propose-align.test.js +136 -0
  242. package/dist/core-runtime/evolve/commands/reconstruct.js +330 -0
  243. package/dist/core-runtime/evolve/commands/reconstruct.test.js +278 -0
  244. package/dist/core-runtime/evolve/commands/shared.js +22 -0
  245. package/dist/core-runtime/evolve/commands/stale-check.js +103 -0
  246. package/dist/core-runtime/evolve/commands/stale-check.test.js +84 -0
  247. package/dist/core-runtime/evolve/commands/start.js +887 -0
  248. package/dist/core-runtime/evolve/commands/start.test.js +396 -0
  249. package/dist/core-runtime/evolve/config/project-config.js +99 -0
  250. package/dist/core-runtime/evolve/config/project-config.test.js +170 -0
  251. package/dist/core-runtime/evolve/renderers/align-packet.js +280 -0
  252. package/dist/core-runtime/evolve/renderers/align-packet.test.js +332 -0
  253. package/dist/core-runtime/evolve/renderers/draft-packet.js +303 -0
  254. package/dist/core-runtime/evolve/renderers/draft-packet.test.js +377 -0
  255. package/dist/core-runtime/evolve/renderers/format.js +5 -0
  256. package/dist/core-runtime/evolve/renderers/scope-md.js +237 -0
  257. package/dist/core-runtime/evolve/renderers/scope-md.test.js +306 -0
  258. package/dist/core-runtime/govern/cli.js +369 -0
  259. package/dist/core-runtime/govern/cli.test.js +314 -0
  260. package/dist/core-runtime/govern/drift-engine.js +103 -0
  261. package/dist/core-runtime/govern/drift-engine.test.js +319 -0
  262. package/dist/core-runtime/govern/promote-principle.js +206 -0
  263. package/dist/core-runtime/govern/promote-principle.test.js +368 -0
  264. package/dist/core-runtime/govern/queue.js +81 -0
  265. package/dist/core-runtime/govern/types.js +16 -0
  266. package/dist/core-runtime/install/cli.js +530 -0
  267. package/dist/core-runtime/install/detect.js +128 -0
  268. package/dist/core-runtime/install/detect.test.js +155 -0
  269. package/dist/core-runtime/install/gitignore-update.js +74 -0
  270. package/dist/core-runtime/install/gitignore-update.test.js +64 -0
  271. package/dist/core-runtime/install/install-integration.test.js +373 -0
  272. package/dist/core-runtime/install/prompts.js +389 -0
  273. package/dist/core-runtime/install/prompts.test.js +293 -0
  274. package/dist/core-runtime/install/types.js +26 -0
  275. package/dist/core-runtime/install/validation.js +295 -0
  276. package/dist/core-runtime/install/validation.test.js +313 -0
  277. package/dist/core-runtime/install/writer.js +254 -0
  278. package/dist/core-runtime/install/writer.test.js +218 -0
  279. package/dist/core-runtime/learning/extractor.js +461 -0
  280. package/dist/core-runtime/learning/feedback.js +179 -0
  281. package/dist/core-runtime/learning/health-report.js +165 -0
  282. package/dist/core-runtime/learning/health-report.test.js +169 -0
  283. package/dist/core-runtime/learning/loader.js +388 -0
  284. package/dist/core-runtime/learning/loader.test.js +102 -0
  285. package/dist/core-runtime/learning/promote/apply-state.js +240 -0
  286. package/dist/core-runtime/learning/promote/audit-obligation.js +195 -0
  287. package/dist/core-runtime/learning/promote/collector.js +432 -0
  288. package/dist/core-runtime/learning/promote/degraded-state.js +125 -0
  289. package/dist/core-runtime/learning/promote/domain-doc-proposer.js +166 -0
  290. package/dist/core-runtime/learning/promote/e2e-promote.test.js +6385 -0
  291. package/dist/core-runtime/learning/promote/health-snapshot.js +150 -0
  292. package/dist/core-runtime/learning/promote/insight-reclassifier.js +544 -0
  293. package/dist/core-runtime/learning/promote/judgment-auditor.js +517 -0
  294. package/dist/core-runtime/learning/promote/panel-reviewer.js +1158 -0
  295. package/dist/core-runtime/learning/promote/promote-executor.js +1675 -0
  296. package/dist/core-runtime/learning/promote/promoter.js +307 -0
  297. package/dist/core-runtime/learning/promote/retirement.js +122 -0
  298. package/dist/core-runtime/learning/promote/types.js +23 -0
  299. package/dist/core-runtime/learning/prompt-sections.js +51 -0
  300. package/dist/core-runtime/learning/shared/artifact-registry-init.js +45 -0
  301. package/dist/core-runtime/learning/shared/artifact-registry.js +254 -0
  302. package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +73 -0
  303. package/dist/core-runtime/learning/shared/audit-state.js +99 -0
  304. package/dist/core-runtime/learning/shared/duplicate-check.js +28 -0
  305. package/dist/core-runtime/learning/shared/llm-caller.js +831 -0
  306. package/dist/core-runtime/learning/shared/llm-caller.test.js +601 -0
  307. package/dist/core-runtime/learning/shared/llm-tool-loop.js +393 -0
  308. package/dist/core-runtime/learning/shared/mode.js +25 -0
  309. package/dist/core-runtime/learning/shared/paths.js +84 -0
  310. package/dist/core-runtime/learning/shared/paths.test.js +79 -0
  311. package/dist/core-runtime/learning/shared/patterns.js +37 -0
  312. package/dist/core-runtime/learning/shared/recoverability.js +355 -0
  313. package/dist/core-runtime/learning/shared/recovery-context.js +374 -0
  314. package/dist/core-runtime/learning/shared/scope.js +1 -0
  315. package/dist/core-runtime/learning/shared/semantic-classifier.js +94 -0
  316. package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +42 -0
  317. package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +37 -0
  318. package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +39 -0
  319. package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +41 -0
  320. package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +38 -0
  321. package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +43 -0
  322. package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +113 -0
  323. package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +36 -0
  324. package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +48 -0
  325. package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +43 -0
  326. package/dist/core-runtime/learning/shared/specs/spec-helpers.js +64 -0
  327. package/dist/core-runtime/learning/usage-tracker.js +190 -0
  328. package/dist/core-runtime/learning/usage-tracker.test.js +176 -0
  329. package/dist/core-runtime/llm/llm-caller.js +649 -0
  330. package/dist/core-runtime/llm/llm-tool-loop.js +401 -0
  331. package/dist/core-runtime/llm/model-switcher.js +62 -0
  332. package/dist/core-runtime/logger.js +22 -0
  333. package/dist/core-runtime/onboard/detect-review-axes.js +122 -0
  334. package/dist/core-runtime/onboard/detect-review-axes.test.js +127 -0
  335. package/dist/core-runtime/onboard/write-review-block.js +188 -0
  336. package/dist/core-runtime/onboard/write-review-block.test.js +240 -0
  337. package/dist/core-runtime/readers/brownfield-builder.js +150 -0
  338. package/dist/core-runtime/readers/brownfield-builder.test.js +136 -0
  339. package/dist/core-runtime/readers/code-chunk-collector.js +53 -0
  340. package/dist/core-runtime/readers/code-chunk-collector.test.js +136 -0
  341. package/dist/core-runtime/readers/file-utils.js +240 -0
  342. package/dist/core-runtime/readers/file-utils.test.js +146 -0
  343. package/dist/core-runtime/readers/lexicon-citation-check.js +93 -0
  344. package/dist/core-runtime/readers/lexicon-citation-check.test.js +77 -0
  345. package/dist/core-runtime/readers/mcp-figma.js +30 -0
  346. package/dist/core-runtime/readers/mcp-figma.test.js +82 -0
  347. package/dist/core-runtime/readers/mcp-generic.js +31 -0
  348. package/dist/core-runtime/readers/mcp-generic.test.js +76 -0
  349. package/dist/core-runtime/readers/ontology-index.js +148 -0
  350. package/dist/core-runtime/readers/ontology-index.test.js +245 -0
  351. package/dist/core-runtime/readers/ontology-query.js +168 -0
  352. package/dist/core-runtime/readers/ontology-query.test.js +311 -0
  353. package/dist/core-runtime/readers/ontology-resolve.js +48 -0
  354. package/dist/core-runtime/readers/ontology-resolve.test.js +48 -0
  355. package/dist/core-runtime/readers/patterns/index.js +7 -0
  356. package/dist/core-runtime/readers/review-log.js +213 -0
  357. package/dist/core-runtime/readers/review-log.test.js +313 -0
  358. package/dist/core-runtime/readers/scan-local.js +102 -0
  359. package/dist/core-runtime/readers/scan-local.test.js +102 -0
  360. package/dist/core-runtime/readers/scan-tarball.js +121 -0
  361. package/dist/core-runtime/readers/scan-tarball.test.js +283 -0
  362. package/dist/core-runtime/readers/scan-vault.js +34 -0
  363. package/dist/core-runtime/readers/scan-vault.test.js +81 -0
  364. package/dist/core-runtime/readers/types.js +42 -0
  365. package/dist/core-runtime/readers/types.test.js +94 -0
  366. package/dist/core-runtime/readers/viewpoint-collectors.js +229 -0
  367. package/dist/core-runtime/reconstruct/artifact-types.js +1 -0
  368. package/dist/core-runtime/reconstruct/directive-validation.js +123 -0
  369. package/dist/core-runtime/reconstruct/materialize-preparation.js +251 -0
  370. package/dist/core-runtime/reconstruct/record.js +198 -0
  371. package/dist/core-runtime/reconstruct/run.js +578 -0
  372. package/dist/core-runtime/reconstruct/seed-candidate-validation.js +356 -0
  373. package/dist/core-runtime/reconstruct/source-observations.js +62 -0
  374. package/dist/core-runtime/reconstruct/source-profiles.js +73 -0
  375. package/dist/core-runtime/release-channel/release-channel.js +90 -0
  376. package/dist/core-runtime/review/artifact-types.js +13 -0
  377. package/dist/core-runtime/review/citation-audit.js +204 -0
  378. package/dist/core-runtime/review/citation-audit.test.js +165 -0
  379. package/dist/core-runtime/review/controlled-lens-deliberation.js +125 -0
  380. package/dist/core-runtime/review/execution-plan-resolver.js +247 -0
  381. package/dist/core-runtime/review/execution-plan-resolver.test.js +243 -0
  382. package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +246 -0
  383. package/dist/core-runtime/review/execution-topology-resolver.js +401 -0
  384. package/dist/core-runtime/review/execution-topology-resolver.test.js +315 -0
  385. package/dist/core-runtime/review/failure-records.js +57 -0
  386. package/dist/core-runtime/review/inline-context-embedder.js +141 -0
  387. package/dist/core-runtime/review/inline-context-embedder.test.js +154 -0
  388. package/dist/core-runtime/review/issue-artifact-runtime.js +859 -0
  389. package/dist/core-runtime/review/legacy-mode-policy.js +88 -0
  390. package/dist/core-runtime/review/lens-completion-policy.js +17 -0
  391. package/dist/core-runtime/review/materializers-effort-persist.test.js +79 -0
  392. package/dist/core-runtime/review/materializers.js +963 -0
  393. package/dist/core-runtime/review/ontology-path-classifier.js +179 -0
  394. package/dist/core-runtime/review/ontology-path-classifier.test.js +216 -0
  395. package/dist/core-runtime/review/packet-boundary-policy.js +215 -0
  396. package/dist/core-runtime/review/packet-boundary-policy.test.js +107 -0
  397. package/dist/core-runtime/review/participating-lens-paths.js +61 -0
  398. package/dist/core-runtime/review/participating-lens-paths.test.js +73 -0
  399. package/dist/core-runtime/review/review-artifact-utils.js +287 -0
  400. package/dist/core-runtime/review/review-config-legacy-translate.js +244 -0
  401. package/dist/core-runtime/review/review-config-legacy-translate.test.js +161 -0
  402. package/dist/core-runtime/review/review-config-validator.js +289 -0
  403. package/dist/core-runtime/review/review-config-validator.test.js +236 -0
  404. package/dist/core-runtime/review/review-execution-profile.js +193 -0
  405. package/dist/core-runtime/review/review-execution-route.js +52 -0
  406. package/dist/core-runtime/review/review-progress-contract.js +123 -0
  407. package/dist/core-runtime/review/review-record-validation.js +251 -0
  408. package/dist/core-runtime/review/review-result-classification.js +379 -0
  409. package/dist/core-runtime/review/review-state-machine.js +39 -0
  410. package/dist/core-runtime/review/route-visibility.js +125 -0
  411. package/dist/core-runtime/review/shape-pipeline-audit.test.js +311 -0
  412. package/dist/core-runtime/review/shape-to-topology-id.js +117 -0
  413. package/dist/core-runtime/review/shape-to-topology-id.test.js +132 -0
  414. package/dist/core-runtime/review/topology-shape-derivation.js +155 -0
  415. package/dist/core-runtime/review/topology-shape-derivation.test.js +195 -0
  416. package/dist/core-runtime/scope-runtime/constants.js +12 -0
  417. package/dist/core-runtime/scope-runtime/constraint-pool.js +166 -0
  418. package/dist/core-runtime/scope-runtime/constraint-pool.test.js +674 -0
  419. package/dist/core-runtime/scope-runtime/domain-validation-log.js +135 -0
  420. package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +156 -0
  421. package/dist/core-runtime/scope-runtime/eval-persistence.js +65 -0
  422. package/dist/core-runtime/scope-runtime/eval-persistence.test.js +84 -0
  423. package/dist/core-runtime/scope-runtime/event-pipeline.js +64 -0
  424. package/dist/core-runtime/scope-runtime/event-pipeline.test.js +450 -0
  425. package/dist/core-runtime/scope-runtime/event-store.js +39 -0
  426. package/dist/core-runtime/scope-runtime/event-store.test.js +95 -0
  427. package/dist/core-runtime/scope-runtime/gate-guard.js +348 -0
  428. package/dist/core-runtime/scope-runtime/gate-guard.test.js +1047 -0
  429. package/dist/core-runtime/scope-runtime/hash.js +4 -0
  430. package/dist/core-runtime/scope-runtime/hash.test.js +33 -0
  431. package/dist/core-runtime/scope-runtime/id.js +4 -0
  432. package/dist/core-runtime/scope-runtime/id.test.js +17 -0
  433. package/dist/core-runtime/scope-runtime/reducer.js +297 -0
  434. package/dist/core-runtime/scope-runtime/reducer.test.js +759 -0
  435. package/dist/core-runtime/scope-runtime/scope-manager.js +161 -0
  436. package/dist/core-runtime/scope-runtime/state-machine.js +309 -0
  437. package/dist/core-runtime/scope-runtime/state-machine.test.js +704 -0
  438. package/dist/core-runtime/scope-runtime/types.js +116 -0
  439. package/dist/core-runtime/scope-runtime/types.test.js +69 -0
  440. package/dist/core-runtime/target-material-kind.js +256 -0
  441. package/dist/core-runtime/translate/render-for-user.js +169 -0
  442. package/dist/core-runtime/translate/render-for-user.test.js +122 -0
  443. package/dist/mcp/server.js +1011 -0
  444. package/dist/mcp/tool-schemas.js +93 -0
  445. package/dist/providers/capability-contract.js +1 -0
  446. package/package.json +68 -0
  447. package/settings.example.json +33 -0
@@ -0,0 +1,859 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileExists, readYamlDocument, toRelativePath, } from "./review-artifact-utils.js";
4
+ import { isMaterialSeverity, REVIEW_SEVERITY_ORDER, } from "./review-result-classification.js";
5
+ import { reviewProgressStepByIssueArtifact } from "./review-progress-contract.js";
6
+ export const ISSUE_ARTIFACT_REGISTRY = [
7
+ {
8
+ artifact_id: "finding-ledger",
9
+ file_name: "finding-ledger.yaml",
10
+ prompt_packet_file_name: "finding-ledger.prompt.md",
11
+ ref_key: "finding_ledger",
12
+ phase: "pre_deliberation",
13
+ progress_step: reviewProgressStepByIssueArtifact("finding-ledger").step,
14
+ progress_label: reviewProgressStepByIssueArtifact("finding-ledger").label,
15
+ },
16
+ {
17
+ artifact_id: "finding-relation-graph",
18
+ file_name: "finding-relation-graph.yaml",
19
+ prompt_packet_file_name: "finding-relation-graph.prompt.md",
20
+ ref_key: "finding_relation_graph",
21
+ phase: "pre_deliberation",
22
+ progress_step: reviewProgressStepByIssueArtifact("finding-relation-graph").step,
23
+ progress_label: reviewProgressStepByIssueArtifact("finding-relation-graph").label,
24
+ },
25
+ {
26
+ artifact_id: "issue-ledger",
27
+ file_name: "issue-ledger.yaml",
28
+ prompt_packet_file_name: "issue-ledger.prompt.md",
29
+ ref_key: "issue_ledger",
30
+ phase: "pre_deliberation",
31
+ progress_step: reviewProgressStepByIssueArtifact("issue-ledger").step,
32
+ progress_label: reviewProgressStepByIssueArtifact("issue-ledger").label,
33
+ },
34
+ {
35
+ artifact_id: "issue-stance-matrix",
36
+ file_name: "issue-stance-matrix.yaml",
37
+ prompt_packet_file_name: "issue-stance-matrix.prompt.md",
38
+ ref_key: "issue_stance_matrix",
39
+ phase: "pre_deliberation",
40
+ progress_step: reviewProgressStepByIssueArtifact("issue-stance-matrix").step,
41
+ progress_label: reviewProgressStepByIssueArtifact("issue-stance-matrix").label,
42
+ },
43
+ {
44
+ artifact_id: "deliberation-plan",
45
+ file_name: "deliberation-plan.yaml",
46
+ prompt_packet_file_name: "deliberation-plan.prompt.md",
47
+ ref_key: "deliberation_plan",
48
+ phase: "pre_deliberation",
49
+ progress_step: reviewProgressStepByIssueArtifact("deliberation-plan").step,
50
+ progress_label: reviewProgressStepByIssueArtifact("deliberation-plan").label,
51
+ },
52
+ {
53
+ artifact_id: "problem-framing",
54
+ file_name: "problem-framing.yaml",
55
+ prompt_packet_file_name: "problem-framing.prompt.md",
56
+ ref_key: "problem_framing",
57
+ phase: "post_deliberation",
58
+ progress_step: reviewProgressStepByIssueArtifact("problem-framing").step,
59
+ progress_label: reviewProgressStepByIssueArtifact("problem-framing").label,
60
+ },
61
+ ];
62
+ export const PRE_DELIBERATION_ISSUE_ARTIFACT_IDS = ISSUE_ARTIFACT_REGISTRY
63
+ .filter((spec) => spec.phase === "pre_deliberation")
64
+ .map((spec) => spec.artifact_id);
65
+ export const ISSUE_ARTIFACT_IDS = ISSUE_ARTIFACT_REGISTRY.map((spec) => spec.artifact_id);
66
+ export function issueArtifactSpec(artifactId) {
67
+ const spec = ISSUE_ARTIFACT_REGISTRY.find((candidate) => candidate.artifact_id === artifactId);
68
+ if (!spec) {
69
+ throw new Error(`Unknown issue artifact id: ${artifactId}`);
70
+ }
71
+ return spec;
72
+ }
73
+ export function issueArtifactConsumerId(artifactId) {
74
+ return `issue-artifact:${artifactId}`;
75
+ }
76
+ const STANCE_VALUES = new Set([
77
+ "support",
78
+ "oppose",
79
+ "narrow",
80
+ "alternative_root",
81
+ "surface_only",
82
+ "not_applicable",
83
+ "insufficient_evidence",
84
+ ]);
85
+ const RELATION_VALUES = new Set([
86
+ "same_root_candidate",
87
+ "causes",
88
+ "symptom_of",
89
+ "enables",
90
+ "duplicates",
91
+ "conflicts_with",
92
+ "independent",
93
+ ]);
94
+ const CONFIDENCE_VALUES = new Set(["low", "medium", "high"]);
95
+ const SEVERITY_VALUES = new Set(REVIEW_SEVERITY_ORDER);
96
+ const ROOT_HYPOTHESIS_POSITION_VALUES = new Set([
97
+ "accepts",
98
+ "narrows",
99
+ "replaces",
100
+ "rejects",
101
+ "not_applicable",
102
+ "insufficient_evidence",
103
+ ]);
104
+ const SEVERITY_POSITION_VALUES = new Set([
105
+ "keeps",
106
+ "raises",
107
+ "lowers",
108
+ "not_applicable",
109
+ "insufficient_evidence",
110
+ ]);
111
+ const ISSUE_ROLE_VALUES = new Set([
112
+ "root_cause",
113
+ "symptom",
114
+ "enabler",
115
+ "conflicting_interpretation",
116
+ "evidence_gap",
117
+ "independent_issue",
118
+ ]);
119
+ const JUDGMENT_STATE_VALUES = new Set([
120
+ "observed",
121
+ "inferred",
122
+ "contested",
123
+ "insufficient_evidence",
124
+ "outside_boundary",
125
+ ]);
126
+ const IMPACT_KIND_VALUES = new Set([
127
+ "correctness",
128
+ "consistency",
129
+ "completeness",
130
+ "safety_risk",
131
+ "usability",
132
+ "governance_value",
133
+ "maintainability_evolvability",
134
+ ]);
135
+ const TIMING_CLASS_VALUES = new Set([
136
+ "current_blocker",
137
+ "next_step_blocker",
138
+ "planned_follow_up",
139
+ "defer_watch",
140
+ ]);
141
+ const CLOSURE_CLASS_VALUES = new Set([
142
+ "fix_now",
143
+ "carry_forward",
144
+ "document_only",
145
+ "needs_decision",
146
+ "needs_evidence",
147
+ "watch",
148
+ ]);
149
+ const CLOSURE_OBLIGATION_VALUES = new Set([
150
+ "must_close_in_target",
151
+ "must_close_before_next_stage",
152
+ "may_close_during_next_stage",
153
+ "planned_later",
154
+ "out_of_scope",
155
+ ]);
156
+ const DOMAIN_PROFILE_STATUS_VALUES = new Set([
157
+ "applied",
158
+ "absent",
159
+ "not_requested",
160
+ ]);
161
+ export function requireIssueArtifactSeat(executionPlan, artifactId) {
162
+ const seat = executionPlan.issue_artifact_prompt_packet_seats.find((candidate) => candidate.artifact_id === artifactId);
163
+ if (!seat) {
164
+ throw new Error(`Missing issue artifact prompt seat: ${artifactId}`);
165
+ }
166
+ return seat;
167
+ }
168
+ function requireRecord(value, label) {
169
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
170
+ throw new Error(`${label} must be a YAML mapping.`);
171
+ }
172
+ return value;
173
+ }
174
+ function requireString(value, label) {
175
+ if (typeof value !== "string" || value.trim().length === 0) {
176
+ throw new Error(`${label} must be a non-empty string.`);
177
+ }
178
+ return value;
179
+ }
180
+ function requireArray(value, label) {
181
+ if (!Array.isArray(value)) {
182
+ throw new Error(`${label} must be a YAML list.`);
183
+ }
184
+ return value;
185
+ }
186
+ function requireStringArray(value, label) {
187
+ return requireArray(value, label).map((item, index) => requireString(item, `${label}[${index}]`));
188
+ }
189
+ function requireOptionalStringOrNull(value, label) {
190
+ if (value === undefined || value === null)
191
+ return;
192
+ requireString(value, label);
193
+ }
194
+ function requireAllowed(value, allowed, label) {
195
+ const text = requireString(value, label);
196
+ if (!allowed.has(text)) {
197
+ throw new Error(`${label} has unsupported value: ${text}. Allowed values: ${[
198
+ ...allowed,
199
+ ].join(", ")}`);
200
+ }
201
+ return text;
202
+ }
203
+ function ensureUnique(values, label) {
204
+ const seen = new Set();
205
+ for (const value of values) {
206
+ if (seen.has(value)) {
207
+ throw new Error(`${label} contains duplicate value: ${value}`);
208
+ }
209
+ seen.add(value);
210
+ }
211
+ }
212
+ function ensureKnown(value, known, label) {
213
+ if (!known.has(value)) {
214
+ throw new Error(`${label} references unknown id: ${value}`);
215
+ }
216
+ }
217
+ function relativeList(projectRoot, paths) {
218
+ if (paths.length === 0)
219
+ return "- (none)";
220
+ return paths.map((targetPath) => `- ${toRelativePath(targetPath, projectRoot)}`).join("\n");
221
+ }
222
+ export function renderIssueArtifactRefs(projectRoot, executionPlan, artifactIds) {
223
+ return artifactIds
224
+ .map((artifactId) => {
225
+ const seat = requireIssueArtifactSeat(executionPlan, artifactId);
226
+ return `- ${artifactId}: ${toRelativePath(seat.output_path, projectRoot)}`;
227
+ })
228
+ .join("\n");
229
+ }
230
+ export async function resolveProblemFramingProfileRef(args) {
231
+ const contextCandidateAssemblyPath = path.join(args.executionPlan.execution_preparation_root, "context-candidate-assembly.yaml");
232
+ if (!(await fileExists(contextCandidateAssemblyPath)))
233
+ return null;
234
+ const assembly = await readYamlDocument(contextCandidateAssemblyPath);
235
+ const refs = Array.isArray(assembly.domain_context_refs)
236
+ ? assembly.domain_context_refs
237
+ : [];
238
+ const profileRef = refs.find((candidate) => typeof candidate === "string" &&
239
+ path.basename(candidate) === "problem_framing_profile.md");
240
+ return profileRef ? toRelativePath(profileRef, args.projectRoot) : null;
241
+ }
242
+ export function buildIssueArtifactPrompt(args) {
243
+ const outputRef = toRelativePath(args.outputPath, args.projectRoot);
244
+ const lensRefs = relativeList(args.projectRoot, args.lensOutputPaths);
245
+ const reviewTargetProfileRef = toRelativePath(args.executionPlan.review_target_profile_path, args.projectRoot);
246
+ const deliberationResponseRefs = relativeList(args.projectRoot, args.deliberationResponsePaths ?? []);
247
+ const commonHeader = `# Issue-Stance Artifact Prompt
248
+
249
+ session_id: ${args.sessionId}
250
+ unit_id: ${args.artifactId}
251
+ unit_kind: issue_artifact
252
+ artifact_id: ${args.artifactId}
253
+ consumer_id: ${issueArtifactConsumerId(args.artifactId)}
254
+ output_path: ${outputRef}
255
+
256
+ ## Canonical Role
257
+ You are a review runtime artifact builder.
258
+ You are not an independent review lens.
259
+ You must derive the requested artifact from existing lens outputs and prior issue artifacts.
260
+
261
+ ## Hard Output Contract
262
+ - Write YAML only.
263
+ - Do not use markdown fences.
264
+ - Do not include commentary before or after the YAML.
265
+ - Include \`schema_version: 1\`.
266
+ - Include \`session_id: "${args.sessionId}"\`.
267
+ - Quote every scalar string value with double quotes, or use a YAML block scalar for long text.
268
+ - Do not leave a colon-bearing text value unquoted.
269
+ - Preserve lens IDs, source refs, issue IDs, and finding IDs consistently.
270
+ - If evidence is insufficient, encode that explicitly in the YAML instead of inventing facts.
271
+ - Enum fields must use exactly one listed token. Do not append explanation text to enum values; put explanations in rationale fields.
272
+
273
+ ## Severity Contract
274
+ \`severity\` is the review result classification axis. It also determines whether an issue is material.
275
+
276
+ Allowed severity values:
277
+ - blocker: the declared primary happy path cannot be achieved by any intended user, or the result appears trustworthy while breaking a core contract.
278
+ - high: a supported user group, environment, data condition, or execution path cannot achieve the declared purpose.
279
+ - medium: the happy path is possible, but trust, auditability, reproducibility, completeness, or decision quality is meaningfully weakened.
280
+ - low: an improvement opportunity that does not make the reviewed result unsafe for its declared purpose.
281
+ - info: an observation, question, or evidence gap that is not yet an issue.
282
+
283
+ Derived materiality:
284
+ - material issue: blocker, high, medium
285
+ - non-material finding: low, info
286
+
287
+ Every blocker/high/medium severity claim must cite concrete evidence and explain affected_purpose, failure_condition, and impact.
288
+ If evidence is insufficient, use severity: info and explain the evidence gap.
289
+
290
+ ## Lens Outputs
291
+ ${lensRefs}
292
+
293
+ ## Review Target Profile
294
+ - profile: ${reviewTargetProfileRef}
295
+ `;
296
+ switch (args.artifactId) {
297
+ case "finding-ledger":
298
+ return `${commonHeader}
299
+ ## Task
300
+ Build \`finding-ledger.yaml\` from every Round 1 lens output.
301
+ Register every finding or issue claim that can affect the final review.
302
+ Do not cluster findings here.
303
+
304
+ ## Required YAML Shape
305
+ schema_version: 1
306
+ session_id: "${args.sessionId}"
307
+ findings:
308
+ - finding_id: finding-001
309
+ lens_id: logic
310
+ source_ref: round1/logic.md#finding-1
311
+ target: "file or artifact"
312
+ evidence_anchor: "stable evidence anchor"
313
+ claim: "surface finding claim"
314
+ proposed_action: "stated or inferred action"
315
+ affected_purpose: "declared purpose or contract affected by this finding"
316
+ failure_condition: "user group, environment, data condition, execution path, or boundary where trust fails"
317
+ impact: "why this changes trust for the declared review purpose"
318
+ evidence_refs: [round1/logic.md#finding-1]
319
+ severity: medium
320
+ domain_threshold_used: null
321
+ validation:
322
+ unaddressable_findings: []
323
+ `;
324
+ case "finding-relation-graph":
325
+ return `${commonHeader}
326
+ ## Prior Issue Artifacts
327
+ ${renderIssueArtifactRefs(args.projectRoot, args.executionPlan, ["finding-ledger"])}
328
+
329
+ ## Task
330
+ Build \`finding-relation-graph.yaml\`.
331
+ Relate findings by common root, causality, dependency, duplication, conflict, or independence.
332
+
333
+ Allowed relation values:
334
+ - same_root_candidate
335
+ - causes
336
+ - symptom_of
337
+ - enables
338
+ - duplicates
339
+ - conflicts_with
340
+ - independent
341
+
342
+ ## Required YAML Shape
343
+ schema_version: 1
344
+ session_id: "${args.sessionId}"
345
+ relations:
346
+ - relation_id: rel-001
347
+ from_finding_id: finding-001
348
+ to_finding_id: finding-002
349
+ relation: same_root_candidate
350
+ root_hypothesis: "falsifiable common-root claim"
351
+ rationale: "why this relation is supported"
352
+ confidence: medium
353
+ singleton_findings:
354
+ - finding_id: finding-009
355
+ reason: "why no relation was accepted"
356
+ `;
357
+ case "issue-ledger":
358
+ return `${commonHeader}
359
+ ## Prior Issue Artifacts
360
+ ${renderIssueArtifactRefs(args.projectRoot, args.executionPlan, [
361
+ "finding-ledger",
362
+ "finding-relation-graph",
363
+ ])}
364
+
365
+ ## Task
366
+ Build \`issue-ledger.yaml\`.
367
+ Group surface findings into root-cause issue clusters.
368
+ Do not create an issue that has no supporting finding_id.
369
+
370
+ ## Required YAML Shape
371
+ schema_version: 1
372
+ session_id: "${args.sessionId}"
373
+ issues:
374
+ - issue_id: issue-001
375
+ root_cause_hypothesis: "falsifiable root-cause hypothesis"
376
+ root_confidence: medium
377
+ surface_finding_ids: [finding-001]
378
+ relation_refs: [rel-001]
379
+ raised_by_lens_ids: [logic]
380
+ issue_statement: "root-level issue statement"
381
+ proposed_action: "action framing from source findings, not a detailed fix"
382
+ affected_purpose: "declared purpose or contract affected by this root-cause issue"
383
+ failure_condition: "user group, environment, data condition, execution path, or boundary where trust fails"
384
+ impact: "why this changes trust for the declared review purpose"
385
+ evidence_refs: [round1/logic.md#finding-1]
386
+ severity: medium
387
+ domain_threshold_used: null
388
+ singleton_reason: null
389
+ validation:
390
+ unclustered_finding_ids: []
391
+ `;
392
+ case "issue-stance-matrix":
393
+ return `${commonHeader}
394
+ ## Prior Issue Artifacts
395
+ ${renderIssueArtifactRefs(args.projectRoot, args.executionPlan, [
396
+ "finding-ledger",
397
+ "finding-relation-graph",
398
+ "issue-ledger",
399
+ ])}
400
+
401
+ ## Task
402
+ Build \`issue-stance-matrix.yaml\`.
403
+ Every participating lens must have one stance for every issue.
404
+
405
+ Allowed stance values:
406
+ - support
407
+ - oppose
408
+ - narrow
409
+ - alternative_root
410
+ - surface_only
411
+ - not_applicable
412
+ - insufficient_evidence
413
+
414
+ Allowed root_hypothesis_position values:
415
+ - accepts
416
+ - narrows
417
+ - replaces
418
+ - rejects
419
+ - not_applicable
420
+ - insufficient_evidence
421
+
422
+ Allowed severity_position values:
423
+ - keeps
424
+ - raises
425
+ - lowers
426
+ - not_applicable
427
+ - insufficient_evidence
428
+
429
+ ## Required YAML Shape
430
+ schema_version: 1
431
+ session_id: "${args.sessionId}"
432
+ issues:
433
+ - issue_id: issue-001
434
+ stances:
435
+ - lens_id: logic
436
+ stance: support
437
+ rationale: "why this lens takes this stance"
438
+ root_hypothesis_position: accepts
439
+ severity_position: keeps
440
+ evidence_refs: [round1/logic.md]
441
+ validation:
442
+ missing_stances: []
443
+ `;
444
+ case "deliberation-plan":
445
+ return `${commonHeader}
446
+ ## Prior Issue Artifacts
447
+ ${renderIssueArtifactRefs(args.projectRoot, args.executionPlan, [
448
+ "finding-ledger",
449
+ "finding-relation-graph",
450
+ "issue-ledger",
451
+ "issue-stance-matrix",
452
+ ])}
453
+
454
+ ## Task
455
+ Build \`deliberation-plan.yaml\`.
456
+ Only material conflicts enter planned deliberation.
457
+ Compatible issue stances should be listed under skipped_issues with a reason.
458
+
459
+ ## Required YAML Shape
460
+ schema_version: 1
461
+ session_id: "${args.sessionId}"
462
+ planned_issues:
463
+ - issue_id: issue-001
464
+ order: 1
465
+ material_conflict: true
466
+ participating_lens_ids: [logic, structure]
467
+ conflict_summary: "what incompatible claims must be deliberated"
468
+ resolution_question: "the exact question deliberation must answer"
469
+ skipped_issues:
470
+ - issue_id: issue-002
471
+ reason: "no material conflict"
472
+ `;
473
+ case "problem-framing":
474
+ return `${commonHeader}
475
+ ## Prior Issue Artifacts
476
+ ${renderIssueArtifactRefs(args.projectRoot, args.executionPlan, [
477
+ "finding-ledger",
478
+ "finding-relation-graph",
479
+ "issue-ledger",
480
+ "issue-stance-matrix",
481
+ "deliberation-plan",
482
+ ])}
483
+
484
+ ## Controlled Deliberation Result
485
+ - teamlead result: ${args.deliberationOutputPath
486
+ ? toRelativePath(args.deliberationOutputPath, args.projectRoot)
487
+ : "(missing)"}
488
+
489
+ ## Lens Deliberation Responses
490
+ ${deliberationResponseRefs}
491
+
492
+ ## Domain Problem Framing Profile
493
+ - profile: ${args.problemFramingProfileRef ?? "(absent)"}
494
+
495
+ ## Task
496
+ Build \`problem-framing.yaml\`.
497
+ Classify each issue with the common spine and optional domain axes from the selected profile.
498
+ Do not change issue status or lens stance.
499
+ Do not propose detailed fixes.
500
+
501
+ Allowed common spine values:
502
+ - issue_role: root_cause, symptom, enabler, conflicting_interpretation, evidence_gap, independent_issue
503
+ - judgment_state: observed, inferred, contested, insufficient_evidence, outside_boundary
504
+ - impact_kind: correctness, consistency, completeness, safety_risk, usability, governance_value, maintainability_evolvability
505
+ - timing_class: current_blocker, next_step_blocker, planned_follow_up, defer_watch
506
+ - closure_class: fix_now, carry_forward, document_only, needs_decision, needs_evidence, watch
507
+ - closure_obligation: must_close_in_target, must_close_before_next_stage, may_close_during_next_stage, planned_later, out_of_scope
508
+
509
+ ## Required YAML Shape
510
+ schema_version: 1
511
+ session_id: "${args.sessionId}"
512
+ classification_context:
513
+ common_spine_version: 1
514
+ session_domain: "from binding"
515
+ domain_profile_ref: "${args.problemFramingProfileRef ?? ""}"
516
+ domain_profile_doc_type: "custom:problem_framing_profile"
517
+ domain_profile_status: ${args.problemFramingProfileRef ? "applied" : "absent"}
518
+ classifications:
519
+ - issue_id: issue-001
520
+ problem_definition: "root-level problem definition"
521
+ issue_role: root_cause
522
+ judgment_state: inferred
523
+ impact_kind: consistency
524
+ timing_class: next_step_blocker
525
+ closure_class: carry_forward
526
+ closure_obligation: may_close_during_next_stage
527
+ domain_axes: {}
528
+ rationale: "why this classification is appropriate"
529
+ related_surface_finding_ids: [finding-001]
530
+ `;
531
+ }
532
+ }
533
+ export async function writeIssueArtifactPromptPacket(args) {
534
+ const seat = requireIssueArtifactSeat(args.executionPlan, args.artifactId);
535
+ const packetText = buildIssueArtifactPrompt({
536
+ artifactId: args.artifactId,
537
+ sessionId: args.sessionId,
538
+ projectRoot: args.projectRoot,
539
+ outputPath: seat.output_path,
540
+ lensOutputPaths: args.lensOutputPaths,
541
+ ...(args.deliberationResponsePaths
542
+ ? { deliberationResponsePaths: args.deliberationResponsePaths }
543
+ : {}),
544
+ ...(args.deliberationOutputPath
545
+ ? { deliberationOutputPath: args.deliberationOutputPath }
546
+ : {}),
547
+ ...(args.problemFramingProfileRef !== undefined
548
+ ? { problemFramingProfileRef: args.problemFramingProfileRef }
549
+ : {}),
550
+ executionPlan: args.executionPlan,
551
+ });
552
+ await fs.mkdir(path.dirname(seat.packet_path), { recursive: true });
553
+ await fs.writeFile(seat.packet_path, `${packetText.trimEnd()}\n`, "utf8");
554
+ return seat;
555
+ }
556
+ function validateEnvelope(args) {
557
+ if (args.parsed.schema_version !== 1) {
558
+ throw new Error(`${args.artifactId} must declare schema_version: 1`);
559
+ }
560
+ if (args.parsed.session_id !== args.sessionId) {
561
+ throw new Error(`${args.artifactId} must declare session_id: ${args.sessionId}`);
562
+ }
563
+ }
564
+ export function validateIssueArtifactObject(args) {
565
+ validateEnvelope(args);
566
+ switch (args.artifactId) {
567
+ case "finding-ledger": {
568
+ const findings = requireArray(args.parsed.findings, "finding-ledger.findings");
569
+ const findingIds = [];
570
+ for (const [index, item] of findings.entries()) {
571
+ const finding = requireRecord(item, `finding-ledger.findings[${index}]`);
572
+ findingIds.push(requireString(finding.finding_id, `finding-ledger.findings[${index}].finding_id`));
573
+ requireString(finding.lens_id, `finding-ledger.findings[${index}].lens_id`);
574
+ requireString(finding.source_ref, `finding-ledger.findings[${index}].source_ref`);
575
+ requireString(finding.claim, `finding-ledger.findings[${index}].claim`);
576
+ requireString(finding.affected_purpose, `finding-ledger.findings[${index}].affected_purpose`);
577
+ requireString(finding.failure_condition, `finding-ledger.findings[${index}].failure_condition`);
578
+ requireString(finding.impact, `finding-ledger.findings[${index}].impact`);
579
+ const evidenceRefs = requireStringArray(finding.evidence_refs, `finding-ledger.findings[${index}].evidence_refs`);
580
+ const severity = requireAllowed(finding.severity, SEVERITY_VALUES, `finding-ledger.findings[${index}].severity`);
581
+ if (isMaterialSeverity(severity) && evidenceRefs.length === 0) {
582
+ throw new Error(`finding-ledger.findings[${index}].evidence_refs must not be empty for severity=${severity}.`);
583
+ }
584
+ requireOptionalStringOrNull(finding.domain_threshold_used, `finding-ledger.findings[${index}].domain_threshold_used`);
585
+ }
586
+ ensureUnique(findingIds, "finding-ledger.finding_id");
587
+ const validation = requireRecord(args.parsed.validation, "finding-ledger.validation");
588
+ requireArray(validation.unaddressable_findings, "finding-ledger.validation.unaddressable_findings");
589
+ return;
590
+ }
591
+ case "finding-relation-graph": {
592
+ const knownFindingIds = args.knownFindingIds ?? new Set();
593
+ const relationIds = [];
594
+ for (const [index, item] of requireArray(args.parsed.relations, "finding-relation-graph.relations").entries()) {
595
+ const relation = requireRecord(item, `finding-relation-graph.relations[${index}]`);
596
+ relationIds.push(requireString(relation.relation_id, `finding-relation-graph.relations[${index}].relation_id`));
597
+ const from = requireString(relation.from_finding_id, `finding-relation-graph.relations[${index}].from_finding_id`);
598
+ const to = requireString(relation.to_finding_id, `finding-relation-graph.relations[${index}].to_finding_id`);
599
+ if (knownFindingIds.size > 0) {
600
+ ensureKnown(from, knownFindingIds, `finding-relation-graph.relations[${index}].from_finding_id`);
601
+ ensureKnown(to, knownFindingIds, `finding-relation-graph.relations[${index}].to_finding_id`);
602
+ }
603
+ requireAllowed(relation.relation, RELATION_VALUES, `finding-relation-graph.relations[${index}].relation`);
604
+ if (relation.confidence !== undefined) {
605
+ requireAllowed(relation.confidence, CONFIDENCE_VALUES, `finding-relation-graph.relations[${index}].confidence`);
606
+ }
607
+ requireString(relation.rationale, `finding-relation-graph.relations[${index}].rationale`);
608
+ }
609
+ ensureUnique(relationIds, "finding-relation-graph.relation_id");
610
+ for (const [index, item] of requireArray(args.parsed.singleton_findings, "finding-relation-graph.singleton_findings").entries()) {
611
+ const singleton = requireRecord(item, `finding-relation-graph.singleton_findings[${index}]`);
612
+ const findingId = requireString(singleton.finding_id, `finding-relation-graph.singleton_findings[${index}].finding_id`);
613
+ if (knownFindingIds.size > 0) {
614
+ ensureKnown(findingId, knownFindingIds, `finding-relation-graph.singleton_findings[${index}].finding_id`);
615
+ }
616
+ requireString(singleton.reason, `finding-relation-graph.singleton_findings[${index}].reason`);
617
+ }
618
+ return;
619
+ }
620
+ case "issue-ledger": {
621
+ const knownFindingIds = args.knownFindingIds ?? new Set();
622
+ const knownRelationIds = args.knownRelationIds ?? new Set();
623
+ const issueIds = [];
624
+ for (const [index, item] of requireArray(args.parsed.issues, "issue-ledger.issues").entries()) {
625
+ const issue = requireRecord(item, `issue-ledger.issues[${index}]`);
626
+ issueIds.push(requireString(issue.issue_id, `issue-ledger.issues[${index}].issue_id`));
627
+ requireString(issue.root_cause_hypothesis, `issue-ledger.issues[${index}].root_cause_hypothesis`);
628
+ requireAllowed(issue.root_confidence, CONFIDENCE_VALUES, `issue-ledger.issues[${index}].root_confidence`);
629
+ requireString(issue.issue_statement, `issue-ledger.issues[${index}].issue_statement`);
630
+ requireString(issue.affected_purpose, `issue-ledger.issues[${index}].affected_purpose`);
631
+ requireString(issue.failure_condition, `issue-ledger.issues[${index}].failure_condition`);
632
+ requireString(issue.impact, `issue-ledger.issues[${index}].impact`);
633
+ const evidenceRefs = requireStringArray(issue.evidence_refs, `issue-ledger.issues[${index}].evidence_refs`);
634
+ const severity = requireAllowed(issue.severity, SEVERITY_VALUES, `issue-ledger.issues[${index}].severity`);
635
+ if (isMaterialSeverity(severity) && evidenceRefs.length === 0) {
636
+ throw new Error(`issue-ledger.issues[${index}].evidence_refs must not be empty for severity=${severity}.`);
637
+ }
638
+ requireOptionalStringOrNull(issue.domain_threshold_used, `issue-ledger.issues[${index}].domain_threshold_used`);
639
+ const surfaceFindingIds = requireStringArray(issue.surface_finding_ids, `issue-ledger.issues[${index}].surface_finding_ids`);
640
+ if (surfaceFindingIds.length === 0) {
641
+ throw new Error(`issue-ledger.issues[${index}].surface_finding_ids must not be empty.`);
642
+ }
643
+ for (const findingId of surfaceFindingIds) {
644
+ if (knownFindingIds.size > 0) {
645
+ ensureKnown(findingId, knownFindingIds, `issue-ledger.issues[${index}].surface_finding_ids`);
646
+ }
647
+ }
648
+ for (const relationId of requireStringArray(issue.relation_refs, `issue-ledger.issues[${index}].relation_refs`)) {
649
+ if (knownRelationIds.size > 0) {
650
+ ensureKnown(relationId, knownRelationIds, `issue-ledger.issues[${index}].relation_refs`);
651
+ }
652
+ }
653
+ requireStringArray(issue.raised_by_lens_ids, `issue-ledger.issues[${index}].raised_by_lens_ids`);
654
+ }
655
+ ensureUnique(issueIds, "issue-ledger.issue_id");
656
+ const validation = requireRecord(args.parsed.validation, "issue-ledger.validation");
657
+ requireArray(validation.unclustered_finding_ids, "issue-ledger.validation.unclustered_finding_ids");
658
+ return;
659
+ }
660
+ case "issue-stance-matrix": {
661
+ const knownIssueIds = args.knownIssueIds ?? new Set();
662
+ const participatingLensIds = args.participatingLensIds ?? [];
663
+ const matrixIssueIds = [];
664
+ for (const [index, item] of requireArray(args.parsed.issues, "issue-stance-matrix.issues").entries()) {
665
+ const issue = requireRecord(item, `issue-stance-matrix.issues[${index}]`);
666
+ const issueId = requireString(issue.issue_id, `issue-stance-matrix.issues[${index}].issue_id`);
667
+ matrixIssueIds.push(issueId);
668
+ if (knownIssueIds.size > 0) {
669
+ ensureKnown(issueId, knownIssueIds, `issue-stance-matrix.issues[${index}].issue_id`);
670
+ }
671
+ const stanceLensIds = [];
672
+ for (const [stanceIndex, stanceItem] of requireArray(issue.stances, `issue-stance-matrix.issues[${index}].stances`).entries()) {
673
+ const stance = requireRecord(stanceItem, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}]`);
674
+ stanceLensIds.push(requireString(stance.lens_id, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}].lens_id`));
675
+ requireAllowed(stance.stance, STANCE_VALUES, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}].stance`);
676
+ requireString(stance.rationale, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}].rationale`);
677
+ requireAllowed(stance.root_hypothesis_position, ROOT_HYPOTHESIS_POSITION_VALUES, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}].root_hypothesis_position`);
678
+ requireAllowed(stance.severity_position, SEVERITY_POSITION_VALUES, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}].severity_position`);
679
+ requireArray(stance.evidence_refs, `issue-stance-matrix.issues[${index}].stances[${stanceIndex}].evidence_refs`);
680
+ }
681
+ ensureUnique(stanceLensIds, `issue-stance-matrix.issues[${index}].stances.lens_id`);
682
+ for (const lensId of participatingLensIds) {
683
+ if (!stanceLensIds.includes(lensId)) {
684
+ throw new Error(`issue-stance-matrix missing stance for issue ${issueId} and lens ${lensId}`);
685
+ }
686
+ }
687
+ }
688
+ ensureUnique(matrixIssueIds, "issue-stance-matrix.issue_id");
689
+ if (knownIssueIds.size > 0) {
690
+ for (const issueId of knownIssueIds) {
691
+ if (!matrixIssueIds.includes(issueId)) {
692
+ throw new Error(`issue-stance-matrix missing issue: ${issueId}`);
693
+ }
694
+ }
695
+ }
696
+ const validation = requireRecord(args.parsed.validation, "issue-stance-matrix.validation");
697
+ requireArray(validation.missing_stances, "issue-stance-matrix.validation.missing_stances");
698
+ return;
699
+ }
700
+ case "deliberation-plan": {
701
+ const knownIssueIds = args.knownIssueIds ?? new Set();
702
+ const covered = new Set();
703
+ for (const [index, item] of requireArray(args.parsed.planned_issues, "deliberation-plan.planned_issues").entries()) {
704
+ const issue = requireRecord(item, `deliberation-plan.planned_issues[${index}]`);
705
+ const issueId = requireString(issue.issue_id, `deliberation-plan.planned_issues[${index}].issue_id`);
706
+ covered.add(issueId);
707
+ if (knownIssueIds.size > 0) {
708
+ ensureKnown(issueId, knownIssueIds, `deliberation-plan.planned_issues[${index}].issue_id`);
709
+ }
710
+ requireStringArray(issue.participating_lens_ids, `deliberation-plan.planned_issues[${index}].participating_lens_ids`);
711
+ requireString(issue.conflict_summary, `deliberation-plan.planned_issues[${index}].conflict_summary`);
712
+ requireString(issue.resolution_question, `deliberation-plan.planned_issues[${index}].resolution_question`);
713
+ }
714
+ for (const [index, item] of requireArray(args.parsed.skipped_issues, "deliberation-plan.skipped_issues").entries()) {
715
+ const issue = requireRecord(item, `deliberation-plan.skipped_issues[${index}]`);
716
+ const issueId = requireString(issue.issue_id, `deliberation-plan.skipped_issues[${index}].issue_id`);
717
+ covered.add(issueId);
718
+ if (knownIssueIds.size > 0) {
719
+ ensureKnown(issueId, knownIssueIds, `deliberation-plan.skipped_issues[${index}].issue_id`);
720
+ }
721
+ requireString(issue.reason, `deliberation-plan.skipped_issues[${index}].reason`);
722
+ }
723
+ if (knownIssueIds.size > 0) {
724
+ for (const issueId of knownIssueIds) {
725
+ if (!covered.has(issueId)) {
726
+ throw new Error(`deliberation-plan does not cover issue: ${issueId}`);
727
+ }
728
+ }
729
+ }
730
+ return;
731
+ }
732
+ case "problem-framing": {
733
+ const knownIssueIds = args.knownIssueIds ?? new Set();
734
+ const classificationContext = requireRecord(args.parsed.classification_context, "problem-framing.classification_context");
735
+ if (classificationContext.common_spine_version !== 1) {
736
+ throw new Error("problem-framing.classification_context.common_spine_version must be 1.");
737
+ }
738
+ requireString(classificationContext.session_domain, "problem-framing.classification_context.session_domain");
739
+ const profileRef = typeof classificationContext.domain_profile_ref === "string"
740
+ ? classificationContext.domain_profile_ref
741
+ : "";
742
+ if (classificationContext.domain_profile_doc_type !== "custom:problem_framing_profile") {
743
+ throw new Error("problem-framing.classification_context.domain_profile_doc_type must be custom:problem_framing_profile.");
744
+ }
745
+ const profileStatus = requireAllowed(classificationContext.domain_profile_status, DOMAIN_PROFILE_STATUS_VALUES, "problem-framing.classification_context.domain_profile_status");
746
+ if (profileRef.trim().length > 0 && profileStatus !== "applied") {
747
+ throw new Error("problem-framing profile ref is present, so domain_profile_status must be applied.");
748
+ }
749
+ if (profileRef.trim().length === 0 && profileStatus === "applied") {
750
+ throw new Error("problem-framing profile ref is absent, so domain_profile_status must not be applied.");
751
+ }
752
+ const classificationIssueIds = [];
753
+ for (const [index, item] of requireArray(args.parsed.classifications, "problem-framing.classifications").entries()) {
754
+ const classification = requireRecord(item, `problem-framing.classifications[${index}]`);
755
+ const issueId = requireString(classification.issue_id, `problem-framing.classifications[${index}].issue_id`);
756
+ classificationIssueIds.push(issueId);
757
+ if (knownIssueIds.size > 0) {
758
+ ensureKnown(issueId, knownIssueIds, `problem-framing.classifications[${index}].issue_id`);
759
+ }
760
+ requireString(classification.problem_definition, `problem-framing.classifications[${index}].problem_definition`);
761
+ requireAllowed(classification.issue_role, ISSUE_ROLE_VALUES, `problem-framing.classifications[${index}].issue_role`);
762
+ requireAllowed(classification.judgment_state, JUDGMENT_STATE_VALUES, `problem-framing.classifications[${index}].judgment_state`);
763
+ requireAllowed(classification.impact_kind, IMPACT_KIND_VALUES, `problem-framing.classifications[${index}].impact_kind`);
764
+ requireAllowed(classification.timing_class, TIMING_CLASS_VALUES, `problem-framing.classifications[${index}].timing_class`);
765
+ requireAllowed(classification.closure_class, CLOSURE_CLASS_VALUES, `problem-framing.classifications[${index}].closure_class`);
766
+ requireAllowed(classification.closure_obligation, CLOSURE_OBLIGATION_VALUES, `problem-framing.classifications[${index}].closure_obligation`);
767
+ requireRecord(classification.domain_axes, `problem-framing.classifications[${index}].domain_axes`);
768
+ requireString(classification.rationale, `problem-framing.classifications[${index}].rationale`);
769
+ requireStringArray(classification.related_surface_finding_ids, `problem-framing.classifications[${index}].related_surface_finding_ids`);
770
+ }
771
+ ensureUnique(classificationIssueIds, "problem-framing.issue_id");
772
+ if (knownIssueIds.size > 0) {
773
+ for (const issueId of knownIssueIds) {
774
+ if (!classificationIssueIds.includes(issueId)) {
775
+ throw new Error(`problem-framing missing issue classification: ${issueId}`);
776
+ }
777
+ }
778
+ }
779
+ return;
780
+ }
781
+ }
782
+ }
783
+ async function readArtifact(executionPlan, artifactId) {
784
+ const seat = requireIssueArtifactSeat(executionPlan, artifactId);
785
+ return readYamlDocument(seat.output_path);
786
+ }
787
+ function findingIdsFrom(findingLedger) {
788
+ return new Set(requireArray(findingLedger.findings, "finding-ledger.findings").map((item, index) => requireString(requireRecord(item, `finding-ledger.findings[${index}]`).finding_id, `finding-ledger.findings[${index}].finding_id`)));
789
+ }
790
+ function relationIdsFrom(relationGraph) {
791
+ return new Set(requireArray(relationGraph.relations, "finding-relation-graph.relations").map((item, index) => requireString(requireRecord(item, `finding-relation-graph.relations[${index}]`).relation_id, `finding-relation-graph.relations[${index}].relation_id`)));
792
+ }
793
+ function issueIdsFrom(issueLedger) {
794
+ return new Set(requireArray(issueLedger.issues, "issue-ledger.issues").map((item, index) => requireString(requireRecord(item, `issue-ledger.issues[${index}]`).issue_id, `issue-ledger.issues[${index}].issue_id`)));
795
+ }
796
+ export async function validateIssueArtifactOnDisk(args) {
797
+ const parsed = await readArtifact(args.executionPlan, args.artifactId);
798
+ const findingLedger = args.artifactId === "finding-ledger"
799
+ ? parsed
800
+ : await readArtifact(args.executionPlan, "finding-ledger");
801
+ const knownFindingIds = findingIdsFrom(findingLedger);
802
+ const relationGraph = (() => {
803
+ if (args.artifactId === "finding-ledger")
804
+ return null;
805
+ if (args.artifactId === "finding-relation-graph")
806
+ return parsed;
807
+ return undefined;
808
+ })();
809
+ const resolvedRelationGraph = relationGraph === undefined
810
+ ? await readArtifact(args.executionPlan, "finding-relation-graph")
811
+ : relationGraph;
812
+ const knownRelationIds = relationGraph ? relationIdsFrom(relationGraph) : new Set();
813
+ const knownResolvedRelationIds = resolvedRelationGraph
814
+ ? relationIdsFrom(resolvedRelationGraph)
815
+ : knownRelationIds;
816
+ const issueLedger = (() => {
817
+ if (args.artifactId === "finding-ledger" ||
818
+ args.artifactId === "finding-relation-graph") {
819
+ return null;
820
+ }
821
+ if (args.artifactId === "issue-ledger")
822
+ return parsed;
823
+ return undefined;
824
+ })();
825
+ const resolvedIssueLedger = issueLedger === undefined
826
+ ? await readArtifact(args.executionPlan, "issue-ledger")
827
+ : issueLedger;
828
+ const knownIssueIds = resolvedIssueLedger ? issueIdsFrom(resolvedIssueLedger) : new Set();
829
+ validateIssueArtifactObject({
830
+ artifactId: args.artifactId,
831
+ parsed,
832
+ sessionId: args.executionPlan.session_id,
833
+ knownFindingIds,
834
+ knownRelationIds: knownResolvedRelationIds,
835
+ knownIssueIds,
836
+ participatingLensIds: args.participatingLensIds,
837
+ });
838
+ return parsed;
839
+ }
840
+ export async function renderIssueArtifactContext(args) {
841
+ const artifactIds = args.artifactIds ?? PRE_DELIBERATION_ISSUE_ARTIFACT_IDS;
842
+ const sections = [
843
+ "Use the issue artifact content below as the root-cause issue frame.",
844
+ "The file paths are provenance anchors; the YAML bodies are in-scope evidence.",
845
+ ];
846
+ for (const artifactId of artifactIds) {
847
+ const seat = requireIssueArtifactSeat(args.executionPlan, artifactId);
848
+ const content = await fs.readFile(seat.output_path, "utf8");
849
+ sections.push([
850
+ `### ${artifactId}`,
851
+ `path: ${toRelativePath(seat.output_path, args.projectRoot)}`,
852
+ "",
853
+ "```yaml",
854
+ content.trim(),
855
+ "```",
856
+ ].join("\n"));
857
+ }
858
+ return sections.join("\n\n");
859
+ }