onto-mcp 0.3.2 → 0.4.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 (300) hide show
  1. package/.onto/processes/reconstruct/actionable-ontology-seed-recomposition-design.md +447 -0
  2. package/.onto/processes/reconstruct/foundry-style-ontology-seed-contract.md +934 -0
  3. package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +303 -725
  4. package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +1645 -0
  5. package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +26 -22
  6. package/.onto/processes/reconstruct/source-profile-contract.md +49 -23
  7. package/.onto/processes/reconstruct/source-profiles/code.md +6 -3
  8. package/.onto/processes/reconstruct/source-profiles/database.md +5 -2
  9. package/.onto/processes/reconstruct/source-profiles/document.md +5 -2
  10. package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +5 -4
  11. package/.onto/processes/review/review-execution-ux-contract.md +40 -0
  12. package/.onto/processes/shared/pipeline-execution-ledger-contract.md +26 -10
  13. package/.onto/processes/shared/target-material-kind-contract.md +29 -16
  14. package/AGENTS.md +6 -4
  15. package/README.md +135 -76
  16. package/dist/cli.js +8 -8
  17. package/dist/core-api/reconstruct-api.js +117 -31
  18. package/dist/core-api/review-api.js +47 -0
  19. package/dist/core-runtime/cli/codex-review-unit-executor.js +39 -2
  20. package/dist/core-runtime/cli/complete-review-session.js +2 -2
  21. package/dist/core-runtime/cli/mock-review-unit-executor.js +1 -1
  22. package/dist/core-runtime/cli/review-invoke.js +9 -9
  23. package/dist/core-runtime/cli/run-review-prompt-execution.js +39 -5
  24. package/dist/core-runtime/cli/spawn-watcher.js +266 -47
  25. package/dist/core-runtime/cli/start-review-session.js +3 -3
  26. package/dist/core-runtime/llm/llm-caller.js +11 -0
  27. package/dist/core-runtime/llm/llm-tool-loop.js +2 -0
  28. package/dist/core-runtime/observability/runtime-stream-observation.js +118 -0
  29. package/dist/core-runtime/onboard/cli-host.js +149 -0
  30. package/dist/core-runtime/onboard/host-target.js +22 -0
  31. package/dist/core-runtime/onboard/json-config-host.js +122 -0
  32. package/dist/core-runtime/onboard/path-scan.js +26 -0
  33. package/dist/core-runtime/onboard/prompt.js +51 -0
  34. package/dist/core-runtime/onboard/register.js +207 -0
  35. package/dist/core-runtime/onboard/types.js +27 -0
  36. package/dist/core-runtime/reconstruct/actionable-seed-validation.js +1777 -0
  37. package/dist/core-runtime/reconstruct/artifact-types.js +10 -4
  38. package/dist/core-runtime/reconstruct/contract-registry.js +623 -0
  39. package/dist/core-runtime/reconstruct/domain-id.js +10 -0
  40. package/dist/core-runtime/reconstruct/governing-snapshot.js +716 -0
  41. package/dist/core-runtime/reconstruct/material-profile-validation.js +191 -0
  42. package/dist/core-runtime/reconstruct/materialize-preparation.js +49 -11
  43. package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +269 -79
  44. package/dist/core-runtime/reconstruct/post-seed-validation.js +1194 -51
  45. package/dist/core-runtime/reconstruct/record.js +104 -20
  46. package/dist/core-runtime/reconstruct/run.js +2107 -413
  47. package/dist/core-runtime/reconstruct/seed-claim-projections.js +268 -0
  48. package/dist/core-runtime/reconstruct/source-profiles.js +93 -4
  49. package/dist/core-runtime/reconstruct/terminal-validation.js +807 -0
  50. package/dist/core-runtime/review/review-invocation-runner.js +4 -4
  51. package/dist/mcp/server.js +110 -38
  52. package/dist/mcp/tool-schemas.js +20 -6
  53. package/package.json +8 -17
  54. package/scripts/onto-review-watch.sh +486 -0
  55. package/scripts/onto-runtime-watch.sh +122 -0
  56. package/scripts/postinstall-hint.js +22 -0
  57. package/.onto/processes/reconstruct/top-level-concept-discovery-contract.md +0 -387
  58. package/dist/core-runtime/cli/bootstrap-review-binding.js +0 -186
  59. package/dist/core-runtime/cli/codex-nested-dispatch.test.js +0 -390
  60. package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +0 -335
  61. package/dist/core-runtime/cli/coordinator-helpers.js +0 -583
  62. package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +0 -167
  63. package/dist/core-runtime/cli/coordinator-state-machine.js +0 -794
  64. package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +0 -615
  65. package/dist/core-runtime/cli/e2e-start-review-session.test.js +0 -312
  66. package/dist/core-runtime/cli/health.js +0 -44
  67. package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +0 -567
  68. package/dist/core-runtime/cli/materialize-review-execution-preparation.js +0 -104
  69. package/dist/core-runtime/cli/migrate-session-roots.js +0 -118
  70. package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +0 -106
  71. package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +0 -268
  72. package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +0 -136
  73. package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +0 -201
  74. package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +0 -192
  75. package/dist/core-runtime/cli/session-root-guard.js +0 -168
  76. package/dist/core-runtime/cli/spawn-watcher.test.js +0 -457
  77. package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +0 -79
  78. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +0 -412
  79. package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +0 -351
  80. package/dist/core-runtime/cli/topology-executor-mapping.js +0 -139
  81. package/dist/core-runtime/cli/topology-executor-mapping.test.js +0 -173
  82. package/dist/core-runtime/cli/write-review-interpretation.js +0 -81
  83. package/dist/core-runtime/config/onto-config-cli.js +0 -278
  84. package/dist/core-runtime/config/onto-config-key-path.js +0 -288
  85. package/dist/core-runtime/config/onto-config-key-path.test.js +0 -195
  86. package/dist/core-runtime/config/onto-config-preview.js +0 -108
  87. package/dist/core-runtime/config/onto-config-preview.test.js +0 -132
  88. package/dist/core-runtime/discovery/config-chain.js +0 -118
  89. package/dist/core-runtime/discovery/config-chain.test.js +0 -103
  90. package/dist/core-runtime/discovery/config-profile.js +0 -199
  91. package/dist/core-runtime/discovery/config-profile.test.js +0 -233
  92. package/dist/core-runtime/discovery/host-detection.test.js +0 -186
  93. package/dist/core-runtime/discovery/installation-paths.test.js +0 -65
  94. package/dist/core-runtime/discovery/lens-registry.test.js +0 -81
  95. package/dist/core-runtime/discovery/path-normalization.test.js +0 -22
  96. package/dist/core-runtime/discovery/plugin-path.js +0 -72
  97. package/dist/core-runtime/discovery/plugin-path.test.js +0 -95
  98. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +0 -344
  99. package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +0 -915
  100. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +0 -564
  101. package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +0 -708
  102. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +0 -165
  103. package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +0 -227
  104. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +0 -59
  105. package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +0 -205
  106. package/dist/core-runtime/evolve/adapters/methodology/adapter.js +0 -16
  107. package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +0 -9
  108. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +0 -298
  109. package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +0 -70
  110. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +0 -46
  111. package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +0 -73
  112. package/dist/core-runtime/evolve/adapters/registry.js +0 -47
  113. package/dist/core-runtime/evolve/adapters/registry.test.js +0 -67
  114. package/dist/core-runtime/evolve/cli.js +0 -256
  115. package/dist/core-runtime/evolve/commands/align.js +0 -194
  116. package/dist/core-runtime/evolve/commands/align.test.js +0 -82
  117. package/dist/core-runtime/evolve/commands/apply.js +0 -161
  118. package/dist/core-runtime/evolve/commands/apply.test.js +0 -138
  119. package/dist/core-runtime/evolve/commands/close.js +0 -39
  120. package/dist/core-runtime/evolve/commands/close.test.js +0 -99
  121. package/dist/core-runtime/evolve/commands/defer.js +0 -40
  122. package/dist/core-runtime/evolve/commands/defer.test.js +0 -134
  123. package/dist/core-runtime/evolve/commands/draft.js +0 -323
  124. package/dist/core-runtime/evolve/commands/draft.test.js +0 -178
  125. package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +0 -208
  126. package/dist/core-runtime/evolve/commands/error-messages.js +0 -125
  127. package/dist/core-runtime/evolve/commands/error-messages.test.js +0 -167
  128. package/dist/core-runtime/evolve/commands/propose-align.js +0 -222
  129. package/dist/core-runtime/evolve/commands/propose-align.test.js +0 -136
  130. package/dist/core-runtime/evolve/commands/reconstruct.js +0 -330
  131. package/dist/core-runtime/evolve/commands/reconstruct.test.js +0 -278
  132. package/dist/core-runtime/evolve/commands/shared.js +0 -22
  133. package/dist/core-runtime/evolve/commands/stale-check.js +0 -103
  134. package/dist/core-runtime/evolve/commands/stale-check.test.js +0 -84
  135. package/dist/core-runtime/evolve/commands/start.js +0 -887
  136. package/dist/core-runtime/evolve/commands/start.test.js +0 -396
  137. package/dist/core-runtime/evolve/config/project-config.js +0 -99
  138. package/dist/core-runtime/evolve/config/project-config.test.js +0 -170
  139. package/dist/core-runtime/evolve/renderers/align-packet.js +0 -280
  140. package/dist/core-runtime/evolve/renderers/align-packet.test.js +0 -332
  141. package/dist/core-runtime/evolve/renderers/draft-packet.js +0 -303
  142. package/dist/core-runtime/evolve/renderers/draft-packet.test.js +0 -377
  143. package/dist/core-runtime/evolve/renderers/format.js +0 -5
  144. package/dist/core-runtime/evolve/renderers/scope-md.js +0 -237
  145. package/dist/core-runtime/evolve/renderers/scope-md.test.js +0 -306
  146. package/dist/core-runtime/govern/cli.js +0 -369
  147. package/dist/core-runtime/govern/cli.test.js +0 -314
  148. package/dist/core-runtime/govern/drift-engine.js +0 -103
  149. package/dist/core-runtime/govern/drift-engine.test.js +0 -319
  150. package/dist/core-runtime/govern/promote-principle.js +0 -206
  151. package/dist/core-runtime/govern/promote-principle.test.js +0 -368
  152. package/dist/core-runtime/govern/queue.js +0 -81
  153. package/dist/core-runtime/govern/types.js +0 -16
  154. package/dist/core-runtime/install/cli.js +0 -530
  155. package/dist/core-runtime/install/detect.js +0 -128
  156. package/dist/core-runtime/install/detect.test.js +0 -155
  157. package/dist/core-runtime/install/gitignore-update.js +0 -74
  158. package/dist/core-runtime/install/gitignore-update.test.js +0 -64
  159. package/dist/core-runtime/install/install-integration.test.js +0 -373
  160. package/dist/core-runtime/install/prompts.js +0 -389
  161. package/dist/core-runtime/install/prompts.test.js +0 -293
  162. package/dist/core-runtime/install/types.js +0 -26
  163. package/dist/core-runtime/install/validation.js +0 -295
  164. package/dist/core-runtime/install/validation.test.js +0 -313
  165. package/dist/core-runtime/install/writer.js +0 -254
  166. package/dist/core-runtime/install/writer.test.js +0 -218
  167. package/dist/core-runtime/learning/extractor.js +0 -461
  168. package/dist/core-runtime/learning/feedback.js +0 -179
  169. package/dist/core-runtime/learning/health-report.js +0 -165
  170. package/dist/core-runtime/learning/health-report.test.js +0 -169
  171. package/dist/core-runtime/learning/loader.js +0 -388
  172. package/dist/core-runtime/learning/loader.test.js +0 -102
  173. package/dist/core-runtime/learning/promote/apply-state.js +0 -240
  174. package/dist/core-runtime/learning/promote/audit-obligation.js +0 -195
  175. package/dist/core-runtime/learning/promote/collector.js +0 -432
  176. package/dist/core-runtime/learning/promote/degraded-state.js +0 -125
  177. package/dist/core-runtime/learning/promote/domain-doc-proposer.js +0 -166
  178. package/dist/core-runtime/learning/promote/e2e-promote.test.js +0 -6385
  179. package/dist/core-runtime/learning/promote/health-snapshot.js +0 -150
  180. package/dist/core-runtime/learning/promote/insight-reclassifier.js +0 -544
  181. package/dist/core-runtime/learning/promote/judgment-auditor.js +0 -517
  182. package/dist/core-runtime/learning/promote/panel-reviewer.js +0 -1158
  183. package/dist/core-runtime/learning/promote/promote-executor.js +0 -1675
  184. package/dist/core-runtime/learning/promote/promoter.js +0 -307
  185. package/dist/core-runtime/learning/promote/retirement.js +0 -122
  186. package/dist/core-runtime/learning/promote/types.js +0 -23
  187. package/dist/core-runtime/learning/prompt-sections.js +0 -51
  188. package/dist/core-runtime/learning/shared/artifact-registry-init.js +0 -45
  189. package/dist/core-runtime/learning/shared/artifact-registry.js +0 -254
  190. package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +0 -73
  191. package/dist/core-runtime/learning/shared/audit-state.js +0 -99
  192. package/dist/core-runtime/learning/shared/duplicate-check.js +0 -28
  193. package/dist/core-runtime/learning/shared/llm-caller.js +0 -831
  194. package/dist/core-runtime/learning/shared/llm-caller.test.js +0 -601
  195. package/dist/core-runtime/learning/shared/llm-tool-loop.js +0 -393
  196. package/dist/core-runtime/learning/shared/mode.js +0 -25
  197. package/dist/core-runtime/learning/shared/paths.js +0 -84
  198. package/dist/core-runtime/learning/shared/paths.test.js +0 -79
  199. package/dist/core-runtime/learning/shared/patterns.js +0 -37
  200. package/dist/core-runtime/learning/shared/recoverability.js +0 -355
  201. package/dist/core-runtime/learning/shared/recovery-context.js +0 -374
  202. package/dist/core-runtime/learning/shared/scope.js +0 -1
  203. package/dist/core-runtime/learning/shared/semantic-classifier.js +0 -94
  204. package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +0 -42
  205. package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +0 -37
  206. package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +0 -39
  207. package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +0 -41
  208. package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +0 -38
  209. package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +0 -43
  210. package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +0 -113
  211. package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +0 -36
  212. package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +0 -48
  213. package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +0 -43
  214. package/dist/core-runtime/learning/shared/specs/spec-helpers.js +0 -64
  215. package/dist/core-runtime/learning/usage-tracker.js +0 -190
  216. package/dist/core-runtime/learning/usage-tracker.test.js +0 -176
  217. package/dist/core-runtime/onboard/detect-review-axes.js +0 -122
  218. package/dist/core-runtime/onboard/detect-review-axes.test.js +0 -127
  219. package/dist/core-runtime/onboard/write-review-block.js +0 -188
  220. package/dist/core-runtime/onboard/write-review-block.test.js +0 -240
  221. package/dist/core-runtime/readers/brownfield-builder.js +0 -150
  222. package/dist/core-runtime/readers/brownfield-builder.test.js +0 -136
  223. package/dist/core-runtime/readers/code-chunk-collector.js +0 -53
  224. package/dist/core-runtime/readers/code-chunk-collector.test.js +0 -136
  225. package/dist/core-runtime/readers/file-utils.js +0 -240
  226. package/dist/core-runtime/readers/file-utils.test.js +0 -146
  227. package/dist/core-runtime/readers/lexicon-citation-check.js +0 -93
  228. package/dist/core-runtime/readers/lexicon-citation-check.test.js +0 -77
  229. package/dist/core-runtime/readers/mcp-figma.js +0 -30
  230. package/dist/core-runtime/readers/mcp-figma.test.js +0 -82
  231. package/dist/core-runtime/readers/mcp-generic.js +0 -31
  232. package/dist/core-runtime/readers/mcp-generic.test.js +0 -76
  233. package/dist/core-runtime/readers/ontology-index.js +0 -148
  234. package/dist/core-runtime/readers/ontology-index.test.js +0 -245
  235. package/dist/core-runtime/readers/ontology-query.js +0 -168
  236. package/dist/core-runtime/readers/ontology-query.test.js +0 -311
  237. package/dist/core-runtime/readers/ontology-resolve.js +0 -48
  238. package/dist/core-runtime/readers/ontology-resolve.test.js +0 -48
  239. package/dist/core-runtime/readers/patterns/index.js +0 -7
  240. package/dist/core-runtime/readers/review-log.js +0 -213
  241. package/dist/core-runtime/readers/review-log.test.js +0 -313
  242. package/dist/core-runtime/readers/scan-local.js +0 -102
  243. package/dist/core-runtime/readers/scan-local.test.js +0 -102
  244. package/dist/core-runtime/readers/scan-tarball.js +0 -121
  245. package/dist/core-runtime/readers/scan-tarball.test.js +0 -283
  246. package/dist/core-runtime/readers/scan-vault.js +0 -34
  247. package/dist/core-runtime/readers/scan-vault.test.js +0 -81
  248. package/dist/core-runtime/readers/types.js +0 -42
  249. package/dist/core-runtime/readers/types.test.js +0 -94
  250. package/dist/core-runtime/readers/viewpoint-collectors.js +0 -229
  251. package/dist/core-runtime/reconstruct/seed-candidate-validation.js +0 -385
  252. package/dist/core-runtime/review/citation-audit.test.js +0 -165
  253. package/dist/core-runtime/review/execution-plan-resolver.js +0 -247
  254. package/dist/core-runtime/review/execution-plan-resolver.test.js +0 -243
  255. package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +0 -246
  256. package/dist/core-runtime/review/execution-topology-resolver.js +0 -401
  257. package/dist/core-runtime/review/execution-topology-resolver.test.js +0 -315
  258. package/dist/core-runtime/review/inline-context-embedder.test.js +0 -154
  259. package/dist/core-runtime/review/legacy-mode-policy.js +0 -88
  260. package/dist/core-runtime/review/materializers-effort-persist.test.js +0 -79
  261. package/dist/core-runtime/review/ontology-path-classifier.js +0 -179
  262. package/dist/core-runtime/review/ontology-path-classifier.test.js +0 -216
  263. package/dist/core-runtime/review/packet-boundary-policy.test.js +0 -107
  264. package/dist/core-runtime/review/participating-lens-paths.test.js +0 -73
  265. package/dist/core-runtime/review/review-config-legacy-translate.js +0 -244
  266. package/dist/core-runtime/review/review-config-legacy-translate.test.js +0 -161
  267. package/dist/core-runtime/review/review-config-validator.js +0 -289
  268. package/dist/core-runtime/review/review-config-validator.test.js +0 -236
  269. package/dist/core-runtime/review/shape-pipeline-audit.test.js +0 -311
  270. package/dist/core-runtime/review/shape-to-topology-id.js +0 -117
  271. package/dist/core-runtime/review/shape-to-topology-id.test.js +0 -132
  272. package/dist/core-runtime/review/topology-shape-derivation.js +0 -155
  273. package/dist/core-runtime/review/topology-shape-derivation.test.js +0 -195
  274. package/dist/core-runtime/scope-runtime/constants.js +0 -12
  275. package/dist/core-runtime/scope-runtime/constraint-pool.js +0 -166
  276. package/dist/core-runtime/scope-runtime/constraint-pool.test.js +0 -674
  277. package/dist/core-runtime/scope-runtime/domain-validation-log.js +0 -135
  278. package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +0 -156
  279. package/dist/core-runtime/scope-runtime/eval-persistence.js +0 -65
  280. package/dist/core-runtime/scope-runtime/eval-persistence.test.js +0 -84
  281. package/dist/core-runtime/scope-runtime/event-pipeline.js +0 -64
  282. package/dist/core-runtime/scope-runtime/event-pipeline.test.js +0 -450
  283. package/dist/core-runtime/scope-runtime/event-store.js +0 -39
  284. package/dist/core-runtime/scope-runtime/event-store.test.js +0 -95
  285. package/dist/core-runtime/scope-runtime/gate-guard.js +0 -348
  286. package/dist/core-runtime/scope-runtime/gate-guard.test.js +0 -1047
  287. package/dist/core-runtime/scope-runtime/hash.js +0 -4
  288. package/dist/core-runtime/scope-runtime/hash.test.js +0 -33
  289. package/dist/core-runtime/scope-runtime/id.js +0 -4
  290. package/dist/core-runtime/scope-runtime/id.test.js +0 -17
  291. package/dist/core-runtime/scope-runtime/reducer.js +0 -297
  292. package/dist/core-runtime/scope-runtime/reducer.test.js +0 -759
  293. package/dist/core-runtime/scope-runtime/scope-manager.js +0 -161
  294. package/dist/core-runtime/scope-runtime/state-machine.js +0 -309
  295. package/dist/core-runtime/scope-runtime/state-machine.test.js +0 -704
  296. package/dist/core-runtime/scope-runtime/types.js +0 -116
  297. package/dist/core-runtime/scope-runtime/types.test.js +0 -69
  298. package/dist/core-runtime/translate/render-for-user.js +0 -169
  299. package/dist/core-runtime/translate/render-for-user.test.js +0 -122
  300. package/dist/providers/capability-contract.js +0 -1
