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,204 @@
1
+ /**
2
+ * Citation audit — Phase 3-4 (A5), fabrication post-flight detection.
3
+ *
4
+ * # What this module is
5
+ *
6
+ * Given a synthesize output and the raw text of participating lens outputs,
7
+ * extracts "significant quoted strings" from the synthesize output and checks
8
+ * whether each one appears as a substring of AT LEAST ONE lens output. Quotes
9
+ * that match nothing AND carry an **attribution pattern** (`axiology: "..."`,
10
+ * `Axiology said "..."`, etc.) are flagged as potential fabrications. Quotes
11
+ * without an attribution pattern are surfaced separately as advisory
12
+ * (`quotes_unmatched_meta`) — they may be taxonomy labels (`"conditional
13
+ * consensus"`), concept names, or paraphrased references rather than
14
+ * fabrications.
15
+ *
16
+ * # Why it exists
17
+ *
18
+ * Phase 3-4 A3 benchmark (2026-04-17) demonstrated that inline mode + path-only
19
+ * packet caused Qwen3-30B-A3B to emit a quoted axiology finding
20
+ * (`Axiology said "Naming alignment between value, activity, and concept is
21
+ * not yet resolved"`) that grep returned 0 matches for across all three lens
22
+ * outputs. The model hallucinated a citation to support its deliberation.
23
+ * The same run also produced 3 quoted taxonomy labels that substring-matched
24
+ * no lens but were not fabrications. Without attribution classification those
25
+ * three labels produced noise warnings and diluted operator attention to the
26
+ * real fabrication.
27
+ *
28
+ * A4 (PR #74) blocks the known precondition (`Tools: required` + inline) at
29
+ * executor entry; the audit here is a **defense-in-depth** layer that catches
30
+ * fabrications from:
31
+ * - packets that don't declare `Tools: required`
32
+ * - partially-inlined packets where some lens content is embedded and some
33
+ * is referenced by path
34
+ * - native-mode runs where the model read a file but still made up a quote
35
+ * - future prompt regressions that could reintroduce fabrication
36
+ *
37
+ * # What it does NOT do
38
+ *
39
+ * - It does not block execution. The audit is **warning-only** per the A5
40
+ * design: an unmatched quote is a suspicion, not a proof.
41
+ * - It does not parse semantic meaning. Only literal substring matching.
42
+ * - It does not audit LENS outputs. Lens outputs don't cite each other; they
43
+ * cite the review target.
44
+ *
45
+ * # Grammar
46
+ *
47
+ * Quotes are extracted from:
48
+ * - `"..."` — straight double-quoted strings
49
+ * - `` `...` `` — backtick-quoted (markdown code spans)
50
+ *
51
+ * Strings shorter than `minQuoteLength` (default 20) are skipped as noise.
52
+ *
53
+ * # Attribution classification
54
+ *
55
+ * A quote is attribution-style when any of the following patterns appears
56
+ * within the preceding `ATTRIBUTION_CONTEXT_WINDOW` characters (up to the
57
+ * previous sentence boundary):
58
+ *
59
+ * - `<lens>:` / `**<lens>**:` / `*<lens>*:` — colon-style attribution
60
+ * - `per <lens>` / `from <lens>` / `according to <lens>`
61
+ * - `<Lens> said|reports|notes|claims|states|asserts|finds`
62
+ * - `<Lens> lens said|...`
63
+ * - `cited from <lens>` / `cited_lens_output <lens>`
64
+ *
65
+ * The `<lens>` token is any of the nine review lenses or `synthesize`.
66
+ * Case-insensitive.
67
+ */
68
+ const DEFAULT_MIN_QUOTE_LENGTH = 20;
69
+ const ATTRIBUTION_CONTEXT_WINDOW = 120;
70
+ const LENS_IDS = [
71
+ "logic",
72
+ "structure",
73
+ "dependency",
74
+ "semantics",
75
+ "pragmatics",
76
+ "evolution",
77
+ "coverage",
78
+ "conciseness",
79
+ "axiology",
80
+ "synthesize",
81
+ ];
82
+ const LENS_ALT = LENS_IDS.join("|");
83
+ const ATTRIBUTION_REGEXES = [
84
+ // `axiology:` / `**axiology**:` / `*axiology*:`
85
+ // The markdown-emphasis variant uses its own asterisk anchors, so `\b` only
86
+ // guards the bare form. Without the split alternation we'd fail because
87
+ // `\b` does not exist between start-of-slice and `*` (both non-word).
88
+ new RegExp(`(?:\\*{1,2}(${LENS_ALT})\\*{1,2}|\\b(${LENS_ALT}))\\s*:\\s*$`, "i"),
89
+ // `per axiology` / `from axiology` / `according to axiology`
90
+ new RegExp(`\\b(?:per|from|according\\s+to)\\s+(${LENS_ALT})\\b[^"\`]*$`, "i"),
91
+ // `Axiology said` / `logic lens reports` / `semantics claims`
92
+ new RegExp(`\\b(${LENS_ALT})(?:\\s+lens)?\\s+(?:said|reports?|notes?|claims?|states?|asserts?|finds?)\\b[^"\`]*$`, "i"),
93
+ // `cited from logic` / `cited_lens_output axiology`
94
+ new RegExp(`\\b(?:cited\\s+from|cited_lens_output)\\s+(${LENS_ALT})\\b[^"\`]*$`, "i"),
95
+ ];
96
+ /**
97
+ * Return the substring of `text` immediately preceding `offset`, cut back to
98
+ * the previous sentence boundary (period, newline, start of text) and capped
99
+ * at `ATTRIBUTION_CONTEXT_WINDOW` characters. This is the "same sentence"
100
+ * window the attribution classifier examines.
101
+ */
102
+ function precedingContext(text, offset) {
103
+ const start = Math.max(0, offset - ATTRIBUTION_CONTEXT_WINDOW);
104
+ let slice = text.slice(start, offset);
105
+ // Cut back to the last sentence boundary within the window so attribution
106
+ // claims in the preceding sentence don't spill into this one's classification.
107
+ const boundary = Math.max(slice.lastIndexOf("."), slice.lastIndexOf("\n"), slice.lastIndexOf("?"), slice.lastIndexOf("!"));
108
+ if (boundary >= 0)
109
+ slice = slice.slice(boundary + 1);
110
+ return slice;
111
+ }
112
+ function classifyAttribution(precedingText) {
113
+ for (const re of ATTRIBUTION_REGEXES) {
114
+ const m = precedingText.match(re);
115
+ if (m) {
116
+ const lens = m.slice(1).find((g) => typeof g === "string" && g.length > 0);
117
+ return lens
118
+ ? { is_attribution: true, attributed_lens: lens.toLowerCase() }
119
+ : { is_attribution: true };
120
+ }
121
+ }
122
+ return { is_attribution: false };
123
+ }
124
+ /**
125
+ * Extract significant quoted strings from free-form markdown text, keeping
126
+ * per-quote attribution classification.
127
+ *
128
+ * De-duplicates identical quote *texts*. When the same text appears multiple
129
+ * times with different attribution, the first occurrence's classification is
130
+ * kept — matching the "any attribution → warning-worthy" spirit of the audit.
131
+ * (Detailed per-occurrence introspection is out of scope here.)
132
+ */
133
+ export function extractSignificantQuotes(text, options) {
134
+ const min = options?.minQuoteLength ?? DEFAULT_MIN_QUOTE_LENGTH;
135
+ const out = [];
136
+ const seen = new Set();
137
+ const doubleRe = /"([^"\n]+(?:\n[^"\n]+)?)"/g;
138
+ for (const m of text.matchAll(doubleRe)) {
139
+ const body = (m[1] ?? "").trim();
140
+ if (body.length < min)
141
+ continue;
142
+ if (seen.has(body))
143
+ continue;
144
+ seen.add(body);
145
+ const offset = m.index ?? 0;
146
+ const preceding = precedingContext(text, offset);
147
+ const { is_attribution, attributed_lens } = classifyAttribution(preceding);
148
+ out.push({
149
+ text: body,
150
+ offset,
151
+ is_attribution,
152
+ ...(attributed_lens !== undefined ? { attributed_lens } : {}),
153
+ });
154
+ }
155
+ const backtickRe = /`([^`\n]+)`/g;
156
+ for (const m of text.matchAll(backtickRe)) {
157
+ const body = (m[1] ?? "").trim();
158
+ if (body.length < min)
159
+ continue;
160
+ if (seen.has(body))
161
+ continue;
162
+ seen.add(body);
163
+ const offset = m.index ?? 0;
164
+ const preceding = precedingContext(text, offset);
165
+ const { is_attribution, attributed_lens } = classifyAttribution(preceding);
166
+ out.push({
167
+ text: body,
168
+ offset,
169
+ is_attribution,
170
+ ...(attributed_lens !== undefined ? { attributed_lens } : {}),
171
+ });
172
+ }
173
+ out.sort((a, b) => a.offset - b.offset);
174
+ return out;
175
+ }
176
+ /**
177
+ * Run citation audit: extract significant quotes from synthesize output,
178
+ * classify by attribution, then substring-match against each lens content.
179
+ */
180
+ export function auditCitations(synthesizeText, lensContents, options) {
181
+ const min = options?.minQuoteLength ?? DEFAULT_MIN_QUOTE_LENGTH;
182
+ const quotes = extractSignificantQuotes(synthesizeText, { minQuoteLength: min });
183
+ const unmatched_strict = [];
184
+ const unmatched_meta = [];
185
+ let attribution_count = 0;
186
+ for (const q of quotes) {
187
+ if (q.is_attribution)
188
+ attribution_count += 1;
189
+ const matched = lensContents.some((content) => content.includes(q.text));
190
+ if (matched)
191
+ continue;
192
+ if (q.is_attribution)
193
+ unmatched_strict.push(q.text);
194
+ else
195
+ unmatched_meta.push(q.text);
196
+ }
197
+ return {
198
+ quotes_checked: quotes.length,
199
+ quotes_unmatched: unmatched_strict,
200
+ quotes_unmatched_meta: unmatched_meta,
201
+ attribution_count,
202
+ min_quote_length: min,
203
+ };
204
+ }
@@ -0,0 +1,165 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { auditCitations, extractSignificantQuotes } from "./citation-audit.js";
3
+ describe("extractSignificantQuotes", () => {
4
+ it("extracts double-quoted strings above threshold", () => {
5
+ const text = 'The lens said "Top-level value lacks operational backing" in evidence.';
6
+ const quotes = extractSignificantQuotes(text);
7
+ expect(quotes.map((q) => q.text)).toContain("Top-level value lacks operational backing");
8
+ });
9
+ it("extracts backtick code spans above threshold", () => {
10
+ const text = "The evidence is at `src/core-runtime/scope-runtime/state-machine.ts` in the module.";
11
+ const quotes = extractSignificantQuotes(text);
12
+ expect(quotes.map((q) => q.text)).toContain("src/core-runtime/scope-runtime/state-machine.ts");
13
+ });
14
+ it("skips quotes below threshold (default 20)", () => {
15
+ const text = 'The status is "performed" for now, file `x.ts`.';
16
+ const quotes = extractSignificantQuotes(text).map((q) => q.text);
17
+ expect(quotes).not.toContain("performed");
18
+ expect(quotes).not.toContain("x.ts");
19
+ });
20
+ it("respects a custom threshold", () => {
21
+ const text = "File `x.ts` matters.";
22
+ const quotes = extractSignificantQuotes(text, { minQuoteLength: 3 });
23
+ expect(quotes.map((q) => q.text)).toContain("x.ts");
24
+ });
25
+ it("de-duplicates identical quotes", () => {
26
+ const text = '"Declaration without operational backing" appears here and "Declaration without operational backing" again.';
27
+ const quotes = extractSignificantQuotes(text);
28
+ expect(quotes.filter((q) => q.text === "Declaration without operational backing").length).toBe(1);
29
+ });
30
+ it("handles multi-line quote bodies (single newline tolerated)", () => {
31
+ const text = '"Line one of a long citation\nthat wraps across one linebreak"';
32
+ const quotes = extractSignificantQuotes(text);
33
+ expect(quotes[0]?.text.includes("Line one")).toBe(true);
34
+ });
35
+ it("does not extract from triple-backtick code fences as code spans", () => {
36
+ const text = "Before\n```ts\nconst x = 1;\n```\nAfter";
37
+ const quotes = extractSignificantQuotes(text);
38
+ expect(quotes.length).toBe(0);
39
+ });
40
+ it("returns empty array when no quoted strings present", () => {
41
+ const text = "Pure prose with no quotations or backtick spans above threshold.";
42
+ expect(extractSignificantQuotes(text)).toEqual([]);
43
+ });
44
+ });
45
+ describe("attribution classification", () => {
46
+ it("classifies `<lens>:` colon attribution", () => {
47
+ const text = 'axiology: "Declaration without operational grounding detected"';
48
+ const [q] = extractSignificantQuotes(text);
49
+ expect(q?.is_attribution).toBe(true);
50
+ expect(q?.attributed_lens).toBe("axiology");
51
+ });
52
+ it("classifies `**<lens>**:` bold attribution", () => {
53
+ const text = '**logic**: "Circular dependency across module boundary"';
54
+ const [q] = extractSignificantQuotes(text);
55
+ expect(q?.is_attribution).toBe(true);
56
+ expect(q?.attributed_lens).toBe("logic");
57
+ });
58
+ it("classifies verb attribution (said / reports / claims)", () => {
59
+ const texts = [
60
+ 'Axiology said "purpose-value misalignment in executor"',
61
+ "Logic reports \"tier-level equivalence cannot be decided\"",
62
+ 'Semantics claims "synonymous terms not consolidated"',
63
+ ];
64
+ for (const text of texts) {
65
+ const [q] = extractSignificantQuotes(text);
66
+ expect(q?.is_attribution).toBe(true);
67
+ }
68
+ });
69
+ it("classifies `<Lens> lens said` phrasing", () => {
70
+ const text = 'Coverage lens notes "sub-area missing from scope"';
71
+ const [q] = extractSignificantQuotes(text);
72
+ expect(q?.is_attribution).toBe(true);
73
+ expect(q?.attributed_lens).toBe("coverage");
74
+ });
75
+ it("classifies `per <lens>` / `from <lens>` / `according to <lens>` prefix", () => {
76
+ const texts = [
77
+ 'per logic, "tier-equivalence can be demonstrated structurally"',
78
+ 'from structure: "isolated node in dependency graph found"',
79
+ 'according to pragmatics: "usage context narrows applicability"',
80
+ ];
81
+ for (const text of texts) {
82
+ const [q] = extractSignificantQuotes(text);
83
+ expect(q?.is_attribution).toBe(true);
84
+ }
85
+ });
86
+ it("does NOT classify a bare quote without a nearby lens reference", () => {
87
+ const text = 'The synthesis includes a "conditional consensus" section per the canonical taxonomy.';
88
+ const [q] = extractSignificantQuotes(text);
89
+ expect(q?.is_attribution).toBe(false);
90
+ expect(q?.attributed_lens).toBeUndefined();
91
+ });
92
+ it("does NOT leak attribution across sentence boundaries", () => {
93
+ // Lens reference is in the previous sentence; quote here is a bare concept
94
+ // label, not an attributed citation.
95
+ const text = 'Axiology covered the purpose axis. Elsewhere the report discusses "conditional consensus" as a taxonomy label.';
96
+ const quotes = extractSignificantQuotes(text);
97
+ const taxonomy = quotes.find((q) => q.text === "conditional consensus");
98
+ expect(taxonomy?.is_attribution).toBe(false);
99
+ });
100
+ });
101
+ describe("auditCitations", () => {
102
+ it("flags an attribution-style fabrication in quotes_unmatched (the A3 case)", () => {
103
+ const synthesize = "### Disagreement\n" +
104
+ '- Axiology said "Naming alignment between value, activity, and concept is not yet resolved".';
105
+ const axiologyLens = "Findings: Top-level value 시간/비용 최소화 lacks operational backing in executor.";
106
+ const depLens = "Authority chain integrity circular between core-lexicon.yaml and .onto/principles/.";
107
+ const structLens = "Naming alignment resolved as of W-A-77.";
108
+ const result = auditCitations(synthesize, [axiologyLens, depLens, structLens]);
109
+ expect(result.quotes_checked).toBe(1);
110
+ expect(result.attribution_count).toBe(1);
111
+ expect(result.quotes_unmatched).toContain("Naming alignment between value, activity, and concept is not yet resolved");
112
+ expect(result.quotes_unmatched_meta).toEqual([]);
113
+ });
114
+ it("routes non-attribution unmatched quotes to quotes_unmatched_meta (taxonomy labels)", () => {
115
+ const synthesize = 'The section is titled "conditional consensus" per the canonical taxonomy, and separately "cross-process deliberation" appears as a meta-concept.';
116
+ const lensA = "Irrelevant lens body without any taxonomy phrase.";
117
+ const result = auditCitations(synthesize, [lensA]);
118
+ // Both taxonomy labels are above threshold 20 and unmatched.
119
+ expect(result.quotes_unmatched).toEqual([]);
120
+ expect(result.quotes_unmatched_meta.length).toBeGreaterThanOrEqual(1);
121
+ // Neither was an attribution citation.
122
+ expect(result.attribution_count).toBe(0);
123
+ });
124
+ it("passes an attribution-style quote that substring-matches a lens", () => {
125
+ const synthesize = 'axiology: "Top-level value 시간/비용 최소화 lacks operational backing"';
126
+ const lensContent = "Findings: Top-level value 시간/비용 최소화 lacks operational backing in executor selection.";
127
+ const result = auditCitations(synthesize, [lensContent]);
128
+ expect(result.quotes_checked).toBe(1);
129
+ expect(result.attribution_count).toBe(1);
130
+ expect(result.quotes_unmatched).toEqual([]);
131
+ expect(result.quotes_unmatched_meta).toEqual([]);
132
+ });
133
+ it("matches against any lens (disjunction)", () => {
134
+ const synthesize = 'logic: "unique phrase of sufficient length here"';
135
+ const lensA = "not related content at all";
136
+ const lensB = "some prose containing unique phrase of sufficient length here inside it";
137
+ const result = auditCitations(synthesize, [lensA, lensB]);
138
+ expect(result.quotes_unmatched).toEqual([]);
139
+ expect(result.quotes_unmatched_meta).toEqual([]);
140
+ });
141
+ it("reports empty unmatched lists when no quotes present", () => {
142
+ const result = auditCitations("Pure synthesis prose.", ["some lens content"]);
143
+ expect(result.quotes_checked).toBe(0);
144
+ expect(result.quotes_unmatched).toEqual([]);
145
+ expect(result.quotes_unmatched_meta).toEqual([]);
146
+ expect(result.attribution_count).toBe(0);
147
+ });
148
+ it("includes min_quote_length in result for traceability", () => {
149
+ const result = auditCitations("", [], { minQuoteLength: 30 });
150
+ expect(result.min_quote_length).toBe(30);
151
+ });
152
+ it("uses default threshold 20 when options omitted", () => {
153
+ const result = auditCitations("", []);
154
+ expect(result.min_quote_length).toBe(20);
155
+ });
156
+ it("empty lens pool: attribution unmatched → strict, non-attribution → meta", () => {
157
+ const synthesize = 'logic: "attribution style phrase of sufficient length for threshold"\n' +
158
+ 'Separately, "non-attributed taxonomy label phrase here" appears.';
159
+ const result = auditCitations(synthesize, []);
160
+ expect(result.quotes_checked).toBe(2);
161
+ expect(result.attribution_count).toBe(1);
162
+ expect(result.quotes_unmatched).toContain("attribution style phrase of sufficient length for threshold");
163
+ expect(result.quotes_unmatched_meta).toContain("non-attributed taxonomy label phrase here");
164
+ });
165
+ });
@@ -0,0 +1,125 @@
1
+ function fencedBlock(label, content) {
2
+ return [`### ${label}`, "", content.trim() || "(empty)"].join("\n");
3
+ }
4
+ export function buildLensControlledDeliberationPrompt(args) {
5
+ const otherBlocks = args.other_outputs
6
+ .map((other) => fencedBlock(`${other.lens_id} primary output (${other.output_path})`, other.content))
7
+ .join("\n\n---\n\n");
8
+ return `# Controlled Lens Deliberation Prompt
9
+
10
+ session_id: ${args.session_id}
11
+ unit_id: deliberation-${args.lens_id}
12
+ unit_kind: deliberation
13
+ lens_id: ${args.lens_id}
14
+ output_path: ${args.output_path}
15
+
16
+ ## Canonical Role
17
+ You are the ${args.lens_id} lens participating in controlled lens deliberation.
18
+ This is a fresh bounded context. You receive only your primary lens output and
19
+ the other participating lens outputs. The teamlead controls this context; do not
20
+ perform final synthesis and do not inspect extra repository files.
21
+
22
+ ## Own Primary Lens Output
23
+ ${fencedBlock(`${args.lens_id} primary output (${args.own_output.output_path})`, args.own_output.content)}
24
+
25
+ ## Other Participating Lens Outputs
26
+ ${otherBlocks || "(none)"}
27
+
28
+ ## Issue Artifact Context
29
+ ${args.issue_artifact_context?.trim() || "(none)"}
30
+
31
+ ## Task
32
+ Re-evaluate your lens position against the other lens outputs.
33
+
34
+ - Identify where another lens changes, strengthens, or weakens your conclusion.
35
+ - If no other lens output is provided, state that no cross-lens contest is
36
+ available and preserve your bounded primary position.
37
+ - Use the issue artifact context to focus on root-cause issue clusters and planned contested points.
38
+ - Identify direct disagreements and state whether your lens concedes, narrows,
39
+ or maintains its position.
40
+ - Preserve evidence limitations explicitly.
41
+ - Do not decide the final review outcome. The teamlead deliberation result will
42
+ resolve or preserve contested points after reading every lens response.
43
+
44
+ ## Required Output Sections
45
+ Use exactly these heading names:
46
+
47
+ \`\`\`
48
+ ## Re-evaluation Summary
49
+ ## Accepted From Other Lenses
50
+ ## Contested Points
51
+ ## Position Changes
52
+ ## Final Lens Position
53
+ \`\`\`
54
+
55
+ Write only the markdown body for your deliberation response.`;
56
+ }
57
+ export function buildTeamleadControlledDeliberationPrompt(args) {
58
+ const primaryBlocks = args.lens_outputs
59
+ .map((lens) => fencedBlock(`${lens.lens_id} primary output (${lens.output_path})`, lens.content))
60
+ .join("\n\n---\n\n");
61
+ const responseBlocks = args.lens_deliberation_responses
62
+ .map((response) => fencedBlock(`${response.lens_id} deliberation response (${response.response_path})`, response.content))
63
+ .join("\n\n---\n\n");
64
+ return `# Teamlead Controlled Deliberation Prompt
65
+
66
+ session_id: ${args.session_id}
67
+ unit_id: controlled-deliberation
68
+ unit_kind: deliberation
69
+ output_path: ${args.output_path}
70
+
71
+ ## Canonical Role
72
+ You are the teamlead-controlled deliberation resolver. Your job is to derive the
73
+ controlled deliberation result from lens primary outputs and lens deliberation
74
+ responses. You are not the final synthesize actor.
75
+
76
+ ## Inputs In Scope
77
+ Only the material below is in scope.
78
+
79
+ ## Primary Lens Outputs
80
+ ${primaryBlocks}
81
+
82
+ ## Lens Deliberation Responses
83
+ ${responseBlocks}
84
+
85
+ ## Issue Artifact Context
86
+ ${args.issue_artifact_context?.trim() || "(none)"}
87
+
88
+ ## Task
89
+ Resolve contested points when the lens deliberation responses provide enough
90
+ reason to converge. Preserve unresolved disagreement when the responses do not
91
+ justify convergence. Do not invent a new lens perspective.
92
+ If only one lens participates, record that cross-lens disagreement is not
93
+ applicable for this run and preserve the single lens position as bounded
94
+ evidence, not as multi-lens consensus.
95
+ Use the issue artifact context as the root-cause issue frame; preserve issue IDs
96
+ and planned contested points when they are present.
97
+
98
+ ## Required Frontmatter
99
+ Start the output with:
100
+
101
+ \`\`\`
102
+ ---
103
+ deliberation_status: performed
104
+ ---
105
+ \`\`\`
106
+
107
+ ## Required Output Sections
108
+ Use exactly these heading names. The final synthesize stage consumes this file
109
+ as the authoritative deliberation result.
110
+
111
+ \`\`\`
112
+ ## Consensus
113
+ ## Conditional Consensus
114
+ ## Disagreement
115
+ ## Deliberation Decision
116
+ ## Axiology-Proposed Additional Perspectives
117
+ ## Purpose Alignment Verification
118
+ ## Immediate Actions Required
119
+ ## Recommendations
120
+ ## Unique Finding Tagging
121
+ \`\`\`
122
+
123
+ The Deliberation Decision section must map every contested point to one of:
124
+ resolved, narrowed, or unresolved-with-reason.`;
125
+ }