@@ -1,432 +0,0 @@
1
- /**
2
- * Phase 3 Promote — Collector (Step 7).
3
- *
4
- * Design authority:
5
- * - learn-phase3-design-v9.md (delta + DD-23)
6
- * - learn-phase3-design-v6.md DD-18 §SST (candidate_items canonical definition)
7
- * - learn-phase3-design-v5.md §5.1 (collector.ts skeleton)
8
- * - learn-phase3-design-v5.md DD-10 (BaselineHash + freshness gate)
9
- * - .onto/processes/learn/promote.md Step 1~2
10
- * - learning-rules.md (file format)
11
- *
12
- * Responsibility:
13
- * - Discover learning files (project + global) per CollectorMode.
14
- * - Parse §1.3 lines into ParsedLearningItem (Phase 3 shape from promote/types.ts).
15
- * - Capture BaselineHash (DD-10) for freshness re-check at Phase B.
16
- * - Build candidate_items per DD-18 §SST table (mode-dispatched filter).
17
- * - Return CollectionResult with project_items / global_items / candidate_items
18
- * as separate canonical seats. Consumers MUST read candidate_items rather
19
- * than re-deriving from project_items/global_items.
20
- *
21
- * Layering:
22
- * - Phase A only (strict source-read-only). No mutation, no LLM calls.
23
- * - Reuses TAG_PATTERN/SOURCE_PATTERN/CONTENT_CAPTURE from shared/patterns.ts.
24
- * - File path resolution mirrors shared/paths.ts: bare-id .md files under
25
- * `<root>/.onto/learnings/`. Phase 0 dual-read tolerates `onto_` legacy
26
- * filenames during the migration window.
27
- *
28
- * Failure model:
29
- * - Per-line parse failures append to parse_errors and the line is skipped.
30
- * Collection itself does not throw; the caller decides whether parse_errors
31
- * gates Phase A. v5 §5.1 explicitly returns parse failures rather than
32
- * aborting the whole collection.
33
- */
34
- import fs from "node:fs";
35
- import path from "node:path";
36
- import os from "node:os";
37
- import crypto from "node:crypto";
38
- import { ITEM_LINE_RE, SOURCE_PATTERN, } from "../shared/patterns.js";
39
- // ---------------------------------------------------------------------------
40
- // Path discovery
41
- // ---------------------------------------------------------------------------
42
- const LEARNINGS_SUBDIR = path.join(".onto", "learnings");
43
- function getProjectLearningsDir(projectRoot) {
44
- return path.join(projectRoot, LEARNINGS_SUBDIR);
45
- }
46
- function getGlobalLearningsDir() {
47
- return path.join(os.homedir(), LEARNINGS_SUBDIR);
48
- }
49
- /**
50
- * agent_id is the file basename without `.md`. Phase 0 dual-read accepts the
51
- * legacy `onto_` prefix; canonical agent_id strips it so promote outputs join
52
- * cleanly with the rest of the runtime.
53
- */
54
- function deriveAgentId(filename) {
55
- const base = filename.endsWith(".md") ? filename.slice(0, -3) : filename;
56
- return base.startsWith("onto_") ? base.slice(5) : base;
57
- }
58
- function listLearningFiles(dir, scope) {
59
- if (!fs.existsSync(dir))
60
- return [];
61
- const entries = fs.readdirSync(dir, { withFileTypes: true });
62
- const files = [];
63
- for (const entry of entries) {
64
- if (!entry.isFile())
65
- continue;
66
- if (!entry.name.endsWith(".md"))
67
- continue;
68
- files.push({
69
- absolute_path: path.join(dir, entry.name),
70
- agent_id: deriveAgentId(entry.name),
71
- scope,
72
- });
73
- }
74
- // Sort for deterministic baseline hash ordering.
75
- files.sort((a, b) => a.absolute_path.localeCompare(b.absolute_path));
76
- return files;
77
- }
78
- // ---------------------------------------------------------------------------
79
- // Line parsing
80
- // ---------------------------------------------------------------------------
81
- const LEARNING_ID_COMMENT_RE = /<!--\s*learning_id:\s*(\w+)(?:\s+taxonomy_version:\s*[\w.-]+)?\s*-->/;
82
- const EVENT_MARKER_COMMENT_RE = /<!--\s*(applied-then-found-invalid|observed-obsolete):\s*([^>]*?)\s*-->/g;
83
- const RETENTION_CONFIRMED_RE = /<!--\s*retention-confirmed:\s*(\d{4}-\d{2}-\d{2})\s*-->/;
84
- /**
85
- * Extract applicability tags and role from the bracket-tag prefix of a line.
86
- *
87
- * §1.3 grammar:
88
- * - [type] [methodology|domain/X]+ [role]? content (source: ...) [impact:...]
89
- *
90
- * The role bracket is optional. When [insight] appears it is preserved as-is
91
- * because Phase 3 reclassify-insights (DD-9) needs to find it; Phase 1 loader's
92
- * "insight → null" rewrite is intentionally NOT applied here.
93
- */
94
- function extractApplicabilityAndRole(line) {
95
- const applicability_tags = [];
96
- let role = null;
97
- const bracketRe = /\[([^\]]+)\]/g;
98
- let match;
99
- // Skip the first bracket which is the [type] discriminator.
100
- let firstSeen = false;
101
- while ((match = bracketRe.exec(line)) !== null) {
102
- const value = match[1];
103
- if (!firstSeen) {
104
- firstSeen = true;
105
- continue; // [fact] | [judgment]
106
- }
107
- if (value === "methodology" || value.startsWith("domain/")) {
108
- applicability_tags.push(value);
109
- continue;
110
- }
111
- if (value === "guardrail" ||
112
- value === "foundation" ||
113
- value === "convention" ||
114
- value === "insight") {
115
- role = value;
116
- continue;
117
- }
118
- if (value.startsWith("impact:")) {
119
- // impact handled by IMPACT_RE; bracket scan ignores it.
120
- break;
121
- }
122
- }
123
- return { applicability_tags, role };
124
- }
125
- /**
126
- * Lenient §1.3 line parser.
127
- *
128
- * Phase 3 collector intentionally accepts BOTH strict Phase 2 output and
129
- * pre-Phase 2 legacy lines: the whole point of promote is to review legacy
130
- * items and elevate or retire them. Strict TAG_PATTERN would drop too much.
131
- *
132
- * Required: line begins with `- [fact]` / `- [judgment]` and at least one
133
- * applicability tag.
134
- *
135
- * Best-effort: source metadata may be missing or use the pre-Phase 2 2-field
136
- * shape `(source: <description>, <date>)`. Impact defaults to "normal" when
137
- * absent. Trailing annotations (e.g., `(-> promoted to global, ...)`) are
138
- * tolerated.
139
- *
140
- * parse_errors only fires when the line truly cannot be classified — i.e.,
141
- * the type discriminator is missing or there is no usable applicability tag.
142
- */
143
- function parseLearningLine(rawLine, agentId, scope, sourcePath, lineNumber) {
144
- const typeMatch = rawLine.match(ITEM_LINE_RE);
145
- if (!typeMatch) {
146
- return { error: "line does not start with [fact] or [judgment] marker" };
147
- }
148
- const type = typeMatch[1];
149
- const { applicability_tags, role } = extractApplicabilityAndRole(rawLine);
150
- if (applicability_tags.length === 0) {
151
- return { error: "no applicability tags ([methodology] or [domain/X])" };
152
- }
153
- const impactMatch = rawLine.match(/\[impact:(high|normal)\]/);
154
- const impact = (impactMatch?.[1] ?? "normal");
155
- // Source metadata: try strict 3-field shape first, fall back to 2-field
156
- // legacy shape, fall back to null when absent entirely.
157
- let source_project = null;
158
- let source_domain = null;
159
- let source_date = null;
160
- const source3 = rawLine.match(SOURCE_PATTERN);
161
- if (source3) {
162
- source_project = source3[1].trim();
163
- source_domain = source3[2].trim();
164
- source_date = source3[3].trim();
165
- }
166
- else {
167
- const source2 = rawLine.match(/\(source:\s*([^,]+),\s*(\d{4}-\d{2}-\d{2})\)/);
168
- if (source2) {
169
- source_project = source2[1].trim();
170
- source_date = source2[2].trim();
171
- }
172
- }
173
- // Content: strip the leading `- [type] [tags...] [role]?` prefix and the
174
- // trailing `(source: ...)` / `[impact:...]` / `(-> ...)` annotations. The
175
- // remainder is the human-readable body.
176
- const content = extractContentBody(rawLine);
177
- if (!content) {
178
- return { error: "empty content body" };
179
- }
180
- return {
181
- item: {
182
- agent_id: agentId,
183
- scope,
184
- source_path: sourcePath,
185
- raw_line: rawLine,
186
- line_number: lineNumber,
187
- type,
188
- applicability_tags,
189
- role,
190
- content,
191
- source_project,
192
- source_domain,
193
- source_date,
194
- impact,
195
- },
196
- };
197
- }
198
- /**
199
- * Strip the §1.3 wrapper and return just the content body.
200
- *
201
- * Strategy:
202
- * 1. Drop the leading `- [type] [tag] [role]?` bracket prefix.
203
- * 2. Drop everything from the first `(source: ...)` onward (which also
204
- * removes trailing `(-> ...)` and `[impact:...]` annotations attached
205
- * after the source clause).
206
- * 3. Trim whitespace.
207
- *
208
- * If no source clause exists, also strip a trailing `[impact:...]` and any
209
- * trailing `(-> ...)` notes so legacy lines without source still produce a
210
- * clean body.
211
- */
212
- function extractContentBody(rawLine) {
213
- // Remove leading list marker.
214
- let body = rawLine.replace(/^[-*+]\s+/, "");
215
- // Remove leading bracket prefix: walk through consecutive `[...]` blocks.
216
- while (true) {
217
- const m = body.match(/^\[[^\]]+\]\s*/);
218
- if (!m)
219
- break;
220
- body = body.slice(m[0].length);
221
- }
222
- // Cut at the first source clause if present.
223
- const sourceIdx = body.indexOf("(source:");
224
- if (sourceIdx >= 0) {
225
- body = body.slice(0, sourceIdx);
226
- }
227
- else {
228
- // No source clause: still strip trailing impact and `(-> ...)` notes.
229
- body = body.replace(/\s*\[impact:(high|normal)\]\s*$/, "");
230
- body = body.replace(/\s*\(->[^)]*\)\s*$/, "");
231
- }
232
- return body.trim();
233
- }
234
- function parseLearningFile(file) {
235
- const buffer = fs.readFileSync(file.absolute_path);
236
- const content = buffer.toString("utf8");
237
- const lines = content.split("\n");
238
- const items = [];
239
- const errors = [];
240
- for (let i = 0; i < lines.length; i++) {
241
- const raw = lines[i];
242
- const trimmed = raw.trim();
243
- if (!trimmed)
244
- continue;
245
- if (trimmed.startsWith("#"))
246
- continue; // markdown heading
247
- if (trimmed.startsWith("<!--"))
248
- continue; // top-of-file format marker
249
- if (!/^[-*+]\s+\[/.test(trimmed))
250
- continue;
251
- const parsed = parseLearningLine(trimmed, file.agent_id, file.scope, file.absolute_path, i + 1);
252
- if ("error" in parsed) {
253
- errors.push({
254
- source_path: file.absolute_path,
255
- line_number: i + 1,
256
- raw_line: trimmed,
257
- error: parsed.error,
258
- });
259
- continue;
260
- }
261
- // Look ahead for trailing comment annotations attached to this learning.
262
- let learning_id = null;
263
- let retention_confirmed_at = null;
264
- const event_markers = [];
265
- let lookahead = i + 1;
266
- while (lookahead < lines.length) {
267
- const nextRaw = lines[lookahead].trim();
268
- if (!nextRaw)
269
- break;
270
- if (!nextRaw.startsWith("<!--"))
271
- break;
272
- const idMatch = nextRaw.match(LEARNING_ID_COMMENT_RE);
273
- if (idMatch) {
274
- learning_id = idMatch[1];
275
- lookahead++;
276
- continue;
277
- }
278
- const retentionMatch = nextRaw.match(RETENTION_CONFIRMED_RE);
279
- if (retentionMatch) {
280
- retention_confirmed_at = retentionMatch[1];
281
- lookahead++;
282
- continue;
283
- }
284
- const markerRe = new RegExp(EVENT_MARKER_COMMENT_RE.source, "g");
285
- let mm;
286
- let isMarker = false;
287
- while ((mm = markerRe.exec(nextRaw)) !== null) {
288
- // Store the FULL marker comment text so retirement.ts can parse the
289
- // date for retention-confirmed cutoff handling (DD-6 + promote.md §4a).
290
- event_markers.push(mm[0]);
291
- isMarker = true;
292
- }
293
- if (isMarker) {
294
- lookahead++;
295
- continue;
296
- }
297
- // Unrecognized comment — stop scanning so we don't swallow neighbours.
298
- break;
299
- }
300
- items.push({
301
- ...parsed.item,
302
- learning_id,
303
- event_markers,
304
- retention_confirmed_at,
305
- });
306
- }
307
- const baseline = {
308
- path: file.absolute_path,
309
- scope: file.scope,
310
- agent_id: file.agent_id,
311
- size_bytes: buffer.byteLength,
312
- content_sha256: crypto.createHash("sha256").update(buffer).digest("hex"),
313
- line_count: lines.length,
314
- };
315
- return { items, errors, baseline };
316
- }
317
- // ---------------------------------------------------------------------------
318
- // DD-18 §SST candidate selection (canonical definition — single seat)
319
- // ---------------------------------------------------------------------------
320
- /**
321
- * DD-18 §SST canonical definition. This is the only place candidate_items is
322
- * computed; consumers must read CollectionResult.candidate_items rather than
323
- * recomputing it.
324
- *
325
- * | Mode | candidate_items |
326
- * |----------------------|-------------------------------------------------------|
327
- * | promote | project_items.filter(item => item.role !== "insight") |
328
- * | reclassify-insights | global_items.filter(item => item.role === "insight") |
329
- */
330
- function buildCandidateItems(mode, project_items, global_items) {
331
- switch (mode) {
332
- case "promote":
333
- return project_items.filter((item) => item.role !== "insight");
334
- case "reclassify-insights":
335
- return global_items.filter((item) => item.role === "insight");
336
- default: {
337
- const _exhaustive = mode;
338
- throw new Error(`Unknown CollectorMode: ${String(_exhaustive)}`);
339
- }
340
- }
341
- }
342
- export function collect(config) {
343
- const collected_at = new Date().toISOString();
344
- const projectFiles = listLearningFiles(getProjectLearningsDir(config.projectRoot), "project");
345
- const globalFiles = listLearningFiles(getGlobalLearningsDir(), "global");
346
- const project_items = [];
347
- const global_items = [];
348
- const parse_errors = [];
349
- const baseline_files = [];
350
- for (const file of projectFiles) {
351
- const result = parseLearningFile(file);
352
- project_items.push(...result.items);
353
- parse_errors.push(...result.errors);
354
- baseline_files.push(result.baseline);
355
- }
356
- for (const file of globalFiles) {
357
- const result = parseLearningFile(file);
358
- global_items.push(...result.items);
359
- parse_errors.push(...result.errors);
360
- baseline_files.push(result.baseline);
361
- }
362
- const candidate_items = buildCandidateItems(config.mode, project_items, global_items);
363
- const baseline_hash = {
364
- schema_version: "1",
365
- source_scope: config.mode,
366
- captured_at: collected_at,
367
- files: baseline_files,
368
- };
369
- return {
370
- schema_version: "1",
371
- mode: config.mode,
372
- collected_at,
373
- project_items,
374
- global_items,
375
- candidate_items,
376
- baseline_hash,
377
- parse_errors,
378
- };
379
- }
380
- /**
381
- * Re-hash the files captured in a BaselineHash and report any mismatches.
382
- *
383
- * Phase B calls this before mutation to confirm the source files have not
384
- * shifted between Phase A's collect() snapshot and the apply window.
385
- *
386
- * Returns an empty array when the baseline still holds. The caller decides
387
- * whether to halt (default) or proceed with --force-stale.
388
- */
389
- export function verifyBaselineHash(baseline) {
390
- const mismatches = [];
391
- for (const file of baseline.files) {
392
- if (!fs.existsSync(file.path)) {
393
- mismatches.push({
394
- path: file.path,
395
- reason: "file_missing",
396
- expected: file.content_sha256,
397
- actual: "<missing>",
398
- });
399
- continue;
400
- }
401
- const buffer = fs.readFileSync(file.path);
402
- if (buffer.byteLength !== file.size_bytes) {
403
- mismatches.push({
404
- path: file.path,
405
- reason: "size_changed",
406
- expected: String(file.size_bytes),
407
- actual: String(buffer.byteLength),
408
- });
409
- continue;
410
- }
411
- const sha = crypto.createHash("sha256").update(buffer).digest("hex");
412
- if (sha !== file.content_sha256) {
413
- mismatches.push({
414
- path: file.path,
415
- reason: "content_sha256_changed",
416
- expected: file.content_sha256,
417
- actual: sha,
418
- });
419
- continue;
420
- }
421
- const lineCount = buffer.toString("utf8").split("\n").length;
422
- if (lineCount !== file.line_count) {
423
- mismatches.push({
424
- path: file.path,
425
- reason: "line_count_changed",
426
- expected: String(file.line_count),
427
- actual: String(lineCount),
428
- });
429
- }
430
- }
431
- return mismatches;
432
- }
@@ -1,125 +0,0 @@
1
- /**
2
- * Phase 3 Promote — Degraded state aggregator (Step 9b).
3
- *
4
- * Design authority:
5
- * - learn-phase3-design-v4.md DD-11 (degraded state taxonomy)
6
- * - learn-phase3-design-v4.md DD-12 (panel_minimum_unmet hard gate)
7
- *
8
- * Responsibility:
9
- * - Aggregate DegradedStateEntry records emitted by panel-reviewer,
10
- * judgment-auditor, and the orchestrator into operator-friendly views.
11
- * - Map DegradedStateKind → severity tier so the report can highlight
12
- * hard-gate items (panel_minimum_unmet) above informational ones
13
- * (criterion_6_waived).
14
- * - Determine which candidates are blocked from the ordinary apply path —
15
- * these surface in the user-approval section as "needs explicit decision".
16
- *
17
- * Scope:
18
- * - This module owns no I/O and emits no degraded states itself. The
19
- * types stay in promote/types.ts so emitter modules can construct entries
20
- * without depending on this aggregator. Aggregation is a one-way
21
- * downstream operation from emitters into PromoteReport assembly.
22
- *
23
- * Severity tiers (axis = "what does the operator do?"):
24
- * - blocking: candidate cannot follow the ordinary apply path; explicit
25
- * review or waiver is required.
26
- * - degraded: review still possible but with reduced confidence; the
27
- * report should annotate the affected candidates but not block them.
28
- * - informational: surfaced for transparency; no action required.
29
- */
30
- const SEVERITY_BY_KIND = {
31
- panel_minimum_unmet: "blocking",
32
- panel_contract_invalid: "degraded",
33
- member_unreachable: "degraded",
34
- criterion_6_blocked: "degraded",
35
- criterion_6_waived: "informational",
36
- stale_baseline: "blocking",
37
- };
38
- export function severityOf(kind) {
39
- return SEVERITY_BY_KIND[kind];
40
- }
41
- /**
42
- * Group entries by kind, preserving insertion order within each group so the
43
- * timeline of when each degraded state surfaced is recoverable.
44
- */
45
- export function groupByKind(entries) {
46
- const buckets = new Map();
47
- for (const e of entries) {
48
- const arr = buckets.get(e.kind) ?? [];
49
- arr.push(e);
50
- buckets.set(e.kind, arr);
51
- }
52
- return Array.from(buckets.entries()).map(([kind, list]) => ({
53
- kind,
54
- severity: severityOf(kind),
55
- count: list.length,
56
- entries: list,
57
- }));
58
- }
59
- /**
60
- * Collect candidate ids that are blocked from the ordinary apply path.
61
- *
62
- * DD-12 hard gate: any candidate touched by a `panel_minimum_unmet` entry is
63
- * blocked. `stale_baseline` is also blocking but is session-wide rather than
64
- * per-candidate, so it does not contribute candidate ids here — the
65
- * orchestrator surfaces it as a top-level abort.
66
- */
67
- export function collectBlockedCandidates(entries) {
68
- const blocked = new Set();
69
- for (const e of entries) {
70
- if (e.kind !== "panel_minimum_unmet")
71
- continue;
72
- for (const id of e.affected_candidates ?? []) {
73
- blocked.add(id);
74
- }
75
- }
76
- return [...blocked].sort();
77
- }
78
- /**
79
- * Roll up the full degraded-state picture into a summary block ready for
80
- * inclusion in PromoteReport assembly.
81
- */
82
- export function summarizeDegradedStates(entries) {
83
- const by_kind = groupByKind(entries);
84
- let blocking_count = 0;
85
- let degraded_count = 0;
86
- let informational_count = 0;
87
- for (const g of by_kind) {
88
- if (g.severity === "blocking")
89
- blocking_count += g.count;
90
- else if (g.severity === "degraded")
91
- degraded_count += g.count;
92
- else
93
- informational_count += g.count;
94
- }
95
- return {
96
- total: entries.length,
97
- blocking_count,
98
- degraded_count,
99
- informational_count,
100
- by_kind,
101
- blocked_candidate_ids: collectBlockedCandidates(entries),
102
- };
103
- }
104
- // ---------------------------------------------------------------------------
105
- // Stable-baseline helper (called by promoter / promote-executor)
106
- // ---------------------------------------------------------------------------
107
- /**
108
- * Construct a `stale_baseline` entry from verifyBaselineHash() mismatches.
109
- *
110
- * The orchestrator calls verifyBaselineHash() on Phase B entry and converts
111
- * any mismatches into a single degraded state entry — the entry is itself a
112
- * blocking gate that aborts the apply path unless --force-stale is set.
113
- */
114
- export function buildStaleBaselineEntry(mismatches) {
115
- const detail = mismatches.length === 0
116
- ? "no mismatches (defensive entry)"
117
- : mismatches
118
- .map((m) => `${m.path}: ${m.reason}`)
119
- .join("; ");
120
- return {
121
- kind: "stale_baseline",
122
- detail,
123
- occurred_at: new Date().toISOString(),
124
- };
125
- }