mirai-graph 1.3.0 → 2.1.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 (555) hide show
  1. package/cli.js +6 -0
  2. package/index.js +1 -0
  3. package/package.json +9 -121
  4. package/.github/workflows/ci.yml +0 -48
  5. package/.github/workflows/mirai-graph-validate.yml +0 -30
  6. package/CHANGELOG.md +0 -702
  7. package/CITATION.cff +0 -21
  8. package/LICENSE +0 -21
  9. package/LICENSE-DOCS +0 -26
  10. package/README.md +0 -351
  11. package/ROADMAP.md +0 -241
  12. package/benchmarks/protocols/measure-convert-optimize.md +0 -131
  13. package/benchmarks/synthetic-context-reduction-v0/README.md +0 -70
  14. package/benchmarks/synthetic-context-reduction-v0/RESULT.md +0 -52
  15. package/benchmarks/synthetic-context-reduction-v0/expected/context-pack-compact.md +0 -31
  16. package/benchmarks/synthetic-context-reduction-v0/gates/results.json +0 -12
  17. package/benchmarks/synthetic-context-reduction-v0/graph/objects.json +0 -114
  18. package/benchmarks/synthetic-context-reduction-v0/graph/relations.json +0 -74
  19. package/benchmarks/synthetic-context-reduction-v0/graph.json +0 -37
  20. package/benchmarks/synthetic-context-reduction-v0/metrics/example-metrics.json +0 -22
  21. package/benchmarks/synthetic-context-reduction-v0/results/baseline-comparison-result.json +0 -42
  22. package/benchmarks/synthetic-context-reduction-v0/results/context-pack.json +0 -181
  23. package/benchmarks/synthetic-context-reduction-v0/results/context-reduction-result.json +0 -8
  24. package/benchmarks/synthetic-context-reduction-v0/results/profile-conformance-result.json +0 -28
  25. package/benchmarks/synthetic-context-reduction-v0/results/readiness-score.json +0 -24
  26. package/benchmarks/synthetic-context-reduction-v0/reviews/semantic-completeness-review.json +0 -78
  27. package/benchmarks/synthetic-context-reduction-v0/scripts/calculate-context-reduction.js +0 -42
  28. package/benchmarks/synthetic-context-reduction-v0/source-corpus/audit-events.md +0 -8
  29. package/benchmarks/synthetic-context-reduction-v0/source-corpus/content-workflow.md +0 -8
  30. package/benchmarks/synthetic-context-reduction-v0/source-corpus/identity-access.md +0 -8
  31. package/benchmarks/synthetic-context-reduction-v0/source-corpus/notification-delivery.md +0 -8
  32. package/benchmarks/synthetic-context-reduction-v0/tasks/tasks.json +0 -31
  33. package/docs/README.md +0 -130
  34. package/docs/adoption/adopter-kit.md +0 -187
  35. package/docs/adoption/ai-employee-graph.md +0 -151
  36. package/docs/adoption/character-layer.md +0 -196
  37. package/docs/adoption/choose-profile.md +0 -106
  38. package/docs/adoption/cli.md +0 -134
  39. package/docs/adoption/connect-project-15-minutes.md +0 -122
  40. package/docs/adoption/developer-integration-guide.md +0 -122
  41. package/docs/adoption/end-to-end-control-loop.md +0 -168
  42. package/docs/adoption/for-developers.md +0 -210
  43. package/docs/adoption/getting-started.md +0 -192
  44. package/docs/adoption/mirai-graph-transition.md +0 -67
  45. package/docs/adoption/profile-conformance-fixtures.md +0 -112
  46. package/docs/adoption/seed-to-validated-package.md +0 -121
  47. package/docs/concept.md +0 -109
  48. package/docs/repository-purpose.md +0 -422
  49. package/docs/research/ai-work-field-instrumentation-bridge.md +0 -126
  50. package/docs/research/baseline-comparison-protocol.md +0 -79
  51. package/docs/research/evidence-package-v0.1.md +0 -99
  52. package/docs/research/evidence-package-v0.2.md +0 -150
  53. package/docs/research/evidence-package-v0.3.md +0 -256
  54. package/docs/research/independent-implementation-pilot-plan.md +0 -74
  55. package/docs/research/limitations-and-threats.md +0 -40
  56. package/docs/research/practice-science-program.md +0 -232
  57. package/docs/research/scientific-evidence-package.md +0 -188
  58. package/docs/research/semantic-completeness-review-protocol.md +0 -70
  59. package/docs/terminology.md +0 -119
  60. package/docs/transfer/ai-employee-profile-proposal.md +0 -119
  61. package/docs/transfer/federation-routing-control-loop-2026-05-31.md +0 -28
  62. package/docs/transfer/graph-capability-map-2026-05-29.md +0 -126
  63. package/docs/transfer/graph-skill-to-mirai-graph.md +0 -128
  64. package/docs/transfer/project-management-standard-harvest-2026-06-02.md +0 -322
  65. package/docs/transfer/skill-graph-standard-harvest-2026-05-31.md +0 -113
  66. package/docs/transfer/standard-gap-report-2026-05-28.md +0 -208
  67. package/examples/ai-employee-minimal/README.md +0 -53
  68. package/examples/ai-employee-minimal/gates/results.json +0 -35
  69. package/examples/ai-employee-minimal/graph/objects.json +0 -187
  70. package/examples/ai-employee-minimal/graph/relations.json +0 -167
  71. package/examples/ai-employee-minimal/graph.json +0 -37
  72. package/examples/ai-employee-minimal/results/profile-conformance-result.json +0 -28
  73. package/examples/character-layer-integration-minimal/README.md +0 -25
  74. package/examples/character-layer-integration-minimal/results/character-layer-integration.json +0 -53
  75. package/examples/character-layer-minimal/README.md +0 -29
  76. package/examples/character-layer-minimal/gates/results.json +0 -57
  77. package/examples/character-layer-minimal/graph/objects.json +0 -165
  78. package/examples/character-layer-minimal/graph/relations.json +0 -178
  79. package/examples/character-layer-minimal/graph.json +0 -37
  80. package/examples/character-layer-readiness-1-0/README.md +0 -27
  81. package/examples/character-layer-readiness-1-0/results/character-layer-readiness.json +0 -90
  82. package/examples/dynamic-episode-minimal/README.md +0 -34
  83. package/examples/dynamic-episode-minimal/gates/results.json +0 -12
  84. package/examples/dynamic-episode-minimal/graph/objects.json +0 -92
  85. package/examples/dynamic-episode-minimal/graph/relations.json +0 -29
  86. package/examples/dynamic-episode-minimal/graph.json +0 -47
  87. package/examples/dynamic-episode-minimal/invalid-canonical-write-allowed.json +0 -40
  88. package/examples/dynamic-episode-minimal/invalid-evidence-as-authorization.json +0 -46
  89. package/examples/dynamic-episode-minimal/invalid-missing-event.json +0 -35
  90. package/examples/dynamic-episode-minimal/invalid-missing-selected-path.json +0 -40
  91. package/examples/dynamic-episode-minimal/invalid-unclassified-finding.json +0 -50
  92. package/examples/dynamic-episode-minimal/results/dynamic-episode-trace.json +0 -149
  93. package/examples/federation-routing-smoke/README.md +0 -19
  94. package/examples/federation-routing-smoke/federation-health-dashboard.json +0 -42
  95. package/examples/federation-routing-smoke/route-explanation.json +0 -32
  96. package/examples/federation-routing-smoke/route-regression-result.json +0 -35
  97. package/examples/federation-routing-smoke/routes/production-deploy-execution-evidence.json +0 -17
  98. package/examples/federation-routing-smoke/routes/production-deploy-route-result.json +0 -12
  99. package/examples/federation-routing-smoke/routes/production-deploy-runtime-preflight.json +0 -8
  100. package/examples/federation-routing-smoke/routes/production-deploy-stderr.txt +0 -1
  101. package/examples/federation-routing-smoke/routes/production-deploy-stdout.txt +0 -1
  102. package/examples/federation-routing-smoke/routes/search-page-execution-evidence.json +0 -17
  103. package/examples/federation-routing-smoke/routes/search-page-route-result.json +0 -12
  104. package/examples/federation-routing-smoke/routes/search-page-stderr.txt +0 -1
  105. package/examples/federation-routing-smoke/routes/search-page-stdout.txt +0 -1
  106. package/examples/federation-routing-smoke/routing-fixture-run.json +0 -66
  107. package/examples/federation-routing-smoke/routing-fixtures.json +0 -44
  108. package/examples/goal-vector-quality-control-minimal/README.md +0 -22
  109. package/examples/goal-vector-quality-control-minimal/gates/results.json +0 -22
  110. package/examples/goal-vector-quality-control-minimal/graph/objects.json +0 -56
  111. package/examples/goal-vector-quality-control-minimal/graph/relations.json +0 -29
  112. package/examples/goal-vector-quality-control-minimal/graph.json +0 -41
  113. package/examples/goal-vector-quality-control-minimal/invalid-complete-without-evidence.json +0 -77
  114. package/examples/goal-vector-quality-control-minimal/invalid-correction-without-route.json +0 -86
  115. package/examples/goal-vector-quality-control-minimal/invalid-missing-reverse-audit.json +0 -77
  116. package/examples/goal-vector-quality-control-minimal/invalid-missing-vector-link.json +0 -62
  117. package/examples/goal-vector-quality-control-minimal/invalid-tests-as-acceptance.json +0 -72
  118. package/examples/goal-vector-quality-control-minimal/results/goal-vector-quality-control.json +0 -130
  119. package/examples/graph-dna-alignment-minimal/README.md +0 -16
  120. package/examples/graph-dna-alignment-minimal/graph/objects.json +0 -38
  121. package/examples/graph-dna-alignment-minimal/graph/relations.json +0 -20
  122. package/examples/graph-dna-alignment-minimal/graph.json +0 -37
  123. package/examples/graph-dna-alignment-minimal/results/graph-dna-alignment.json +0 -32
  124. package/examples/graph-seed-minimal/README.md +0 -9
  125. package/examples/graph-seed-minimal/graph-embryo.json +0 -63
  126. package/examples/graph-seed-minimal/graph-seed.json +0 -60
  127. package/examples/implementation-control-cycles/README.md +0 -47
  128. package/examples/implementation-control-cycles/gates/results.json +0 -22
  129. package/examples/implementation-control-cycles/graph/objects.json +0 -119
  130. package/examples/implementation-control-cycles/graph/relations.json +0 -200
  131. package/examples/implementation-control-cycles/graph.json +0 -37
  132. package/examples/implementation-control-cycles/results/implementation-control-cycles.json +0 -456
  133. package/examples/implementation-control-minimal/README.md +0 -39
  134. package/examples/implementation-control-minimal/gates/results.json +0 -42
  135. package/examples/implementation-control-minimal/graph/objects.json +0 -128
  136. package/examples/implementation-control-minimal/graph/relations.json +0 -128
  137. package/examples/implementation-control-minimal/graph.json +0 -37
  138. package/examples/implementation-control-minimal/results/implementation-control-loop.json +0 -21
  139. package/examples/instrumentation-layer-minimal/README.md +0 -32
  140. package/examples/instrumentation-layer-minimal/gates/results.json +0 -11
  141. package/examples/instrumentation-layer-minimal/graph/objects.json +0 -74
  142. package/examples/instrumentation-layer-minimal/graph/relations.json +0 -56
  143. package/examples/instrumentation-layer-minimal/graph.json +0 -37
  144. package/examples/instrumentation-layer-minimal/invalid-cockpit-missing-gates.json +0 -40
  145. package/examples/instrumentation-layer-minimal/invalid-feedback-accepted-with-blocking.json +0 -38
  146. package/examples/instrumentation-layer-minimal/invalid-feedback-process-improvement-without-kaizen.json +0 -38
  147. package/examples/instrumentation-layer-minimal/invalid-traceability-missing-evidence.json +0 -43
  148. package/examples/instrumentation-layer-minimal/results/development-cockpit.json +0 -68
  149. package/examples/instrumentation-layer-minimal/results/feature-implementation-traceability.json +0 -56
  150. package/examples/instrumentation-layer-minimal/results/multi-source-quality-feedback.json +0 -72
  151. package/examples/invalid-character-layer-context-authorization/graph/objects.json +0 -22
  152. package/examples/invalid-character-layer-context-authorization/graph/relations.json +0 -1
  153. package/examples/invalid-character-layer-context-authorization/graph.json +0 -35
  154. package/examples/invalid-character-layer-correction-loop-no-review/graph/objects.json +0 -22
  155. package/examples/invalid-character-layer-correction-loop-no-review/graph/relations.json +0 -1
  156. package/examples/invalid-character-layer-correction-loop-no-review/graph.json +0 -35
  157. package/examples/invalid-character-layer-feedback-auto-update/graph/objects.json +0 -22
  158. package/examples/invalid-character-layer-feedback-auto-update/graph/relations.json +0 -1
  159. package/examples/invalid-character-layer-feedback-auto-update/graph.json +0 -35
  160. package/examples/invalid-character-layer-object-kind/graph/objects.json +0 -22
  161. package/examples/invalid-character-layer-object-kind/graph/relations.json +0 -1
  162. package/examples/invalid-character-layer-object-kind/graph.json +0 -35
  163. package/examples/invalid-character-layer-relation-direction/graph/objects.json +0 -33
  164. package/examples/invalid-character-layer-relation-direction/graph/relations.json +0 -13
  165. package/examples/invalid-character-layer-relation-direction/graph.json +0 -35
  166. package/examples/invalid-character-layer-relation-type/graph/objects.json +0 -33
  167. package/examples/invalid-character-layer-relation-type/graph/relations.json +0 -13
  168. package/examples/invalid-character-layer-relation-type/graph.json +0 -35
  169. package/examples/invalid-character-layer-role-permission/graph/objects.json +0 -22
  170. package/examples/invalid-character-layer-role-permission/graph/relations.json +0 -1
  171. package/examples/invalid-character-layer-role-permission/graph.json +0 -35
  172. package/examples/invalid-context-pack-missing-explanation/context-pack.json +0 -25
  173. package/examples/invalid-missing-relation-target/graph/objects.json +0 -11
  174. package/examples/invalid-missing-relation-target/graph/relations.json +0 -11
  175. package/examples/invalid-missing-relation-target/graph.json +0 -32
  176. package/examples/invalid-profile-object-kind/graph/objects.json +0 -20
  177. package/examples/invalid-profile-object-kind/graph/relations.json +0 -1
  178. package/examples/invalid-profile-object-kind/graph.json +0 -32
  179. package/examples/invalid-profile-relation-type/graph/objects.json +0 -29
  180. package/examples/invalid-profile-relation-type/graph/relations.json +0 -11
  181. package/examples/invalid-profile-relation-type/graph.json +0 -32
  182. package/examples/invalid-relation-id-mismatch/graph/objects.json +0 -29
  183. package/examples/invalid-relation-id-mismatch/graph/relations.json +0 -11
  184. package/examples/invalid-relation-id-mismatch/graph.json +0 -32
  185. package/examples/invalid-seed-unsafe-write/graph-seed.json +0 -27
  186. package/examples/invalid-societal-governance-auto-learning-update/graph/objects.json +0 -29
  187. package/examples/invalid-societal-governance-auto-learning-update/graph/relations.json +0 -11
  188. package/examples/invalid-societal-governance-auto-learning-update/graph.json +0 -35
  189. package/examples/invalid-societal-governance-avatar-no-consent/graph/objects.json +0 -29
  190. package/examples/invalid-societal-governance-avatar-no-consent/graph/relations.json +0 -11
  191. package/examples/invalid-societal-governance-avatar-no-consent/graph.json +0 -35
  192. package/examples/invalid-societal-governance-generated-context-authorization/graph/objects.json +0 -38
  193. package/examples/invalid-societal-governance-generated-context-authorization/graph/relations.json +0 -20
  194. package/examples/invalid-societal-governance-generated-context-authorization/graph.json +0 -35
  195. package/examples/invalid-societal-governance-missing-appeal-path/graph/objects.json +0 -29
  196. package/examples/invalid-societal-governance-missing-appeal-path/graph/relations.json +0 -11
  197. package/examples/invalid-societal-governance-missing-appeal-path/graph.json +0 -35
  198. package/examples/invalid-societal-governance-private-trace-exposed/graph/objects.json +0 -29
  199. package/examples/invalid-societal-governance-private-trace-exposed/graph/relations.json +0 -11
  200. package/examples/invalid-societal-governance-private-trace-exposed/graph.json +0 -35
  201. package/examples/invalid-societal-governance-rights-overridden/graph/objects.json +0 -29
  202. package/examples/invalid-societal-governance-rights-overridden/graph/relations.json +0 -11
  203. package/examples/invalid-societal-governance-rights-overridden/graph.json +0 -35
  204. package/examples/launch-record-minimal/README.md +0 -29
  205. package/examples/launch-record-minimal/gates/results.json +0 -12
  206. package/examples/launch-record-minimal/graph/objects.json +0 -47
  207. package/examples/launch-record-minimal/graph/relations.json +0 -38
  208. package/examples/launch-record-minimal/graph.json +0 -34
  209. package/examples/launch-record-minimal/results/launch-record.json +0 -51
  210. package/examples/managed-project-control-loop/README.md +0 -43
  211. package/examples/managed-project-control-loop/gates/results.json +0 -22
  212. package/examples/managed-project-control-loop/graph/objects.json +0 -119
  213. package/examples/managed-project-control-loop/graph/relations.json +0 -110
  214. package/examples/managed-project-control-loop/graph.json +0 -37
  215. package/examples/managed-project-control-loop/results/managed-loop-result.json +0 -21
  216. package/examples/minimal-graph/README.md +0 -15
  217. package/examples/minimal-graph/gates/results.json +0 -12
  218. package/examples/minimal-graph/graph/objects.json +0 -24
  219. package/examples/minimal-graph/graph/relations.json +0 -11
  220. package/examples/minimal-graph/graph.json +0 -37
  221. package/examples/minimal-graph/results/profile-conformance-result.json +0 -26
  222. package/examples/model-portability-minimal/README.md +0 -15
  223. package/examples/model-portability-minimal/results/model-portability-evidence.json +0 -55
  224. package/examples/organization-governance-minimal/README.md +0 -29
  225. package/examples/organization-governance-minimal/gates/results.json +0 -21
  226. package/examples/organization-governance-minimal/graph/objects.json +0 -147
  227. package/examples/organization-governance-minimal/graph/relations.json +0 -147
  228. package/examples/organization-governance-minimal/graph.json +0 -37
  229. package/examples/organization-governance-minimal/results/profile-conformance-result.json +0 -31
  230. package/examples/process-control-contract-minimal/README.md +0 -19
  231. package/examples/process-control-contract-minimal/graph/objects.json +0 -38
  232. package/examples/process-control-contract-minimal/graph/relations.json +0 -29
  233. package/examples/process-control-contract-minimal/graph.json +0 -34
  234. package/examples/process-control-contract-minimal/results/process-control-contract.json +0 -58
  235. package/examples/process-transition-minimal/README.md +0 -25
  236. package/examples/process-transition-minimal/invalid-missing-launch-record.json +0 -14
  237. package/examples/process-transition-minimal/invalid-ready-to-written.json +0 -14
  238. package/examples/process-transition-minimal/invalid-release-missing-evidence.json +0 -14
  239. package/examples/process-transition-minimal/invalid-sync-to-update.json +0 -14
  240. package/examples/process-transition-minimal/invalid-terminal-missing-kaizen.json +0 -14
  241. package/examples/process-transition-minimal/invalid-tests-to-approved.json +0 -14
  242. package/examples/process-transition-minimal/results/transition-explanation-invalid-ready-to-written.json +0 -35
  243. package/examples/process-transition-minimal/results/transition-explanation-valid.json +0 -34
  244. package/examples/process-transition-minimal/state-machine.json +0 -79
  245. package/examples/process-transition-minimal/transition-request-skip-kaizen.json +0 -14
  246. package/examples/process-transition-minimal/transition-request.json +0 -14
  247. package/examples/project-technology-context-traversal/README.md +0 -17
  248. package/examples/project-technology-context-traversal/graph/objects.json +0 -78
  249. package/examples/project-technology-context-traversal/graph/relations.json +0 -47
  250. package/examples/project-technology-context-traversal/graph.json +0 -30
  251. package/examples/project-technology-context-traversal/selection.example.json +0 -29
  252. package/examples/project-technology-context-traversal/sources/announcement.md +0 -3
  253. package/examples/project-technology-context-traversal/sources/release-guide.md +0 -3
  254. package/examples/project-technology-context-traversal/sources/release-smoke.md +0 -3
  255. package/examples/project-technology-context-traversal/sources/rollback-policy.md +0 -3
  256. package/examples/risk-and-coordination-minimal/README.md +0 -16
  257. package/examples/risk-and-coordination-minimal/graph/objects.json +0 -47
  258. package/examples/risk-and-coordination-minimal/graph/relations.json +0 -29
  259. package/examples/risk-and-coordination-minimal/graph.json +0 -37
  260. package/examples/risk-and-coordination-minimal/results/multi-agent-coordination.json +0 -25
  261. package/examples/risk-and-coordination-minimal/results/risk-control-matrix.json +0 -34
  262. package/examples/self-service-onboarding/bootstrap-proposal/bootstrap-proposal.json +0 -20
  263. package/examples/self-service-onboarding/existing-graph/README.md +0 -4
  264. package/examples/self-service-onboarding/existing-graph/gates/results.json +0 -11
  265. package/examples/self-service-onboarding/existing-graph/graph/objects.json +0 -11
  266. package/examples/self-service-onboarding/existing-graph/graph/relations.json +0 -1
  267. package/examples/self-service-onboarding/existing-graph/graph.json +0 -36
  268. package/examples/self-service-onboarding/no-graph/README.md +0 -6
  269. package/examples/self-service-onboarding/no-graph/package.json +0 -6
  270. package/examples/self-service-onboarding/no-graph/src/index.js +0 -3
  271. package/examples/self-service-onboarding/stale-graph/README.md +0 -4
  272. package/examples/self-service-onboarding/stale-graph/graph.json +0 -36
  273. package/examples/semantic-intent-resolution-minimal/README.md +0 -13
  274. package/examples/semantic-intent-resolution-minimal/invalid-low-confidence-executes.json +0 -26
  275. package/examples/semantic-intent-resolution-minimal/invalid-proposal-canonical-update.json +0 -27
  276. package/examples/semantic-intent-resolution-minimal/results/semantic-intent-resolution.json +0 -45
  277. package/examples/skill-runtime-minimal/README.md +0 -29
  278. package/examples/skill-runtime-minimal/gates/results.json +0 -35
  279. package/examples/skill-runtime-minimal/graph/objects.json +0 -209
  280. package/examples/skill-runtime-minimal/graph/relations.json +0 -178
  281. package/examples/skill-runtime-minimal/graph.json +0 -37
  282. package/examples/skill-runtime-minimal/results/profile-conformance-result.json +0 -27
  283. package/examples/societal-governance-minimal/README.md +0 -37
  284. package/examples/societal-governance-minimal/graph/objects.json +0 -218
  285. package/examples/societal-governance-minimal/graph/relations.json +0 -209
  286. package/examples/societal-governance-minimal/graph.json +0 -37
  287. package/examples/source-boundary-minimal/README.md +0 -16
  288. package/examples/source-boundary-minimal/graph/objects.json +0 -38
  289. package/examples/source-boundary-minimal/graph/relations.json +0 -20
  290. package/examples/source-boundary-minimal/graph.json +0 -37
  291. package/examples/source-boundary-minimal/results/source-boundary-contract.json +0 -37
  292. package/examples/technology-quality-feedback-minimal/README.md +0 -33
  293. package/examples/technology-quality-feedback-minimal/graph/objects.json +0 -56
  294. package/examples/technology-quality-feedback-minimal/graph/relations.json +0 -47
  295. package/examples/technology-quality-feedback-minimal/graph.json +0 -34
  296. package/examples/technology-quality-feedback-minimal/invalid-accepted-with-blocking.json +0 -33
  297. package/examples/technology-quality-feedback-minimal/invalid-evidence-as-authorization.json +0 -22
  298. package/examples/technology-quality-feedback-minimal/invalid-missing-required-step.json +0 -22
  299. package/examples/technology-quality-feedback-minimal/invalid-process-improvement-without-kaizen.json +0 -33
  300. package/examples/technology-quality-feedback-minimal/invalid-spec-gap-without-route.json +0 -33
  301. package/examples/technology-quality-feedback-minimal/invalid-unclassified-finding.json +0 -33
  302. package/examples/technology-quality-feedback-minimal/results/technology-quality-feedback.json +0 -80
  303. package/examples/work-recovery-minimal/README.md +0 -15
  304. package/examples/work-recovery-minimal/graph/objects.json +0 -47
  305. package/examples/work-recovery-minimal/graph/relations.json +0 -20
  306. package/examples/work-recovery-minimal/graph.json +0 -37
  307. package/examples/work-recovery-minimal/results/recovery-resume-record.json +0 -17
  308. package/examples/work-recovery-minimal/results/work-state-machine.json +0 -21
  309. package/packages/cli/adopter-workflow.js +0 -228
  310. package/packages/cli/context-pack.js +0 -269
  311. package/packages/cli/graph-manifest.js +0 -367
  312. package/packages/cli/instrumentation-report.js +0 -97
  313. package/packages/cli/migrate-graph-manifest.js +0 -33
  314. package/packages/cli/mirai-graph.js +0 -154
  315. package/packages/cli/mirai_graph.js +0 -3
  316. package/packages/cli/playground-demo.js +0 -114
  317. package/packages/cli/project-technology.js +0 -129
  318. package/packages/cli/readiness-score.js +0 -164
  319. package/packages/cli/release-state.js +0 -329
  320. package/packages/cli/seed-preview.js +0 -78
  321. package/packages/cli/self-service-onboarding.js +0 -386
  322. package/packages/cli/validate-adopter-workflow.js +0 -63
  323. package/packages/cli/validate-artifact-releases.js +0 -282
  324. package/packages/cli/validate-baseline-comparison.js +0 -105
  325. package/packages/cli/validate-context-traversal.js +0 -292
  326. package/packages/cli/validate-graph-manifest-migration.js +0 -64
  327. package/packages/cli/validate-mirai-graph.js +0 -3245
  328. package/packages/cli/validate-process-transition-report.js +0 -105
  329. package/packages/cli/validate-profile-results.js +0 -64
  330. package/packages/cli/validate-project-continuity.js +0 -173
  331. package/packages/cli/validate-project-technology.js +0 -296
  332. package/packages/cli/validate-release-state.js +0 -100
  333. package/packages/cli/validate-routing-control-examples.js +0 -79
  334. package/packages/cli/validate-self-service-onboarding.js +0 -159
  335. package/packages/project-technology/artifact-release.js +0 -738
  336. package/packages/project-technology/context-traversal.js +0 -684
  337. package/packages/project-technology/continuity.js +0 -414
  338. package/packages/project-technology/index.js +0 -835
  339. package/pilots/independent-implementation-001-conference-planning/README.md +0 -40
  340. package/pilots/independent-implementation-001-conference-planning/gates/results.json +0 -12
  341. package/pilots/independent-implementation-001-conference-planning/graph/objects.json +0 -74
  342. package/pilots/independent-implementation-001-conference-planning/graph/relations.json +0 -56
  343. package/pilots/independent-implementation-001-conference-planning/graph-seed.json +0 -65
  344. package/pilots/independent-implementation-001-conference-planning/graph.json +0 -37
  345. package/pilots/independent-implementation-001-conference-planning/reports/pilot-report.md +0 -120
  346. package/pilots/independent-implementation-001-conference-planning/results/context-pack.json +0 -35
  347. package/pilots/independent-implementation-001-conference-planning/results/graph-embryo.json +0 -81
  348. package/pilots/independent-implementation-001-conference-planning/results/package-validation.json +0 -7
  349. package/pilots/independent-implementation-001-conference-planning/results/profile-conformance-result.json +0 -28
  350. package/pilots/independent-implementation-001-conference-planning/results/readiness-score.json +0 -26
  351. package/pilots/independent-implementation-001-conference-planning/results/seed-validation.json +0 -7
  352. package/pilots/independent-implementation-002-software-specification/README.md +0 -40
  353. package/pilots/independent-implementation-002-software-specification/gates/results.json +0 -22
  354. package/pilots/independent-implementation-002-software-specification/graph/objects.json +0 -101
  355. package/pilots/independent-implementation-002-software-specification/graph/relations.json +0 -92
  356. package/pilots/independent-implementation-002-software-specification/graph-seed.json +0 -72
  357. package/pilots/independent-implementation-002-software-specification/graph.json +0 -37
  358. package/pilots/independent-implementation-002-software-specification/reports/pilot-report.md +0 -142
  359. package/pilots/independent-implementation-002-software-specification/results/context-pack.json +0 -184
  360. package/pilots/independent-implementation-002-software-specification/results/graph-embryo.json +0 -90
  361. package/pilots/independent-implementation-002-software-specification/results/package-validation.json +0 -7
  362. package/pilots/independent-implementation-002-software-specification/results/profile-conformance-result.json +0 -28
  363. package/pilots/independent-implementation-002-software-specification/results/readiness-score.json +0 -26
  364. package/pilots/independent-implementation-002-software-specification/results/seed-validation.json +0 -7
  365. package/pilots/independent-implementation-002-software-specification/reviews/semantic-completeness-review.json +0 -81
  366. package/pilots/independent-implementation-003-ai-employee-workflow/README.md +0 -42
  367. package/pilots/independent-implementation-003-ai-employee-workflow/gates/results.json +0 -30
  368. package/pilots/independent-implementation-003-ai-employee-workflow/graph/objects.json +0 -156
  369. package/pilots/independent-implementation-003-ai-employee-workflow/graph/relations.json +0 -147
  370. package/pilots/independent-implementation-003-ai-employee-workflow/graph-seed.json +0 -90
  371. package/pilots/independent-implementation-003-ai-employee-workflow/graph.json +0 -37
  372. package/pilots/independent-implementation-003-ai-employee-workflow/reports/pilot-report.md +0 -49
  373. package/pilots/independent-implementation-003-ai-employee-workflow/results/profile-conformance-result.json +0 -30
  374. package/pilots/independent-implementation-004-research-program/README.md +0 -41
  375. package/pilots/independent-implementation-004-research-program/gates/results.json +0 -21
  376. package/pilots/independent-implementation-004-research-program/graph/objects.json +0 -102
  377. package/pilots/independent-implementation-004-research-program/graph/relations.json +0 -84
  378. package/pilots/independent-implementation-004-research-program/graph-seed.json +0 -76
  379. package/pilots/independent-implementation-004-research-program/graph.json +0 -37
  380. package/pilots/independent-implementation-004-research-program/reports/pilot-report.md +0 -50
  381. package/pilots/independent-implementation-004-research-program/results/profile-conformance-result.json +0 -30
  382. package/pilots/independent-implementation-005-organization-governance/README.md +0 -42
  383. package/pilots/independent-implementation-005-organization-governance/gates/results.json +0 -20
  384. package/pilots/independent-implementation-005-organization-governance/graph/objects.json +0 -137
  385. package/pilots/independent-implementation-005-organization-governance/graph/relations.json +0 -110
  386. package/pilots/independent-implementation-005-organization-governance/graph-seed.json +0 -97
  387. package/pilots/independent-implementation-005-organization-governance/graph.json +0 -37
  388. package/pilots/independent-implementation-005-organization-governance/reports/pilot-report.md +0 -47
  389. package/pilots/independent-implementation-005-organization-governance/results/profile-conformance-result.json +0 -29
  390. package/playground/README.md +0 -78
  391. package/playground/demo-report.md +0 -84
  392. package/profiles/README.md +0 -28
  393. package/profiles/ai-employee/README.md +0 -132
  394. package/profiles/ai-employee/profile.json +0 -58
  395. package/profiles/character-layer/README.md +0 -143
  396. package/profiles/character-layer/profile.json +0 -46
  397. package/profiles/implementation-control/README.md +0 -174
  398. package/profiles/implementation-control/profile.json +0 -108
  399. package/profiles/organization-governance/README.md +0 -60
  400. package/profiles/organization-governance/profile.json +0 -56
  401. package/profiles/project-management/README.md +0 -119
  402. package/profiles/project-management/profile.json +0 -38
  403. package/profiles/skill-runtime/README.md +0 -99
  404. package/profiles/skill-runtime/profile.json +0 -58
  405. package/profiles/societal-governance/README.md +0 -129
  406. package/profiles/societal-governance/profile.json +0 -121
  407. package/profiles/software-specification/README.md +0 -142
  408. package/profiles/software-specification/profile.json +0 -31
  409. package/publications/README.md +0 -39
  410. package/publications/observable-self-correcting-ai-workflows/README.md +0 -105
  411. package/publications/preprint-note.md +0 -11
  412. package/publications/preprint-outline.md +0 -45
  413. package/publications/semantic-intent-goal-vector-control/README.md +0 -99
  414. package/releases/0.1.0-alpha.0.md +0 -45
  415. package/releases/0.1.0-alpha.1.md +0 -63
  416. package/releases/0.1.0-alpha.10.md +0 -93
  417. package/releases/0.1.0-alpha.11.md +0 -114
  418. package/releases/0.1.0-alpha.2.md +0 -37
  419. package/releases/0.1.0-alpha.3.md +0 -61
  420. package/releases/0.1.0-alpha.4.md +0 -53
  421. package/releases/0.1.0-alpha.5.md +0 -48
  422. package/releases/0.1.0-alpha.6.md +0 -96
  423. package/releases/0.1.0-alpha.7.md +0 -114
  424. package/releases/0.1.0-alpha.8.md +0 -92
  425. package/releases/0.1.0-alpha.9.md +0 -80
  426. package/releases/1.0.0-rc.1.md +0 -121
  427. package/releases/1.0.0-rc.10.md +0 -14
  428. package/releases/1.0.0-rc.11.md +0 -14
  429. package/releases/1.0.0-rc.2.md +0 -79
  430. package/releases/1.0.0-rc.3.md +0 -51
  431. package/releases/1.0.0-rc.4.md +0 -70
  432. package/releases/1.0.0-rc.5.md +0 -88
  433. package/releases/1.0.0-rc.6.md +0 -76
  434. package/releases/1.0.0-rc.8.md +0 -17
  435. package/releases/1.0.0-rc.9.md +0 -14
  436. package/releases/1.0.0.md +0 -23
  437. package/releases/1.1.0.md +0 -36
  438. package/releases/1.1.1.md +0 -25
  439. package/releases/1.2.0.md +0 -19
  440. package/releases/1.3.0.md +0 -16
  441. package/releases/README.md +0 -135
  442. package/releases/societal-governance-profile-proposal.md +0 -45
  443. package/schemas/baseline-comparison-result.schema.json +0 -87
  444. package/schemas/character-layer-integration.schema.json +0 -112
  445. package/schemas/character-layer-readiness.schema.json +0 -73
  446. package/schemas/context-pack.schema.json +0 -190
  447. package/schemas/context-traversal-receipt.schema.json +0 -64
  448. package/schemas/development-cockpit.schema.json +0 -74
  449. package/schemas/dynamic-episode-trace.schema.json +0 -153
  450. package/schemas/feature-implementation-traceability.schema.json +0 -80
  451. package/schemas/federation-health-dashboard.schema.json +0 -47
  452. package/schemas/gate-result.schema.json +0 -44
  453. package/schemas/goal-vector-quality-control.schema.json +0 -131
  454. package/schemas/graph-dna-alignment.schema.json +0 -49
  455. package/schemas/graph-embryo.schema.json +0 -51
  456. package/schemas/graph-lock.schema.json +0 -28
  457. package/schemas/graph-manifest.schema.json +0 -154
  458. package/schemas/graph-seed.schema.json +0 -137
  459. package/schemas/implementation-control-cycle.schema.json +0 -265
  460. package/schemas/implementation-control-loop.schema.json +0 -84
  461. package/schemas/launch-record.schema.json +0 -78
  462. package/schemas/model-portability-evidence.schema.json +0 -93
  463. package/schemas/multi-agent-coordination.schema.json +0 -35
  464. package/schemas/multi-source-quality-feedback.schema.json +0 -54
  465. package/schemas/object.schema.json +0 -49
  466. package/schemas/package-manifest.schema.json +0 -53
  467. package/schemas/process-control-contract.schema.json +0 -100
  468. package/schemas/process-transition-request.schema.json +0 -41
  469. package/schemas/profile.schema.json +0 -56
  470. package/schemas/project-technology-extension.schema.json +0 -15
  471. package/schemas/project-technology-target-export.schema.json +0 -35
  472. package/schemas/readiness-score.schema.json +0 -43
  473. package/schemas/recovery-resume-record.schema.json +0 -25
  474. package/schemas/relation.schema.json +0 -43
  475. package/schemas/risk-control-matrix.schema.json +0 -36
  476. package/schemas/route-explanation.schema.json +0 -51
  477. package/schemas/route-regression-result.schema.json +0 -33
  478. package/schemas/routing-fixture-run.schema.json +0 -45
  479. package/schemas/routing-fixtures.schema.json +0 -59
  480. package/schemas/semantic-intent-resolution.schema.json +0 -151
  481. package/schemas/source-boundary-contract.schema.json +0 -31
  482. package/schemas/technology-quality-feedback.schema.json +0 -116
  483. package/schemas/work-state-machine.schema.json +0 -34
  484. package/standard/action-runtime-boundary.md +0 -99
  485. package/standard/adoption-levels.md +0 -69
  486. package/standard/conformance-levels.md +0 -133
  487. package/standard/context-pack-generation.md +0 -184
  488. package/standard/development-cockpit.md +0 -67
  489. package/standard/dynamic-episode-layer.md +0 -113
  490. package/standard/dynamic-layer-code-generation.md +0 -87
  491. package/standard/episode-trace.md +0 -97
  492. package/standard/evidence-provenance.md +0 -128
  493. package/standard/feature-implementation-traceability.md +0 -68
  494. package/standard/federation-health.md +0 -42
  495. package/standard/feedback-learning-gate.md +0 -101
  496. package/standard/goal-vector-quality-control.md +0 -128
  497. package/standard/governance.md +0 -137
  498. package/standard/graph-as-ai-brain.md +0 -81
  499. package/standard/graph-dna-alignment.md +0 -50
  500. package/standard/graph-dna.md +0 -70
  501. package/standard/graph-embryo.md +0 -69
  502. package/standard/graph-seed.md +0 -122
  503. package/standard/hybrid-source-of-truth.md +0 -91
  504. package/standard/implementation-control-cycles.md +0 -194
  505. package/standard/implementation-control.md +0 -102
  506. package/standard/launch-record.md +0 -53
  507. package/standard/lifecycle-readiness.md +0 -159
  508. package/standard/multi-agent-coordination.md +0 -50
  509. package/standard/multi-source-quality-feedback.md +0 -71
  510. package/standard/object-model.md +0 -167
  511. package/standard/organization-governance.md +0 -83
  512. package/standard/process-control-contract.md +0 -53
  513. package/standard/profile-boundaries.md +0 -225
  514. package/standard/profiles.md +0 -253
  515. package/standard/project-technology.md +0 -186
  516. package/standard/projection-views.md +0 -69
  517. package/standard/recovery-resume.md +0 -49
  518. package/standard/relation-model.md +0 -149
  519. package/standard/risk-control-matrix.md +0 -53
  520. package/standard/route-explanation.md +0 -35
  521. package/standard/route-regression.md +0 -33
  522. package/standard/routing-fixtures.md +0 -54
  523. package/standard/runtime-enablement.md +0 -85
  524. package/standard/semantic-intent-resolution.md +0 -91
  525. package/standard/source-boundary-contract.md +0 -49
  526. package/standard/standard-v0.1.md +0 -132
  527. package/standard/technology-quality-feedback.md +0 -97
  528. package/standard/test-suite.md +0 -159
  529. package/standard/work-state-machine.md +0 -62
  530. package/templates/README.md +0 -77
  531. package/templates/ai-employee-starter/README.md +0 -9
  532. package/templates/ai-employee-starter/gates/results.json +0 -12
  533. package/templates/ai-employee-starter/graph/objects.json +0 -90
  534. package/templates/ai-employee-starter/graph/relations.json +0 -47
  535. package/templates/ai-employee-starter/graph.json +0 -37
  536. package/templates/character-layer-starter/README.md +0 -39
  537. package/templates/character-layer-starter/gates/results.json +0 -20
  538. package/templates/character-layer-starter/graph/objects.json +0 -308
  539. package/templates/character-layer-starter/graph/relations.json +0 -344
  540. package/templates/character-layer-starter/graph.json +0 -37
  541. package/templates/organization-governance-starter/README.md +0 -9
  542. package/templates/organization-governance-starter/gates/results.json +0 -12
  543. package/templates/organization-governance-starter/graph/objects.json +0 -112
  544. package/templates/organization-governance-starter/graph/relations.json +0 -65
  545. package/templates/organization-governance-starter/graph.json +0 -37
  546. package/templates/research-program-starter/README.md +0 -9
  547. package/templates/research-program-starter/gates/results.json +0 -12
  548. package/templates/research-program-starter/graph/objects.json +0 -79
  549. package/templates/research-program-starter/graph/relations.json +0 -47
  550. package/templates/research-program-starter/graph.json +0 -37
  551. package/templates/software-project-starter/README.md +0 -9
  552. package/templates/software-project-starter/gates/results.json +0 -12
  553. package/templates/software-project-starter/graph/objects.json +0 -79
  554. package/templates/software-project-starter/graph/relations.json +0 -47
  555. package/templates/software-project-starter/graph.json +0 -37
@@ -1,3245 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
- const { SCHEMA_VERSION: MANIFEST_SCHEMA_VERSION, validateManifest } = require("./graph-manifest");
6
-
7
- const readinessValues = new Set([
8
- "draft",
9
- "review_ready",
10
- "accepted",
11
- "blocked",
12
- "deprecated"
13
- ]);
14
-
15
- const coreObjectKinds = new Set([
16
- "system",
17
- "goal",
18
- "requirement",
19
- "feature",
20
- "decision",
21
- "risk",
22
- "task",
23
- "component",
24
- "evidence",
25
- "context_pack",
26
- "governance_gate",
27
- "profile",
28
- "owner",
29
- "role",
30
- "capability",
31
- "process",
32
- "resource",
33
- "source",
34
- "check",
35
- "gate",
36
- "constraint",
37
- "access_requirement"
38
- ]);
39
-
40
- const coreRelationTypes = new Set([
41
- "depends_on",
42
- "supports",
43
- "blocks",
44
- "implements",
45
- "evidences",
46
- "contradicts",
47
- "governs",
48
- "requires_approval_from",
49
- "generates",
50
- "derived_from",
51
- "supersedes",
52
- "belongs_to",
53
- "related_to",
54
- "contains",
55
- "specializes",
56
- "requires",
57
- "governed_by",
58
- "validated_by",
59
- "documented_by",
60
- "implemented_by",
61
- "hands_off_to",
62
- "conflicts_with"
63
- ]);
64
-
65
- const conformanceLevels = new Set([
66
- "level_0",
67
- "level_1",
68
- "level_2",
69
- "level_3",
70
- "level_4"
71
- ]);
72
-
73
- const gateVerdicts = new Set([
74
- "pass",
75
- "pass_with_notes",
76
- "blocked",
77
- "rejected",
78
- "needs_more_evidence"
79
- ]);
80
-
81
- function usage() {
82
- console.error("Usage:");
83
- console.error(" node packages/cli/validate-mirai-graph.js <package-dir>");
84
- console.error(" node packages/cli/validate-mirai-graph.js seed <seed-file>");
85
- console.error(" node packages/cli/validate-mirai-graph.js profile <profile-file>");
86
- console.error(" node packages/cli/validate-mirai-graph.js context-pack <package-dir> <context-pack-file>");
87
- console.error(" node packages/cli/validate-mirai-graph.js implementation-control-cycle <cycle-result-file>");
88
- console.error(" node packages/cli/validate-mirai-graph.js launch-record <launch-record-file>");
89
- console.error(" node packages/cli/validate-mirai-graph.js process-transition <state-machine-file> <transition-request-file>");
90
- console.error(" node packages/cli/validate-mirai-graph.js process-control-contract <contract-file>");
91
- console.error(" node packages/cli/validate-mirai-graph.js technology-quality-feedback <feedback-file>");
92
- console.error(" node packages/cli/validate-mirai-graph.js character-layer-integration <integration-file>");
93
- console.error(" node packages/cli/validate-mirai-graph.js model-portability-evidence <evidence-file>");
94
- console.error(" node packages/cli/validate-mirai-graph.js character-layer-readiness <readiness-file>");
95
- console.error(" node packages/cli/validate-mirai-graph.js development-cockpit <cockpit-file>");
96
- console.error(" node packages/cli/validate-mirai-graph.js feature-implementation-traceability <traceability-file>");
97
- console.error(" node packages/cli/validate-mirai-graph.js multi-source-quality-feedback <feedback-file>");
98
- console.error(" node packages/cli/validate-mirai-graph.js dynamic-episode-trace <trace-file>");
99
- console.error(" node packages/cli/validate-mirai-graph.js graph-dna-alignment <result-file>");
100
- console.error(" node packages/cli/validate-mirai-graph.js work-state-machine <result-file>");
101
- console.error(" node packages/cli/validate-mirai-graph.js recovery-resume-record <result-file>");
102
- console.error(" node packages/cli/validate-mirai-graph.js risk-control-matrix <result-file>");
103
- console.error(" node packages/cli/validate-mirai-graph.js multi-agent-coordination <result-file>");
104
- console.error(" node packages/cli/validate-mirai-graph.js source-boundary-contract <result-file>");
105
- console.error(" node packages/cli/validate-mirai-graph.js semantic-intent-resolution <result-file>");
106
- console.error(" node packages/cli/validate-mirai-graph.js goal-vector-quality-control <result-file>");
107
- console.error("");
108
- console.error("Output options:");
109
- console.error(" --json Print JSON output (default)");
110
- console.error(" --markdown Print a human-readable Markdown report");
111
- }
112
-
113
- function markdownList(items, emptyText) {
114
- if (!items || items.length === 0) {
115
- return `- ${emptyText}`;
116
- }
117
- return items.map((item) => `- ${item}`).join("\n");
118
- }
119
-
120
- function formatInstrumentationMarkdown(output) {
121
- const result = output.result || {};
122
-
123
- if (output.mode === "development_cockpit") {
124
- const instruments = Array.isArray(result.instruments)
125
- ? result.instruments.map((instrument) => `\`${instrument.id}\`: ${instrument.family}, score \`${instrument.score}\`, band \`${instrument.band}\`, status \`${instrument.status}\``)
126
- : [];
127
- const nextAction = result.next_best_action || {};
128
- return [
129
- "# Development Cockpit Report",
130
- "",
131
- `- Valid: \`${output.valid ? "true" : "false"}\``,
132
- `- Subject: \`${result.subject_ref || "unknown"}\``,
133
- `- Generated at: \`${result.generated_at || "unknown"}\``,
134
- `- Production readiness: \`${result.readiness ? result.readiness.production_readiness : "unknown"}\``,
135
- `- Next action: \`${nextAction.action || "unknown"}\``,
136
- `- Target cycle: \`${nextAction.target_cycle || "unknown"}\``,
137
- "",
138
- "## Instruments",
139
- "",
140
- markdownList(instruments, "No instruments declared."),
141
- "",
142
- "## Required Gates",
143
- "",
144
- markdownList(nextAction.required_gates || [], "No required gates declared."),
145
- "",
146
- "## Blocking Rules",
147
- "",
148
- markdownList(result.blocking_rules || [], "No blocking rules declared."),
149
- "",
150
- "## Errors",
151
- "",
152
- markdownList(output.errors, "No errors."),
153
- "",
154
- "## Warnings",
155
- "",
156
- markdownList(output.warnings, "No warnings."),
157
- "",
158
- "## Boundary",
159
- "",
160
- "- Cockpit metrics support steering, not acceptance or release.",
161
- "- Evidence and proposals do not authorize canonical updates."
162
- ].join("\n");
163
- }
164
-
165
- if (output.mode === "feature_implementation_traceability") {
166
- const mappings = Array.isArray(result.implementation_mappings)
167
- ? result.implementation_mappings.map((mapping) => `\`${mapping.feature_ref}\`: status \`${mapping.status}\`, confidence \`${mapping.confidence}\`, implementation refs \`${(mapping.implementation_refs || []).length}\`, evidence refs \`${(mapping.evidence_refs || []).length}\``)
168
- : [];
169
- const summary = result.coverage_summary || {};
170
- return [
171
- "# Feature Implementation Traceability Report",
172
- "",
173
- `- Valid: \`${output.valid ? "true" : "false"}\``,
174
- `- Subject: \`${result.subject_ref || "unknown"}\``,
175
- `- Features: \`${summary.feature_count !== undefined ? summary.feature_count : "unknown"}\``,
176
- `- Mapped features: \`${summary.mapped_feature_count !== undefined ? summary.mapped_feature_count : "unknown"}\``,
177
- `- Evidence-backed mappings: \`${summary.evidence_backed_mapping_count !== undefined ? summary.evidence_backed_mapping_count : "unknown"}\``,
178
- `- Accepted features: \`${summary.accepted_feature_count !== undefined ? summary.accepted_feature_count : "unknown"}\``,
179
- "",
180
- "## Implementation Mappings",
181
- "",
182
- markdownList(mappings, "No implementation mappings declared."),
183
- "",
184
- "## Errors",
185
- "",
186
- markdownList(output.errors, "No errors."),
187
- "",
188
- "## Warnings",
189
- "",
190
- markdownList(output.warnings, "No warnings."),
191
- "",
192
- "## Boundary",
193
- "",
194
- "- Mapped intent is not implementation by itself.",
195
- "- Accepted or released status requires the relevant evidence and gates."
196
- ].join("\n");
197
- }
198
-
199
- if (output.mode === "multi_source_quality_feedback") {
200
- const sources = Array.isArray(result.sources)
201
- ? result.sources.map((source) => `\`${source.id}\`: ${source.kind}, verdict \`${source.verdict}\``)
202
- : [];
203
- const findings = Array.isArray(result.findings)
204
- ? result.findings.map((finding) => `\`${finding.id}\`: ${finding.classification}, severity \`${finding.severity}\`, blocking \`${finding.blocking ? "true" : "false"}\`, route \`${finding.next_route}\``)
205
- : [];
206
- return [
207
- "# Multi-Source Quality Feedback Report",
208
- "",
209
- `- Valid: \`${output.valid ? "true" : "false"}\``,
210
- `- Process: \`${result.process_id || "unknown"}\``,
211
- `- Verdict: \`${result.verdict || "unknown"}\``,
212
- `- Next transition: \`${result.next_transition || "unknown"}\``,
213
- `- Blocking findings: \`${Array.isArray(result.blocking_findings) ? result.blocking_findings.length : "unknown"}\``,
214
- "",
215
- "## Sources",
216
- "",
217
- markdownList(sources, "No sources declared."),
218
- "",
219
- "## Findings",
220
- "",
221
- markdownList(findings, "No findings declared."),
222
- "",
223
- "## Kaizen Refs",
224
- "",
225
- markdownList(result.kaizen_refs || [], "No Kaizen refs declared."),
226
- "",
227
- "## Errors",
228
- "",
229
- markdownList(output.errors, "No errors."),
230
- "",
231
- "## Warnings",
232
- "",
233
- markdownList(output.warnings, "No warnings."),
234
- "",
235
- "## Boundary",
236
- "",
237
- "- Multi-source feedback calibrates transitions; it is not approval by itself.",
238
- "- Blocking findings stop the transitions they block."
239
- ].join("\n");
240
- }
241
-
242
- if (output.mode === "dynamic_episode_trace") {
243
- const result = output.result || {};
244
- const activated = result.activated || {};
245
- const blockedPaths = Array.isArray(result.blocked_paths)
246
- ? result.blocked_paths.map((blockedPath) => `\`${blockedPath.id}\`: ${blockedPath.reason}, blocked by \`${blockedPath.blocked_by}\``)
247
- : [];
248
- const findings = Array.isArray(result.findings)
249
- ? result.findings.map((finding) => `\`${finding.id}\`: ${finding.classification}, severity \`${finding.severity}\`, route \`${finding.next_route}\`, blocking \`${finding.blocking ? "true" : "false"}\``)
250
- : [];
251
- return [
252
- "# Dynamic Episode Trace Report",
253
- "",
254
- `- Valid: \`${output.valid ? "true" : "false"}\``,
255
- `- Episode: \`${result.id || "unknown"}\``,
256
- `- Event: \`${result.event ? result.event.id : "unknown"}\``,
257
- `- Event type: \`${result.event ? result.event.type : "unknown"}\``,
258
- `- Canonical write allowed: \`${result.canonical_write_allowed === false ? "false" : "true"}\``,
259
- `- Activated objects: \`${Array.isArray(activated.objects) ? activated.objects.length : "unknown"}\``,
260
- `- Activated relations: \`${Array.isArray(activated.relations) ? activated.relations.length : "unknown"}\``,
261
- `- Selected path steps: \`${Array.isArray(result.selected_path) ? result.selected_path.length : "unknown"}\``,
262
- "",
263
- "## Blocked Paths",
264
- "",
265
- markdownList(blockedPaths, "No blocked paths declared."),
266
- "",
267
- "## Findings",
268
- "",
269
- markdownList(findings, "No findings declared."),
270
- "",
271
- "## Feedback Classification",
272
- "",
273
- markdownList(result.feedback_classification, "No feedback classifications declared."),
274
- "",
275
- "## Errors",
276
- "",
277
- markdownList(output.errors, "No errors."),
278
- "",
279
- "## Warnings",
280
- "",
281
- markdownList(output.warnings, "No warnings."),
282
- "",
283
- "## Boundary",
284
- "",
285
- "- Episode traces explain operational behavior; they do not expose hidden model reasoning.",
286
- "- Episode traces are evidence, not authorization.",
287
- "- Runtime traces do not update canonical graph state."
288
- ].join("\n");
289
- }
290
-
291
- return null;
292
- }
293
-
294
- function formatMarkdownReport(output) {
295
- const instrumentationReport = formatInstrumentationMarkdown(output);
296
- if (instrumentationReport) {
297
- return instrumentationReport;
298
- }
299
-
300
- if (output.mode === "process_transition" && output.explanation) {
301
- const explanation = output.explanation;
302
- const gate = explanation.kaizen_decision || {};
303
- return [
304
- "# Process Transition Decision Report",
305
- "",
306
- `- Valid: \`${output.valid ? "true" : "false"}\``,
307
- `- Process: \`${explanation.process_id || "unknown"}\``,
308
- `- Transition: \`${explanation.current_state || "unknown"} -> ${explanation.target_state || "unknown"}\``,
309
- `- Matched transition: \`${explanation.matched_transition ? "true" : "false"}\``,
310
- `- Requires launch record: \`${explanation.requires_launch_record ? "true" : "false"}\``,
311
- `- Launch record satisfied: \`${explanation.launch_record_satisfied ? "true" : "false"}\``,
312
- `- Terminal transition: \`${explanation.terminal_transition ? "true" : "false"}\``,
313
- `- Kaizen decision: \`${gate.status || "not_required"}\``,
314
- "",
315
- "## Required Evidence",
316
- "",
317
- markdownList(explanation.required_evidence, "No evidence required by matched transition."),
318
- "",
319
- "## Provided Evidence",
320
- "",
321
- markdownList(explanation.provided_evidence, "No evidence provided."),
322
- "",
323
- "## Missing Evidence",
324
- "",
325
- markdownList(explanation.missing_evidence, "No missing evidence."),
326
- "",
327
- "## False-Transition Guards",
328
- "",
329
- markdownList(explanation.false_transition_guard_summary, "No false-transition guards declared."),
330
- "",
331
- "## Errors",
332
- "",
333
- markdownList(output.errors, "No errors."),
334
- "",
335
- "## Warnings",
336
- "",
337
- markdownList(output.warnings, "No warnings."),
338
- "",
339
- "## Boundary",
340
- "",
341
- "- A passing transition report validates this requested transition only.",
342
- "- Readiness, evidence and proposals do not authorize canonical updates."
343
- ].join("\n");
344
- }
345
-
346
- const lines = [
347
- "# Mirai Graph Validation Report",
348
- "",
349
- `- Mode: \`${output.mode}\``,
350
- `- Valid: \`${output.valid ? "true" : "false"}\``,
351
- `- Target: \`${output.target}\``
352
- ];
353
-
354
- if (output.package) {
355
- lines.push(`- Package: \`${output.package}\``);
356
- }
357
- if (output.state_machine) {
358
- lines.push(`- State machine: \`${output.state_machine}\``);
359
- }
360
-
361
- lines.push(
362
- "",
363
- "## Errors",
364
- "",
365
- markdownList(output.errors, "No errors."),
366
- "",
367
- "## Warnings",
368
- "",
369
- markdownList(output.warnings, "No warnings."),
370
- "",
371
- "## Boundary",
372
- "",
373
- "- A passing validation report is evidence for this check only.",
374
- "- Generated context, evidence and proposals do not authorize canonical updates."
375
- );
376
-
377
- return lines.join("\n");
378
- }
379
-
380
- function readJson(filePath) {
381
- try {
382
- return JSON.parse(fs.readFileSync(filePath, "utf8"));
383
- } catch (error) {
384
- throw new Error(`Cannot read JSON ${filePath}: ${error.message}`);
385
- }
386
- }
387
-
388
- function findManifestPath(packageDir) {
389
- const rootManifest = path.join(packageDir, "graph.json");
390
- if (fs.existsSync(rootManifest)) {
391
- const payload = readJson(rootManifest);
392
- if (payload.format === "mirai-graph" && payload.schema_version === MANIFEST_SCHEMA_VERSION) return rootManifest;
393
- }
394
- return path.join(packageDir, "mirai-graph-package.json");
395
- }
396
-
397
- function readPackageManifest(filePath) {
398
- const manifest = readJson(filePath);
399
- if (manifest.format === "mirai-graph" && manifest.schema_version === MANIFEST_SCHEMA_VERSION) {
400
- const profiles = Array.isArray(manifest.profiles) ? manifest.profiles : [];
401
- return {
402
- ...manifest,
403
- _manifest_v2: true,
404
- name: manifest.title,
405
- profile: profiles[0],
406
- graph: manifest.graph ? {
407
- ...manifest.graph,
408
- objects: Array.isArray(manifest.graph.objects) ? manifest.graph.objects[0] : manifest.graph.objects,
409
- relations: Array.isArray(manifest.graph.relations) ? manifest.graph.relations[0] : manifest.graph.relations
410
- } : null
411
- };
412
- }
413
- return manifest;
414
- }
415
-
416
- function asArray(value, label, errors) {
417
- if (!Array.isArray(value)) {
418
- errors.push(`${label} must be an array`);
419
- return [];
420
- }
421
- return value;
422
- }
423
-
424
- function requireString(item, field, label, errors) {
425
- if (typeof item[field] !== "string" || item[field].trim() === "") {
426
- errors.push(`${label}.${field} must be a non-empty string`);
427
- }
428
- }
429
-
430
- function requireArray(item, field, label, errors) {
431
- if (!Array.isArray(item[field])) {
432
- errors.push(`${label}.${field} must be an array`);
433
- return;
434
- }
435
- const seen = new Set();
436
- for (const value of item[field]) {
437
- if (typeof value !== "string" || value.trim() === "") {
438
- errors.push(`${label}.${field} must contain only non-empty strings`);
439
- continue;
440
- }
441
- if (seen.has(value)) {
442
- errors.push(`${label}.${field} contains duplicate value ${value}`);
443
- }
444
- seen.add(value);
445
- }
446
- }
447
-
448
- function requireJsonArray(item, field, label, errors) {
449
- if (!Array.isArray(item[field])) {
450
- errors.push(`${label}.${field} must be an array`);
451
- }
452
- }
453
-
454
- function requireOptionalArray(item, field, label, errors) {
455
- if (item[field] === undefined) {
456
- return;
457
- }
458
- requireArray(item, field, label, errors);
459
- }
460
-
461
- function isValidDateTime(value) {
462
- return typeof value === "string" && value.trim() !== "" && !Number.isNaN(Date.parse(value));
463
- }
464
-
465
- function canonicalRelationId(relation) {
466
- if (
467
- typeof relation.source !== "string" ||
468
- typeof relation.type !== "string" ||
469
- typeof relation.target !== "string"
470
- ) {
471
- return null;
472
- }
473
- return `relation.${relation.source}.${relation.type}.${relation.target}`;
474
- }
475
-
476
- function profileSlug(profileName) {
477
- return profileName.replace(/_/g, "-");
478
- }
479
-
480
- function loadProfile(profileName) {
481
- if (profileName === "core") {
482
- return {
483
- allowed_object_kinds: Array.from(coreObjectKinds),
484
- allowed_relation_types: Array.from(coreRelationTypes)
485
- };
486
- }
487
-
488
- const profilePath = path.resolve(__dirname, "..", "..", "profiles", profileSlug(profileName), "profile.json");
489
- if (!fs.existsSync(profilePath)) {
490
- return null;
491
- }
492
-
493
- return readJson(profilePath);
494
- }
495
-
496
- function includesAnyLowercase(text, terms) {
497
- if (typeof text !== "string") {
498
- return null;
499
- }
500
- const lower = text.toLowerCase();
501
- return terms.find((term) => lower.includes(term));
502
- }
503
-
504
- function validateCharacterLayerSemantics(objects, relations, errors) {
505
- const objectById = new Map(objects.map((object) => [object.id, object]));
506
- const kindOf = (id) => objectById.get(id) && objectById.get(id).kind;
507
- const hasKind = (id, kinds) => kinds.includes(kindOf(id));
508
-
509
- const relationShapes = {
510
- defines_principle: {
511
- source: ["character_constitution"],
512
- target: ["character_principle"]
513
- },
514
- promotes_virtue: {
515
- source: ["character_constitution"],
516
- target: ["character_virtue"]
517
- },
518
- sets_character_boundary: {
519
- source: ["character_constitution"],
520
- target: ["character_boundary"]
521
- },
522
- specializes_character: {
523
- source: ["role_character_profile"],
524
- target: ["character_constitution"]
525
- },
526
- uses_reflection_protocol: {
527
- source: ["role_character_profile", "correction_loop"],
528
- target: ["reflection_protocol"]
529
- },
530
- tests_character: {
531
- source: ["character_fixture"],
532
- target: ["role_character_profile", "character_constitution"]
533
- },
534
- describes_violation_of: {
535
- source: ["violation_pattern"],
536
- target: ["character_principle", "character_boundary", "character_virtue", "character_decision_rule"]
537
- },
538
- corrects_violation: {
539
- source: ["correction_loop"],
540
- target: ["violation_pattern"]
541
- },
542
- updates_character: {
543
- source: ["correction_loop"],
544
- target: ["role_character_profile", "character_constitution", "character_principle", "character_boundary", "character_decision_rule", "reflection_protocol"]
545
- },
546
- evidences_character: {
547
- source: ["evidence"],
548
- target: ["character_constitution", "character_principle", "character_virtue", "character_boundary", "role_character_profile", "character_decision_rule", "reflection_protocol", "character_fixture", "violation_pattern", "correction_loop"]
549
- },
550
- requires_escalation_to: {
551
- source: ["character_boundary", "violation_pattern"],
552
- target: ["governance_gate"]
553
- },
554
- governs: {
555
- source: ["governance_gate"],
556
- target: ["role_character_profile", "character_constitution", "character_boundary", "correction_loop"]
557
- }
558
- };
559
-
560
- for (const [index, relation] of relations.entries()) {
561
- const label = `relation[${index}]`;
562
- const shape = relationShapes[relation.type];
563
- if (!shape || !objectById.has(relation.source) || !objectById.has(relation.target)) {
564
- continue;
565
- }
566
- if (!hasKind(relation.source, shape.source)) {
567
- errors.push(`${label}.source kind ${kindOf(relation.source)} is invalid for character_layer relation ${relation.type}; expected ${shape.source.join(" or ")}`);
568
- }
569
- if (!hasKind(relation.target, shape.target)) {
570
- errors.push(`${label}.target kind ${kindOf(relation.target)} is invalid for character_layer relation ${relation.type}; expected ${shape.target.join(" or ")}`);
571
- }
572
- }
573
-
574
- const forbiddenAuthorityTerms = [
575
- "generated context authorizes",
576
- "evidence authorizes",
577
- "proposal authorizes",
578
- "authorizes external action",
579
- "authorizes canonical update",
580
- "authorization is granted by evidence"
581
- ];
582
- const forbiddenAutomaticUpdateTerms = [
583
- "feedback automatically updates",
584
- "automatically updates canonical",
585
- "automatic canonical update",
586
- "auto canonical update",
587
- "canonical state changes automatically"
588
- ];
589
- const forbiddenRolePermissionTerms = [
590
- "grants tool permission",
591
- "grants runtime permission",
592
- "grants external action permission",
593
- "can execute tools without approval",
594
- "can bypass approval"
595
- ];
596
-
597
- for (const [index, object] of objects.entries()) {
598
- const label = `object[${index}]`;
599
- const haystack = `${object.title || ""}\n${object.summary || ""}`;
600
- const authorityTerm = includesAnyLowercase(haystack, forbiddenAuthorityTerms);
601
- if (authorityTerm) {
602
- errors.push(`${label} contains forbidden character_layer authorization semantics: ${authorityTerm}`);
603
- }
604
- const automaticUpdateTerm = includesAnyLowercase(haystack, forbiddenAutomaticUpdateTerms);
605
- if (automaticUpdateTerm) {
606
- errors.push(`${label} contains forbidden character_layer automatic-update semantics: ${automaticUpdateTerm}`);
607
- }
608
- if (object.kind === "role_character_profile") {
609
- const permissionTerm = includesAnyLowercase(haystack, forbiddenRolePermissionTerms);
610
- if (permissionTerm) {
611
- errors.push(`${label} contains forbidden role_character_profile runtime-permission semantics: ${permissionTerm}`);
612
- }
613
- }
614
- if (object.kind === "correction_loop") {
615
- const ownerReviewText = haystack.toLowerCase();
616
- if (!ownerReviewText.includes("owner review") && !ownerReviewText.includes("human review")) {
617
- errors.push(`${label} correction_loop must mention owner review or human review before canonical character updates`);
618
- }
619
- }
620
- }
621
- }
622
-
623
- function validateSocietalGovernanceSemantics(objects, relations, errors) {
624
- const objectById = new Map(objects.map((object) => [object.id, object]));
625
- const kindOf = (id) => objectById.get(id) && objectById.get(id).kind;
626
- const hasKind = (id, kinds) => kinds.includes(kindOf(id));
627
-
628
- const relationShapes = {
629
- represented_by_avatar: {
630
- source: ["participant"],
631
- target: ["ai_avatar"]
632
- },
633
- bound_by_contract: {
634
- source: ["ai_avatar"],
635
- target: ["avatar_contract"]
636
- },
637
- delegates_scope_to: {
638
- source: ["avatar_contract"],
639
- target: ["delegation_scope"]
640
- },
641
- has_consent_receipt: {
642
- source: ["delegation_scope"],
643
- target: ["consent_receipt"]
644
- },
645
- opens_initiative: {
646
- source: ["participant", "ai_avatar"],
647
- target: ["initiative"]
648
- },
649
- authorizes_decision: {
650
- source: ["legitimacy_gate", "rights_gate"],
651
- target: ["decision"]
652
- },
653
- has_appeal_path: {
654
- source: ["decision"],
655
- target: ["appeal"]
656
- },
657
- creates_learning_proposal: {
658
- source: ["outcome_evidence", "harm_report"],
659
- target: ["learning_proposal"]
660
- },
661
- approved_update_to: {
662
- source: ["learning_proposal", "amendment_proposal"],
663
- target: ["governance_dna"]
664
- }
665
- };
666
-
667
- for (const [index, relation] of relations.entries()) {
668
- const label = `relation[${index}]`;
669
- const shape = relationShapes[relation.type];
670
- if (shape && objectById.has(relation.source) && objectById.has(relation.target)) {
671
- if (!hasKind(relation.source, shape.source)) {
672
- errors.push(`${label}.source kind ${kindOf(relation.source)} is invalid for societal_governance relation ${relation.type}; expected ${shape.source.join(" or ")}`);
673
- }
674
- if (!hasKind(relation.target, shape.target)) {
675
- errors.push(`${label}.target kind ${kindOf(relation.target)} is invalid for societal_governance relation ${relation.type}; expected ${shape.target.join(" or ")}`);
676
- }
677
- }
678
-
679
- const sourceKind = kindOf(relation.source);
680
- if (relation.type === "authorizes_decision" && ["ai_avatar", "generated_context", "participation_signal", "outcome_evidence"].includes(sourceKind)) {
681
- errors.push(`${label} uses ${sourceKind} as decision authority; societal_governance requires human/governance gate authorization`);
682
- }
683
- if (relation.type === "opens_initiative" && sourceKind === "ai_avatar") {
684
- const avatarHasConsent = relations.some((candidate) => {
685
- if (candidate.type !== "bound_by_contract" || candidate.source !== relation.source) {
686
- return false;
687
- }
688
- const contractId = candidate.target;
689
- return relations.some((scopeRelation) => {
690
- if (scopeRelation.type !== "delegates_scope_to" || scopeRelation.source !== contractId) {
691
- return false;
692
- }
693
- const scopeId = scopeRelation.target;
694
- return relations.some((consentRelation) => consentRelation.type === "has_consent_receipt" && consentRelation.source === scopeId);
695
- });
696
- });
697
- if (!avatarHasConsent) {
698
- errors.push(`${label} lets ai_avatar open an initiative without contract scope and consent receipt`);
699
- }
700
- }
701
- if (relation.type === "exposes_private_trace") {
702
- errors.push(`${label} exposes private decision material; public traces may only summarize private proof`);
703
- }
704
- if (relation.type === "overrides_rights") {
705
- errors.push(`${label} lets weights override rights; societal_governance requires rights_before_optimization`);
706
- }
707
- if (relation.type === "auto_applies_learning") {
708
- errors.push(`${label} auto-applies learning; outcome evidence must create a learning proposal and approval-gated update`);
709
- }
710
- }
711
-
712
- const decisions = objects.filter((object) => object.kind === "decision");
713
- for (const decision of decisions) {
714
- const hasAppealPath = relations.some((relation) => relation.source === decision.id && relation.type === "has_appeal_path" && hasKind(relation.target, ["appeal"]));
715
- if (!hasAppealPath) {
716
- errors.push(`${decision.id} decision must have an appeal path before governed decision readiness`);
717
- }
718
- }
719
-
720
- const forbiddenTerms = [
721
- "generated context authorizes",
722
- "avatar authorizes",
723
- "ai avatar authorizes",
724
- "private journal is public",
725
- "private decision journal is public",
726
- "contribution weight overrides rights",
727
- "outcome evidence automatically updates",
728
- "learning automatically updates",
729
- "automatic governance update",
730
- "social score"
731
- ];
732
- for (const [index, object] of objects.entries()) {
733
- const haystack = `${object.title || ""}\n${object.summary || ""}`;
734
- const term = includesAnyLowercase(haystack, forbiddenTerms);
735
- if (term) {
736
- errors.push(`object[${index}] contains forbidden societal_governance semantics: ${term}`);
737
- }
738
- }
739
- }
740
-
741
- function validatePackage(packageDir) {
742
- const manifestLookup = findManifestPath(packageDir);
743
- const manifest = fs.existsSync(manifestLookup) ? readPackageManifest(manifestLookup) : null;
744
- const graphDir = path.join(packageDir, "graph");
745
- const objectsPath = manifest
746
- ? path.join(packageDir, manifest.graph && manifest.graph.objects ? manifest.graph.objects : "")
747
- : path.join(graphDir, "objects.json");
748
- const relationsPath = manifest
749
- ? path.join(packageDir, manifest.graph && manifest.graph.relations ? manifest.graph.relations : "")
750
- : path.join(graphDir, "relations.json");
751
- const gateResultsPath = path.join(packageDir, "gates", "results.json");
752
- const errors = [];
753
- const warnings = [];
754
-
755
- if (manifest) {
756
- requireString(manifest, "id", "manifest", errors);
757
- if (manifest._manifest_v2) {
758
- errors.push(...validateManifest(readJson(manifestLookup), packageDir).map((error) => `manifest.${error}`));
759
- } else {
760
- requireString(manifest, "name", "manifest", errors);
761
- requireString(manifest, "version", "manifest", errors);
762
- requireString(manifest, "profile", "manifest", errors);
763
- requireString(manifest, "conformance_level", "manifest", errors);
764
- }
765
-
766
- if (!manifest.graph || typeof manifest.graph !== "object") {
767
- errors.push("manifest.graph must be an object");
768
- } else {
769
- requireString(manifest.graph, "objects", "manifest.graph", errors);
770
- requireString(manifest.graph, "relations", "manifest.graph", errors);
771
- }
772
-
773
- if (
774
- typeof manifest.conformance_level === "string" &&
775
- !conformanceLevels.has(manifest.conformance_level)
776
- ) {
777
- errors.push(`manifest.conformance_level has unsupported value ${manifest.conformance_level}`);
778
- }
779
- } else {
780
- warnings.push("Missing graph.json or legacy mirai-graph-package.json manifest");
781
- }
782
-
783
- if (!fs.existsSync(objectsPath)) {
784
- errors.push(`Missing ${objectsPath}`);
785
- }
786
- if (!fs.existsSync(relationsPath)) {
787
- errors.push(`Missing ${relationsPath}`);
788
- }
789
- if (errors.length > 0) {
790
- return { errors, warnings };
791
- }
792
-
793
- const objects = asArray(readJson(objectsPath), "graph/objects.json", errors);
794
- const relations = asArray(readJson(relationsPath), "graph/relations.json", errors);
795
- const packageProfile = manifest && typeof manifest.profile === "string" ? loadProfile(manifest.profile) : null;
796
- const allowedObjectKinds = packageProfile ? new Set(packageProfile.allowed_object_kinds || []) : null;
797
- const allowedRelationTypes = packageProfile ? new Set(packageProfile.allowed_relation_types || []) : null;
798
-
799
- if (manifest && typeof manifest.profile === "string" && !packageProfile) {
800
- warnings.push(`No local profile definition found for manifest.profile ${manifest.profile}`);
801
- }
802
-
803
- const objectIds = new Set();
804
-
805
- for (const [index, object] of objects.entries()) {
806
- const label = `object[${index}]`;
807
- requireString(object, "id", label, errors);
808
- requireString(object, "kind", label, errors);
809
- requireString(object, "title", label, errors);
810
- requireString(object, "summary", label, errors);
811
- requireString(object, "readiness", label, errors);
812
- requireString(object, "profile", label, errors);
813
- requireArray(object, "evidence", label, errors);
814
-
815
- if (typeof object.id === "string") {
816
- if (objectIds.has(object.id)) {
817
- errors.push(`${label}.id duplicates ${object.id}`);
818
- }
819
- objectIds.add(object.id);
820
- }
821
-
822
- if (typeof object.readiness === "string" && !readinessValues.has(object.readiness)) {
823
- errors.push(`${label}.readiness has unsupported value ${object.readiness}`);
824
- }
825
-
826
- if (typeof object.kind === "string" && object.profile === "core" && !coreObjectKinds.has(object.kind)) {
827
- warnings.push(`${label}.kind ${object.kind} is not a core object kind`);
828
- }
829
-
830
- if (typeof object.kind === "string" && allowedObjectKinds && !allowedObjectKinds.has(object.kind)) {
831
- errors.push(`${label}.kind ${object.kind} is not allowed by manifest.profile ${manifest.profile}`);
832
- }
833
- }
834
-
835
- const evidenceIds = new Set(
836
- objects
837
- .filter((object) => object.kind === "evidence")
838
- .map((object) => object.id)
839
- );
840
- const relationIds = new Set();
841
-
842
- for (const [index, relation] of relations.entries()) {
843
- const label = `relation[${index}]`;
844
- requireString(relation, "id", label, errors);
845
- requireString(relation, "type", label, errors);
846
- requireString(relation, "source", label, errors);
847
- requireString(relation, "target", label, errors);
848
- requireString(relation, "readiness", label, errors);
849
- requireString(relation, "profile", label, errors);
850
- requireArray(relation, "evidence", label, errors);
851
-
852
- if (typeof relation.id === "string") {
853
- if (relationIds.has(relation.id)) {
854
- errors.push(`${label}.id duplicates ${relation.id}`);
855
- }
856
- relationIds.add(relation.id);
857
-
858
- const expectedRelationId = canonicalRelationId(relation);
859
- if (expectedRelationId && relation.id !== expectedRelationId) {
860
- errors.push(`${label}.id must be ${expectedRelationId} for its source/type/target`);
861
- }
862
- }
863
-
864
- if (typeof relation.source === "string" && !objectIds.has(relation.source)) {
865
- errors.push(`${label}.source references missing object ${relation.source}`);
866
- }
867
-
868
- if (typeof relation.target === "string" && !objectIds.has(relation.target)) {
869
- errors.push(`${label}.target references missing object ${relation.target}`);
870
- }
871
-
872
- if (typeof relation.readiness === "string" && !readinessValues.has(relation.readiness)) {
873
- errors.push(`${label}.readiness has unsupported value ${relation.readiness}`);
874
- }
875
-
876
- if (typeof relation.type === "string" && relation.profile === "core" && !coreRelationTypes.has(relation.type)) {
877
- warnings.push(`${label}.type ${relation.type} is not a core relation type`);
878
- }
879
-
880
- if (typeof relation.type === "string" && allowedRelationTypes && !allowedRelationTypes.has(relation.type)) {
881
- errors.push(`${label}.type ${relation.type} is not allowed by manifest.profile ${manifest.profile}`);
882
- }
883
-
884
- if (Array.isArray(relation.evidence)) {
885
- for (const evidenceRef of relation.evidence) {
886
- if (!evidenceIds.has(evidenceRef) && !objectIds.has(evidenceRef)) {
887
- warnings.push(`${label}.evidence references non-object evidence ${evidenceRef}`);
888
- }
889
- }
890
- }
891
- }
892
-
893
- if (manifest && manifest.profile === "character_layer") {
894
- validateCharacterLayerSemantics(objects, relations, errors);
895
- }
896
- if (manifest && manifest.profile === "societal_governance") {
897
- validateSocietalGovernanceSemantics(objects, relations, errors);
898
- }
899
-
900
- if (fs.existsSync(gateResultsPath)) {
901
- const gateResults = asArray(readJson(gateResultsPath), "gates/results.json", errors);
902
- const gateResultIds = new Set();
903
-
904
- for (const [index, gateResult] of gateResults.entries()) {
905
- const label = `gate_result[${index}]`;
906
- requireString(gateResult, "id", label, errors);
907
- requireString(gateResult, "gate_id", label, errors);
908
- requireString(gateResult, "target_id", label, errors);
909
- requireString(gateResult, "verdict", label, errors);
910
- requireString(gateResult, "summary", label, errors);
911
- requireString(gateResult, "reviewed_at", label, errors);
912
- requireArray(gateResult, "evidence", label, errors);
913
-
914
- if (typeof gateResult.id === "string") {
915
- if (gateResultIds.has(gateResult.id)) {
916
- errors.push(`${label}.id duplicates ${gateResult.id}`);
917
- }
918
- gateResultIds.add(gateResult.id);
919
- }
920
-
921
- if (typeof gateResult.verdict === "string" && !gateVerdicts.has(gateResult.verdict)) {
922
- errors.push(`${label}.verdict has unsupported value ${gateResult.verdict}`);
923
- }
924
-
925
- if (
926
- typeof gateResult.target_id === "string" &&
927
- manifest &&
928
- gateResult.target_id !== manifest.id &&
929
- !objectIds.has(gateResult.target_id) &&
930
- !relationIds.has(gateResult.target_id)
931
- ) {
932
- warnings.push(`${label}.target_id references non-graph target ${gateResult.target_id}`);
933
- }
934
- }
935
- }
936
-
937
- return { errors, warnings };
938
- }
939
-
940
- function requireObject(item, field, label, errors) {
941
- if (!item[field] || typeof item[field] !== "object" || Array.isArray(item[field])) {
942
- errors.push(`${label}.${field} must be an object`);
943
- }
944
- }
945
-
946
- function validateSeed(seedPath) {
947
- const errors = [];
948
- const warnings = [];
949
- const seed = readJson(seedPath);
950
- const label = "seed";
951
-
952
- requireString(seed, "schema_version", label, errors);
953
- requireString(seed, "seed_id", label, errors);
954
- requireString(seed, "target_graph_id", label, errors);
955
- requireString(seed, "purpose", label, errors);
956
- requireString(seed, "target_profile", label, errors);
957
- requireString(seed, "target_mode", label, errors);
958
- requireObject(seed, "graph_dna", label, errors);
959
- requireObject(seed, "source_boundaries", label, errors);
960
- requireObject(seed, "growth_rules", label, errors);
961
- requireArray(seed, "review_gates", label, errors);
962
- requireArray(seed, "generated_views", label, errors);
963
- requireArray(seed, "stop_conditions", label, errors);
964
-
965
- const targetModes = new Set([
966
- "discovery",
967
- "canonical",
968
- "pilot",
969
- "controlled_runtime",
970
- "production_runtime"
971
- ]);
972
-
973
- if (typeof seed.target_mode === "string" && !targetModes.has(seed.target_mode)) {
974
- errors.push(`${label}.target_mode has unsupported value ${seed.target_mode}`);
975
- }
976
-
977
- if (seed.graph_dna && typeof seed.graph_dna === "object") {
978
- requireString(seed.graph_dna, "purpose", "seed.graph_dna", errors);
979
- requireString(seed.graph_dna, "evolution_vector", "seed.graph_dna", errors);
980
- requireArray(seed.graph_dna, "non_negotiable_principles", "seed.graph_dna", errors);
981
- }
982
-
983
- if (seed.source_boundaries && typeof seed.source_boundaries === "object") {
984
- requireArray(seed.source_boundaries, "allowed_sources", "seed.source_boundaries", errors);
985
- requireArray(seed.source_boundaries, "excluded_sources", "seed.source_boundaries", errors);
986
- if (typeof seed.source_boundaries.canonical_write_allowed !== "boolean") {
987
- errors.push("seed.source_boundaries.canonical_write_allowed must be a boolean");
988
- }
989
- }
990
-
991
- if (seed.growth_rules && typeof seed.growth_rules === "object") {
992
- requireArray(seed.growth_rules, "allowed_object_families", "seed.growth_rules", errors);
993
- requireArray(seed.growth_rules, "allowed_relation_families", "seed.growth_rules", errors);
994
- if (!Number.isInteger(seed.growth_rules.max_initial_objects) || seed.growth_rules.max_initial_objects < 1) {
995
- errors.push("seed.growth_rules.max_initial_objects must be a positive integer");
996
- }
997
- if (!["light", "standard", "broad"].includes(seed.growth_rules.depth_mode)) {
998
- errors.push("seed.growth_rules.depth_mode must be light, standard or broad");
999
- }
1000
- }
1001
-
1002
- if (
1003
- seed.source_boundaries &&
1004
- seed.source_boundaries.canonical_write_allowed === true &&
1005
- Array.isArray(seed.review_gates) &&
1006
- !seed.review_gates.includes("human_review_before_canonical_write")
1007
- ) {
1008
- warnings.push("canonical_write_allowed is true without human_review_before_canonical_write gate");
1009
- }
1010
-
1011
- return { errors, warnings };
1012
- }
1013
-
1014
- function validateProfile(profilePath) {
1015
- const errors = [];
1016
- const warnings = [];
1017
- const profile = readJson(profilePath);
1018
- const label = "profile";
1019
-
1020
- requireString(profile, "id", label, errors);
1021
- requireString(profile, "name", label, errors);
1022
- requireString(profile, "version", label, errors);
1023
- requireString(profile, "description", label, errors);
1024
- requireArray(profile, "allowed_object_kinds", label, errors);
1025
- requireArray(profile, "allowed_relation_types", label, errors);
1026
- requireString(profile, "default_readiness", label, errors);
1027
- requireArray(profile, "governance_gates", label, errors);
1028
-
1029
- if (typeof profile.default_readiness === "string" && !readinessValues.has(profile.default_readiness)) {
1030
- errors.push(`${label}.default_readiness has unsupported value ${profile.default_readiness}`);
1031
- }
1032
-
1033
- if (Array.isArray(profile.allowed_object_kinds) && profile.allowed_object_kinds.length === 0) {
1034
- warnings.push("profile.allowed_object_kinds is empty");
1035
- }
1036
-
1037
- if (Array.isArray(profile.allowed_relation_types) && profile.allowed_relation_types.length === 0) {
1038
- warnings.push("profile.allowed_relation_types is empty");
1039
- }
1040
-
1041
- return { errors, warnings };
1042
- }
1043
-
1044
- function loadPackageGraph(packageDir, errors) {
1045
- const manifestLookup = findManifestPath(packageDir);
1046
- const manifest = fs.existsSync(manifestLookup) ? readPackageManifest(manifestLookup) : null;
1047
- const graphDir = path.join(packageDir, "graph");
1048
- const objectsPath = manifest
1049
- ? path.join(packageDir, manifest.graph && manifest.graph.objects ? manifest.graph.objects : "")
1050
- : path.join(graphDir, "objects.json");
1051
- const relationsPath = manifest
1052
- ? path.join(packageDir, manifest.graph && manifest.graph.relations ? manifest.graph.relations : "")
1053
- : path.join(graphDir, "relations.json");
1054
-
1055
- if (!fs.existsSync(objectsPath)) {
1056
- errors.push(`Missing ${objectsPath}`);
1057
- }
1058
- if (!fs.existsSync(relationsPath)) {
1059
- errors.push(`Missing ${relationsPath}`);
1060
- }
1061
- if (errors.length > 0) {
1062
- return { manifest, objects: [], relations: [] };
1063
- }
1064
-
1065
- return {
1066
- manifest,
1067
- objects: asArray(readJson(objectsPath), "graph/objects.json", errors),
1068
- relations: asArray(readJson(relationsPath), "graph/relations.json", errors)
1069
- };
1070
- }
1071
-
1072
- function validateStringSet(values, knownIds, label, errors) {
1073
- const seen = new Set();
1074
- for (const value of values) {
1075
- if (seen.has(value)) {
1076
- errors.push(`${label} contains duplicate value ${value}`);
1077
- }
1078
- seen.add(value);
1079
- if (!knownIds.has(value)) {
1080
- errors.push(`${label} references unknown id ${value}`);
1081
- }
1082
- }
1083
- }
1084
-
1085
- function validateContextPack(packageDir, contextPackPath) {
1086
- const errors = [];
1087
- const warnings = [];
1088
- const { manifest, objects, relations } = loadPackageGraph(packageDir, errors);
1089
- if (errors.length > 0) {
1090
- return { errors, warnings };
1091
- }
1092
-
1093
- const contextPack = readJson(contextPackPath);
1094
- const label = "context_pack";
1095
- requireString(contextPack, "id", label, errors);
1096
- requireString(contextPack, "task_id", label, errors);
1097
- requireString(contextPack, "source_graph", label, errors);
1098
- requireString(contextPack, "generated_at", label, errors);
1099
- requireArray(contextPack, "included_objects", label, errors);
1100
- requireArray(contextPack, "included_relations", label, errors);
1101
- requireArray(contextPack, "evidence", label, errors);
1102
- requireArray(contextPack, "limitations", label, errors);
1103
- requireOptionalArray(contextPack, "assumptions", label, errors);
1104
- requireOptionalArray(contextPack, "omissions", label, errors);
1105
-
1106
- if (typeof contextPack.id === "string" && !contextPack.id.startsWith("context_pack.")) {
1107
- warnings.push("context_pack.id should start with context_pack.");
1108
- }
1109
-
1110
- if (contextPack.generated_at !== undefined && !isValidDateTime(contextPack.generated_at)) {
1111
- errors.push("context_pack.generated_at must be a parseable date-time string");
1112
- }
1113
-
1114
- if (manifest && contextPack.source_graph !== manifest.id) {
1115
- errors.push(`context_pack.source_graph must match manifest.id ${manifest.id}`);
1116
- }
1117
-
1118
- if (Array.isArray(contextPack.limitations) && contextPack.limitations.length === 0) {
1119
- warnings.push("context_pack.limitations is empty");
1120
- }
1121
-
1122
- const objectIds = new Set(objects.map((object) => object.id));
1123
- const relationIds = new Set(relations.map((relation) => relation.id));
1124
- const evidenceObjectIds = new Set(
1125
- objects
1126
- .filter((object) => object.kind === "evidence")
1127
- .map((object) => object.id)
1128
- );
1129
-
1130
- if (Array.isArray(contextPack.included_objects)) {
1131
- validateStringSet(contextPack.included_objects, objectIds, "context_pack.included_objects", errors);
1132
- }
1133
- if (Array.isArray(contextPack.included_relations)) {
1134
- validateStringSet(contextPack.included_relations, relationIds, "context_pack.included_relations", errors);
1135
- }
1136
- if (Array.isArray(contextPack.evidence)) {
1137
- validateStringSet(contextPack.evidence, objectIds, "context_pack.evidence", errors);
1138
- for (const evidenceId of contextPack.evidence) {
1139
- if (objectIds.has(evidenceId) && !evidenceObjectIds.has(evidenceId)) {
1140
- warnings.push(`context_pack.evidence includes non-evidence object ${evidenceId}`);
1141
- }
1142
- }
1143
- }
1144
-
1145
- const selectedObjectIds = new Set(Array.isArray(contextPack.included_objects) ? contextPack.included_objects : []);
1146
- for (const relation of relations) {
1147
- if (!Array.isArray(contextPack.included_relations) || !contextPack.included_relations.includes(relation.id)) {
1148
- continue;
1149
- }
1150
- if (!selectedObjectIds.has(relation.source)) {
1151
- errors.push(`included relation ${relation.id} has source outside included_objects: ${relation.source}`);
1152
- }
1153
- if (!selectedObjectIds.has(relation.target)) {
1154
- errors.push(`included relation ${relation.id} has target outside included_objects: ${relation.target}`);
1155
- }
1156
- }
1157
-
1158
- if (!contextPack.selection) {
1159
- warnings.push("context_pack.selection is missing; generated packs should explain selection metadata");
1160
- return { errors, warnings };
1161
- }
1162
-
1163
- if (typeof contextPack.selection !== "object" || Array.isArray(contextPack.selection)) {
1164
- errors.push("context_pack.selection must be an object");
1165
- return { errors, warnings };
1166
- }
1167
-
1168
- requireString(contextPack.selection, "method", "context_pack.selection", errors);
1169
- requireArray(contextPack.selection, "task_tokens", "context_pack.selection", errors);
1170
- requireJsonArray(contextPack.selection, "object_explanations", "context_pack.selection", errors);
1171
- requireJsonArray(contextPack.selection, "relation_explanations", "context_pack.selection", errors);
1172
-
1173
- if (Array.isArray(contextPack.selection.task_tokens) && contextPack.selection.task_tokens.length === 0) {
1174
- warnings.push("context_pack.selection.task_tokens is empty");
1175
- }
1176
-
1177
- const explainedObjectIds = new Set();
1178
- if (Array.isArray(contextPack.selection.object_explanations)) {
1179
- for (const [index, explanation] of contextPack.selection.object_explanations.entries()) {
1180
- const explanationLabel = `context_pack.selection.object_explanations[${index}]`;
1181
- requireString(explanation, "id", explanationLabel, errors);
1182
- requireArray(explanation, "reasons", explanationLabel, errors);
1183
-
1184
- if (typeof explanation.relevance_score !== "number" || !Number.isFinite(explanation.relevance_score)) {
1185
- errors.push(`${explanationLabel}.relevance_score must be a finite number`);
1186
- }
1187
- if (typeof explanation.id === "string") {
1188
- if (explainedObjectIds.has(explanation.id)) {
1189
- errors.push(`${explanationLabel}.id duplicates ${explanation.id}`);
1190
- }
1191
- explainedObjectIds.add(explanation.id);
1192
- if (!selectedObjectIds.has(explanation.id)) {
1193
- errors.push(`${explanationLabel}.id must reference included object ${explanation.id}`);
1194
- }
1195
- }
1196
- if (Array.isArray(explanation.reasons) && explanation.reasons.length === 0) {
1197
- warnings.push(`${explanationLabel}.reasons is empty`);
1198
- }
1199
- }
1200
- }
1201
-
1202
- for (const objectId of selectedObjectIds) {
1203
- if (!explainedObjectIds.has(objectId)) {
1204
- errors.push(`included object ${objectId} is missing selection.object_explanations entry`);
1205
- }
1206
- }
1207
-
1208
- const selectedRelationIds = new Set(Array.isArray(contextPack.included_relations) ? contextPack.included_relations : []);
1209
- const explainedRelationIds = new Set();
1210
- if (Array.isArray(contextPack.selection.relation_explanations)) {
1211
- for (const [index, explanation] of contextPack.selection.relation_explanations.entries()) {
1212
- const explanationLabel = `context_pack.selection.relation_explanations[${index}]`;
1213
- requireString(explanation, "id", explanationLabel, errors);
1214
- requireString(explanation, "reason", explanationLabel, errors);
1215
- requireString(explanation, "source", explanationLabel, errors);
1216
- requireString(explanation, "target", explanationLabel, errors);
1217
- if (typeof explanation.id === "string") {
1218
- if (explainedRelationIds.has(explanation.id)) {
1219
- errors.push(`${explanationLabel}.id duplicates ${explanation.id}`);
1220
- }
1221
- explainedRelationIds.add(explanation.id);
1222
- if (!selectedRelationIds.has(explanation.id)) {
1223
- errors.push(`${explanationLabel}.id must reference included relation ${explanation.id}`);
1224
- }
1225
- }
1226
- if (typeof explanation.source === "string" && !selectedObjectIds.has(explanation.source)) {
1227
- errors.push(`${explanationLabel}.source must reference an included object`);
1228
- }
1229
- if (typeof explanation.target === "string" && !selectedObjectIds.has(explanation.target)) {
1230
- errors.push(`${explanationLabel}.target must reference an included object`);
1231
- }
1232
- }
1233
- }
1234
-
1235
- for (const relationId of selectedRelationIds) {
1236
- if (!explainedRelationIds.has(relationId)) {
1237
- errors.push(`included relation ${relationId} is missing selection.relation_explanations entry`);
1238
- }
1239
- }
1240
-
1241
- return { errors, warnings };
1242
- }
1243
-
1244
- function validateImplementationControlCycle(cyclePath) {
1245
- const errors = [];
1246
- const warnings = [];
1247
- const result = readJson(cyclePath);
1248
- const label = "implementation_control_cycle";
1249
-
1250
- requireString(result, "schema_version", label, errors);
1251
- requireString(result, "id", label, errors);
1252
- requireString(result, "profile", label, errors);
1253
- requireString(result, "public_safety", label, errors);
1254
- requireJsonArray(result, "cycles", label, errors);
1255
- requireJsonArray(result, "cycle_transitions", label, errors);
1256
- requireArray(result, "kaizen_finding_taxonomy", label, errors);
1257
- requireArray(result, "kaizen_blocking_findings", label, errors);
1258
- requireString(result, "kaizen_default_rule", label, errors);
1259
- requireArray(result, "boundaries", label, errors);
1260
- requireArray(result, "limitations", label, errors);
1261
-
1262
- if (result.profile !== undefined && result.profile !== "implementation_control") {
1263
- errors.push(`${label}.profile must be implementation_control`);
1264
- }
1265
- if (result.public_safety !== undefined && result.public_safety !== "synthetic_public") {
1266
- errors.push(`${label}.public_safety must be synthetic_public`);
1267
- }
1268
-
1269
- const requiredCycleIds = new Set([
1270
- "human_projection_feedback",
1271
- "implementation_planning",
1272
- "bounded_work_batch",
1273
- "review_and_evidence",
1274
- "release_or_publish",
1275
- "runtime_feedback",
1276
- "kaizen_improvement"
1277
- ]);
1278
- const requiredTransitionFields = [
1279
- "from",
1280
- "to",
1281
- "trigger",
1282
- "required_outputs",
1283
- "required_gates",
1284
- "handoff_artifact",
1285
- "owner",
1286
- "failure_behavior",
1287
- "recovery_behavior"
1288
- ];
1289
- const requiredTransitions = [
1290
- ["human_projection_feedback", "implementation_planning", "equilibrium_reached"],
1291
- ["human_projection_feedback", "kaizen_improvement", "cycle_completed"],
1292
- ["implementation_planning", "bounded_work_batch", "launch_record_ready"],
1293
- ["implementation_planning", "kaizen_improvement", "cycle_completed"],
1294
- ["bounded_work_batch", "review_and_evidence", "evidence_ready"],
1295
- ["bounded_work_batch", "kaizen_improvement", "cycle_completed"],
1296
- ["review_and_evidence", "release_or_publish", "review_approved"],
1297
- ["review_and_evidence", "human_projection_feedback", "baseline_gap_found"],
1298
- ["review_and_evidence", "kaizen_improvement", "cycle_completed"],
1299
- ["release_or_publish", "runtime_feedback", "released_or_published"],
1300
- ["release_or_publish", "kaizen_improvement", "cycle_completed"],
1301
- ["runtime_feedback", "human_projection_feedback", "graph_or_projection_improvement_required"],
1302
- ["runtime_feedback", "implementation_planning", "implementation_change_required"],
1303
- ["runtime_feedback", "kaizen_improvement", "cycle_completed"],
1304
- ["kaizen_improvement", "human_projection_feedback", "graph_or_projection_improvement_required"],
1305
- ["kaizen_improvement", "implementation_planning", "planning_improvement_required"],
1306
- ["kaizen_improvement", "bounded_work_batch", "implementation_rework_required"],
1307
- ["kaizen_improvement", "runtime_feedback", "runtime_evidence_required"]
1308
- ];
1309
- const requiredKaizenFindings = [
1310
- "artifact_improvement",
1311
- "graph_spec_improvement",
1312
- "process_improvement",
1313
- "validator_improvement",
1314
- "tooling_improvement",
1315
- "dna_alignment_issue",
1316
- "quality_regression",
1317
- "safety_regression",
1318
- "critical_drift",
1319
- "user_value_gap"
1320
- ];
1321
- const requiredBlockingFindings = [
1322
- "safety_regression",
1323
- "quality_regression",
1324
- "dna_alignment_issue",
1325
- "critical_drift"
1326
- ];
1327
- const cycleIds = new Set();
1328
- const forbiddenAutoUpdateTerms = [
1329
- "automatic canonical update",
1330
- "automatically updates canonical",
1331
- "auto canonical update",
1332
- "feedback directly updates",
1333
- "evidence is approval"
1334
- ];
1335
-
1336
- if (Array.isArray(result.cycles)) {
1337
- for (const [index, cycle] of result.cycles.entries()) {
1338
- const cycleLabel = `${label}.cycles[${index}]`;
1339
- requireString(cycle, "id", cycleLabel, errors);
1340
- requireString(cycle, "purpose", cycleLabel, errors);
1341
- requireArray(cycle, "stages", cycleLabel, errors);
1342
- requireArray(cycle, "inputs", cycleLabel, errors);
1343
- requireArray(cycle, "outputs", cycleLabel, errors);
1344
- requireArray(cycle, "gates", cycleLabel, errors);
1345
- requireArray(cycle, "validators", cycleLabel, errors);
1346
- requireString(cycle, "recovery_behavior", cycleLabel, errors);
1347
- requireString(cycle, "repeat_condition", cycleLabel, errors);
1348
- requireString(cycle, "promotion_path", cycleLabel, errors);
1349
- requireArray(cycle, "evidence_refs", cycleLabel, errors);
1350
- requireArray(cycle, "limitations", cycleLabel, errors);
1351
-
1352
- if (typeof cycle.id === "string") {
1353
- if (cycleIds.has(cycle.id)) {
1354
- errors.push(`${cycleLabel}.id duplicates ${cycle.id}`);
1355
- }
1356
- cycleIds.add(cycle.id);
1357
- }
1358
-
1359
- if (Array.isArray(cycle.stages) && cycle.stages.length < 2) {
1360
- errors.push(`${cycleLabel}.stages must contain at least two stages`);
1361
- }
1362
- if (Array.isArray(cycle.gates) && cycle.gates.length === 0) {
1363
- errors.push(`${cycleLabel}.gates must not be empty`);
1364
- }
1365
- if (Array.isArray(cycle.validators) && cycle.validators.length === 0) {
1366
- errors.push(`${cycleLabel}.validators must not be empty`);
1367
- }
1368
- if (Array.isArray(cycle.evidence_refs) && cycle.evidence_refs.length === 0) {
1369
- errors.push(`${cycleLabel}.evidence_refs must not be empty`);
1370
- }
1371
-
1372
- const cycleText = JSON.stringify(cycle).toLowerCase();
1373
- for (const forbiddenTerm of forbiddenAutoUpdateTerms) {
1374
- if (cycleText.includes(forbiddenTerm)) {
1375
- errors.push(`${cycleLabel} contains forbidden auto-update semantics: ${forbiddenTerm}`);
1376
- }
1377
- }
1378
- }
1379
- }
1380
-
1381
- for (const requiredCycleId of requiredCycleIds) {
1382
- if (!cycleIds.has(requiredCycleId)) {
1383
- errors.push(`${label}.cycles is missing required cycle ${requiredCycleId}`);
1384
- }
1385
- }
1386
-
1387
- if (Array.isArray(result.cycle_transitions)) {
1388
- const transitionKeys = new Set();
1389
- for (const [index, transition] of result.cycle_transitions.entries()) {
1390
- const transitionLabel = `${label}.cycle_transitions[${index}]`;
1391
-
1392
- for (const field of requiredTransitionFields) {
1393
- if (["required_outputs", "required_gates"].includes(field)) {
1394
- requireArray(transition, field, transitionLabel, errors);
1395
- if (Array.isArray(transition[field]) && transition[field].length === 0) {
1396
- errors.push(`${transitionLabel}.${field} must not be empty`);
1397
- }
1398
- } else {
1399
- requireString(transition, field, transitionLabel, errors);
1400
- }
1401
- }
1402
-
1403
- if (typeof transition.from === "string" && !cycleIds.has(transition.from)) {
1404
- errors.push(`${transitionLabel}.from references unknown cycle ${transition.from}`);
1405
- }
1406
- if (typeof transition.to === "string" && !cycleIds.has(transition.to)) {
1407
- errors.push(`${transitionLabel}.to references unknown cycle ${transition.to}`);
1408
- }
1409
-
1410
- const transitionKey = `${transition.from ?? "?"}->${transition.to ?? "?"}:${transition.trigger ?? "?"}`;
1411
- if (transitionKeys.has(transitionKey)) {
1412
- errors.push(`${transitionLabel} duplicates transition ${transitionKey}`);
1413
- }
1414
- transitionKeys.add(transitionKey);
1415
-
1416
- const transitionText = JSON.stringify(transition).toLowerCase();
1417
- for (const forbiddenTerm of forbiddenAutoUpdateTerms) {
1418
- if (transitionText.includes(forbiddenTerm)) {
1419
- errors.push(`${transitionLabel} contains forbidden auto-update semantics: ${forbiddenTerm}`);
1420
- }
1421
- }
1422
- }
1423
-
1424
- for (const [from, to, trigger] of requiredTransitions) {
1425
- const transitionKey = `${from}->${to}:${trigger}`;
1426
- if (!transitionKeys.has(transitionKey)) {
1427
- errors.push(`${label}.cycle_transitions is missing required transition ${transitionKey}`);
1428
- }
1429
- }
1430
-
1431
- for (const cycleId of requiredCycleIds) {
1432
- if (cycleId === "kaizen_improvement") {
1433
- continue;
1434
- }
1435
- const transitionKey = `${cycleId}->kaizen_improvement:cycle_completed`;
1436
- if (!transitionKeys.has(transitionKey)) {
1437
- errors.push(`${label}.cycle_transitions must route ${cycleId} to kaizen_improvement on cycle_completed`);
1438
- }
1439
- }
1440
- }
1441
-
1442
- if (Array.isArray(result.kaizen_finding_taxonomy)) {
1443
- for (const finding of requiredKaizenFindings) {
1444
- if (!result.kaizen_finding_taxonomy.includes(finding)) {
1445
- errors.push(`${label}.kaizen_finding_taxonomy is missing ${finding}`);
1446
- }
1447
- }
1448
- }
1449
-
1450
- if (Array.isArray(result.kaizen_blocking_findings)) {
1451
- for (const finding of requiredBlockingFindings) {
1452
- if (!result.kaizen_blocking_findings.includes(finding)) {
1453
- errors.push(`${label}.kaizen_blocking_findings is missing ${finding}`);
1454
- }
1455
- }
1456
- }
1457
-
1458
- const kaizenRule = typeof result.kaizen_default_rule === "string" ? result.kaizen_default_rule.toLowerCase() : "";
1459
- for (const expectedTerm of ["safety", "quality", "dna", "critical drift"]) {
1460
- if (kaizenRule && !kaizenRule.includes(expectedTerm)) {
1461
- warnings.push(`${label}.kaizen_default_rule should mention ${expectedTerm}`);
1462
- }
1463
- }
1464
-
1465
- if (Array.isArray(result.boundaries)) {
1466
- const boundaryText = result.boundaries.join("\n").toLowerCase();
1467
- const requiredBoundaries = [
1468
- "generated",
1469
- "evidence",
1470
- "feedback",
1471
- "proposal",
1472
- "ready"
1473
- ];
1474
- for (const requiredBoundary of requiredBoundaries) {
1475
- if (!boundaryText.includes(requiredBoundary)) {
1476
- warnings.push(`${label}.boundaries should mention ${requiredBoundary}`);
1477
- }
1478
- }
1479
- }
1480
-
1481
- return { errors, warnings };
1482
- }
1483
-
1484
- function validateCharacterLayerIntegration(resultPath) {
1485
- const errors = [];
1486
- const warnings = [];
1487
- const result = readJson(resultPath);
1488
- const label = "character_layer_integration";
1489
-
1490
- requireString(result, "schema_version", label, errors);
1491
- requireString(result, "profile", label, errors);
1492
- requireString(result, "public_safety", label, errors);
1493
- requireString(result, "integration_id", label, errors);
1494
- requireString(result, "character_package_ref", label, errors);
1495
- requireArray(result, "required_gates", label, errors);
1496
- requireArray(result, "evidence_refs", label, errors);
1497
- requireArray(result, "limitations", label, errors);
1498
- requireJsonArray(result, "ai_employee_links", label, errors);
1499
- requireObject(result, "process_control_links", label, errors);
1500
- requireObject(result, "runtime_context_boundary", label, errors);
1501
-
1502
- if (result.profile !== undefined && result.profile !== "character_layer") {
1503
- errors.push(`${label}.profile must be character_layer`);
1504
- }
1505
- if (result.public_safety !== undefined && result.public_safety !== "synthetic_public") {
1506
- errors.push(`${label}.public_safety must be synthetic_public`);
1507
- }
1508
-
1509
- if (Array.isArray(result.ai_employee_links)) {
1510
- result.ai_employee_links.forEach((link, index) => {
1511
- const linkLabel = `${label}.ai_employee_links[${index}]`;
1512
- requireString(link, "ai_employee_ref", linkLabel, errors);
1513
- requireString(link, "role_ref", linkLabel, errors);
1514
- requireString(link, "role_character_profile_ref", linkLabel, errors);
1515
- requireArray(link, "composition_relations", linkLabel, errors);
1516
- const relationText = Array.isArray(link.composition_relations) ? link.composition_relations.join("\n") : "";
1517
- for (const requiredRelation of ["governs_role", "governs_employee", "specializes_character", "uses_reflection_protocol"]) {
1518
- if (!relationText.includes(requiredRelation)) {
1519
- errors.push(`${linkLabel}.composition_relations must include ${requiredRelation}`);
1520
- }
1521
- }
1522
- });
1523
- }
1524
-
1525
- if (result.process_control_links && typeof result.process_control_links === "object") {
1526
- for (const field of [
1527
- "launch_record_ref",
1528
- "process_control_contract_ref",
1529
- "technology_quality_feedback_ref"
1530
- ]) {
1531
- requireString(result.process_control_links, field, `${label}.process_control_links`, errors);
1532
- }
1533
- requireArray(result.process_control_links, "transition_gate_refs", `${label}.process_control_links`, errors);
1534
- }
1535
-
1536
- if (result.runtime_context_boundary && typeof result.runtime_context_boundary === "object") {
1537
- for (const field of [
1538
- "generated_context_ref",
1539
- "reflection_protocol_ref",
1540
- "authorization_boundary",
1541
- "canonical_update_boundary"
1542
- ]) {
1543
- requireString(result.runtime_context_boundary, field, `${label}.runtime_context_boundary`, errors);
1544
- }
1545
- }
1546
-
1547
- const gateText = Array.isArray(result.required_gates) ? result.required_gates.join("\n") : "";
1548
- for (const requiredGate of [
1549
- "human_review_before_canonical_write",
1550
- "approval_before_external_action",
1551
- "technology_quality_feedback"
1552
- ]) {
1553
- if (!gateText.includes(requiredGate)) {
1554
- errors.push(`${label}.required_gates must include ${requiredGate}`);
1555
- }
1556
- }
1557
-
1558
- const resultText = JSON.stringify(result).toLowerCase();
1559
- for (const forbiddenTerm of [
1560
- "/users/rim/documents/" + "github/",
1561
- "simai private",
1562
- "private runtime " + "trace",
1563
- "generated context authorizes",
1564
- "evidence authorizes",
1565
- "feedback automatically updates",
1566
- "automatic canonical update",
1567
- "grants tool permission",
1568
- "can bypass approval"
1569
- ]) {
1570
- if (resultText.includes(forbiddenTerm)) {
1571
- errors.push(`${label} contains forbidden integration boundary term: ${forbiddenTerm}`);
1572
- }
1573
- }
1574
-
1575
- for (const requiredBoundary of [
1576
- "does not authorize",
1577
- "owner review",
1578
- "canonical"
1579
- ]) {
1580
- if (!resultText.includes(requiredBoundary)) {
1581
- warnings.push(`${label} should mention ${requiredBoundary}`);
1582
- }
1583
- }
1584
-
1585
- return { errors, warnings, result };
1586
- }
1587
-
1588
- function validateModelPortabilityEvidence(resultPath) {
1589
- const errors = [];
1590
- const warnings = [];
1591
- const result = readJson(resultPath);
1592
- const label = "model_portability_evidence";
1593
-
1594
- requireString(result, "schema_version", label, errors);
1595
- requireString(result, "profile", label, errors);
1596
- requireString(result, "public_safety", label, errors);
1597
- requireString(result, "evidence_id", label, errors);
1598
- requireString(result, "character_profile_ref", label, errors);
1599
- requireString(result, "task_set_ref", label, errors);
1600
- requireString(result, "comparison_verdict", label, errors);
1601
- requireArray(result, "evidence_refs", label, errors);
1602
- requireArray(result, "limitations", label, errors);
1603
- requireJsonArray(result, "model_runs", label, errors);
1604
- requireObject(result, "comparison_metrics", label, errors);
1605
-
1606
- if (result.profile !== undefined && result.profile !== "character_layer") {
1607
- errors.push(`${label}.profile must be character_layer`);
1608
- }
1609
- if (result.public_safety !== undefined && result.public_safety !== "synthetic_public") {
1610
- errors.push(`${label}.public_safety must be synthetic_public`);
1611
- }
1612
-
1613
- const verdicts = new Set([
1614
- "portable_within_fixture_limits",
1615
- "needs_review",
1616
- "regressed",
1617
- "insufficient_evidence"
1618
- ]);
1619
- if (typeof result.comparison_verdict === "string" && !verdicts.has(result.comparison_verdict)) {
1620
- errors.push(`${label}.comparison_verdict has unsupported value ${result.comparison_verdict}`);
1621
- }
1622
-
1623
- if (Array.isArray(result.model_runs)) {
1624
- if (result.model_runs.length < 2) {
1625
- errors.push(`${label}.model_runs must include at least two model runs`);
1626
- }
1627
- result.model_runs.forEach((run, index) => {
1628
- const runLabel = `${label}.model_runs[${index}]`;
1629
- requireString(run, "model_ref", runLabel, errors);
1630
- requireString(run, "run_ref", runLabel, errors);
1631
- requireString(run, "notes", runLabel, errors);
1632
- requireArray(run, "passed_fixtures", runLabel, errors);
1633
- requireArray(run, "failed_fixtures", runLabel, errors);
1634
- requireArray(run, "boundary_violations", runLabel, errors);
1635
- });
1636
- }
1637
-
1638
- if (result.comparison_metrics && typeof result.comparison_metrics === "object") {
1639
- for (const metric of [
1640
- "boundary_violation_delta",
1641
- "false_completion_claim_delta",
1642
- "evidence_authorization_confusion_delta",
1643
- "feedback_update_confusion_delta",
1644
- "blocker_reporting_delta",
1645
- "escalation_correctness_delta"
1646
- ]) {
1647
- if (typeof result.comparison_metrics[metric] !== "number") {
1648
- errors.push(`${label}.comparison_metrics.${metric} must be a number`);
1649
- }
1650
- }
1651
- }
1652
-
1653
- const resultText = JSON.stringify(result).toLowerCase();
1654
- for (const forbiddenTerm of [
1655
- "/users/rim/documents/" + "github/",
1656
- "simai private",
1657
- "private runtime " + "trace",
1658
- "proves model equivalence",
1659
- "guarantees model replacement",
1660
- "production-ready replacement",
1661
- "no review required"
1662
- ]) {
1663
- if (resultText.includes(forbiddenTerm)) {
1664
- errors.push(`${label} contains forbidden portability claim: ${forbiddenTerm}`);
1665
- }
1666
- }
1667
-
1668
- for (const requiredLimit of ["synthetic", "does not prove", "model-dependent"]) {
1669
- if (!resultText.includes(requiredLimit)) {
1670
- warnings.push(`${label}.limitations should mention ${requiredLimit}`);
1671
- }
1672
- }
1673
-
1674
- return { errors, warnings, result };
1675
- }
1676
-
1677
- function validateCharacterLayerReadiness(resultPath) {
1678
- const errors = [];
1679
- const warnings = [];
1680
- const result = readJson(resultPath);
1681
- const label = "character_layer_readiness";
1682
-
1683
- requireString(result, "schema_version", label, errors);
1684
- requireString(result, "profile", label, errors);
1685
- requireString(result, "public_safety", label, errors);
1686
- requireString(result, "readiness_id", label, errors);
1687
- requireString(result, "target_release_track", label, errors);
1688
- requireString(result, "readiness_verdict", label, errors);
1689
- requireArray(result, "validation_commands", label, errors);
1690
- requireArray(result, "evidence_refs", label, errors);
1691
- requireArray(result, "claim_boundaries", label, errors);
1692
- requireArray(result, "remaining_limits", label, errors);
1693
- requireJsonArray(result, "completed_capabilities", label, errors);
1694
-
1695
- if (result.profile !== undefined && result.profile !== "character_layer") {
1696
- errors.push(`${label}.profile must be character_layer`);
1697
- }
1698
- if (result.public_safety !== undefined && result.public_safety !== "synthetic_public") {
1699
- errors.push(`${label}.public_safety must be synthetic_public`);
1700
- }
1701
-
1702
- const verdicts = new Set([
1703
- "ready_for_1_0_candidate",
1704
- "needs_hardening",
1705
- "blocked",
1706
- "insufficient_evidence"
1707
- ]);
1708
- if (typeof result.readiness_verdict === "string" && !verdicts.has(result.readiness_verdict)) {
1709
- errors.push(`${label}.readiness_verdict has unsupported value ${result.readiness_verdict}`);
1710
- }
1711
-
1712
- const completedIds = new Set();
1713
- if (Array.isArray(result.completed_capabilities)) {
1714
- result.completed_capabilities.forEach((capability, index) => {
1715
- const capLabel = `${label}.completed_capabilities[${index}]`;
1716
- requireString(capability, "id", capLabel, errors);
1717
- requireString(capability, "status", capLabel, errors);
1718
- requireArray(capability, "evidence_refs", capLabel, errors);
1719
- if (capability.status !== undefined && !["completed", "partial", "missing"].includes(capability.status)) {
1720
- errors.push(`${capLabel}.status has unsupported value ${capability.status}`);
1721
- }
1722
- if (capability.status === "completed" && typeof capability.id === "string") {
1723
- completedIds.add(capability.id);
1724
- }
1725
- });
1726
- }
1727
-
1728
- for (const requiredCapability of [
1729
- "profile_vocabulary",
1730
- "minimal_fixture",
1731
- "starter_pack",
1732
- "semantic_negative_fixtures",
1733
- "cross_layer_integration",
1734
- "model_portability_evidence_shape"
1735
- ]) {
1736
- if (!completedIds.has(requiredCapability)) {
1737
- errors.push(`${label}.completed_capabilities must include completed ${requiredCapability}`);
1738
- }
1739
- }
1740
-
1741
- const commandText = Array.isArray(result.validation_commands) ? result.validation_commands.join("\n") : "";
1742
- for (const requiredCommand of [
1743
- "validate:character-layer",
1744
- "validate:character-layer-starter",
1745
- "validate:character-layer-integration",
1746
- "validate:model-portability-evidence",
1747
- "test:character-layer-semantic-negative",
1748
- "npm test",
1749
- "release:check"
1750
- ]) {
1751
- if (!commandText.includes(requiredCommand)) {
1752
- errors.push(`${label}.validation_commands must include ${requiredCommand}`);
1753
- }
1754
- }
1755
-
1756
- const resultText = JSON.stringify(result).toLowerCase();
1757
- for (const forbiddenTerm of [
1758
- "/users/rim/documents/" + "github/",
1759
- "simai private",
1760
- "private runtime " + "trace",
1761
- "proves broad model equivalence",
1762
- "guarantees model replacement",
1763
- "production autonomous execution safety is proven",
1764
- "peer-reviewed proof"
1765
- ]) {
1766
- if (resultText.includes(forbiddenTerm)) {
1767
- errors.push(`${label} contains forbidden readiness claim: ${forbiddenTerm}`);
1768
- }
1769
- }
1770
-
1771
- for (const requiredBoundary of [
1772
- "does not prove",
1773
- "not authorize canonical updates",
1774
- "no peer-reviewed scientific proof",
1775
- "model replacement"
1776
- ]) {
1777
- if (!resultText.includes(requiredBoundary)) {
1778
- warnings.push(`${label} should mention ${requiredBoundary}`);
1779
- }
1780
- }
1781
-
1782
- return { errors, warnings, result };
1783
- }
1784
-
1785
- function validatePublicImplementationControlResult(resultPath, mode) {
1786
- const errors = [];
1787
- const warnings = [];
1788
- const result = readJson(resultPath);
1789
- const label = mode.replace(/-/g, "_");
1790
-
1791
- requireString(result, "schema_version", label, errors);
1792
- requireString(result, "id", label, errors);
1793
- requireString(result, "profile", label, errors);
1794
- requireString(result, "public_safety", label, errors);
1795
- requireArray(result, "evidence_refs", label, errors);
1796
- requireArray(result, "limitations", label, errors);
1797
-
1798
- if (result.profile !== undefined && result.profile !== "implementation_control") {
1799
- errors.push(`${label}.profile must be implementation_control`);
1800
- }
1801
- if (result.public_safety !== undefined && result.public_safety !== "synthetic_public") {
1802
- errors.push(`${label}.public_safety must be synthetic_public`);
1803
- }
1804
-
1805
- const resultText = JSON.stringify(result).toLowerCase();
1806
- const forbiddenTerms = [
1807
- "/users/rim/documents/" + "github/",
1808
- "lar" + "ena",
1809
- "simai private",
1810
- "source/" + "workflow",
1811
- "private runtime " + "trace",
1812
- "automatic canonical update",
1813
- "feedback directly updates",
1814
- "evidence is approval"
1815
- ];
1816
- for (const forbiddenTerm of forbiddenTerms) {
1817
- if (resultText.includes(forbiddenTerm)) {
1818
- errors.push(`${label} contains forbidden public-transfer term: ${forbiddenTerm}`);
1819
- }
1820
- }
1821
-
1822
- if (mode === "graph-dna-alignment") {
1823
- requireObject(result, "parent_dna", label, errors);
1824
- requireObject(result, "component_dna", label, errors);
1825
- requireObject(result, "alignment", label, errors);
1826
- if (result.parent_dna && typeof result.parent_dna === "object") {
1827
- requireString(result.parent_dna, "mission", `${label}.parent_dna`, errors);
1828
- requireString(result.parent_dna, "evolution_vector", `${label}.parent_dna`, errors);
1829
- requireArray(result.parent_dna, "non_negotiable_principles", `${label}.parent_dna`, errors);
1830
- }
1831
- if (result.component_dna && typeof result.component_dna === "object") {
1832
- requireArray(result.component_dna, "owns", `${label}.component_dna`, errors);
1833
- requireArray(result.component_dna, "must_not_own", `${label}.component_dna`, errors);
1834
- requireArray(result.component_dna, "invariants", `${label}.component_dna`, errors);
1835
- requireArray(result.component_dna, "success_criteria", `${label}.component_dna`, errors);
1836
- requireArray(result.component_dna, "anti_patterns", `${label}.component_dna`, errors);
1837
- }
1838
- if (result.alignment && typeof result.alignment === "object" && typeof result.alignment.proposal_required !== "boolean") {
1839
- errors.push(`${label}.alignment.proposal_required must be a boolean`);
1840
- }
1841
- }
1842
-
1843
- if (mode === "work-state-machine") {
1844
- requireArray(result, "states", label, errors);
1845
- requireJsonArray(result, "transitions", label, errors);
1846
- requireArray(result, "false_transition_guards", label, errors);
1847
- const stateText = Array.isArray(result.states) ? result.states.join("\n") : "";
1848
- for (const requiredState of ["planned", "ready_to_execute", "evidence_recorded", "sync_proposed", "approved"]) {
1849
- if (!stateText.includes(requiredState)) {
1850
- errors.push(`${label}.states must include ${requiredState}`);
1851
- }
1852
- }
1853
- const guardText = Array.isArray(result.false_transition_guards) ? result.false_transition_guards.join("\n").toLowerCase() : "";
1854
- for (const requiredGuard of ["ready", "written", "sync"]) {
1855
- if (!guardText.includes(requiredGuard)) {
1856
- warnings.push(`${label}.false_transition_guards should mention ${requiredGuard}`);
1857
- }
1858
- }
1859
- }
1860
-
1861
- if (mode === "launch-record") {
1862
- for (const field of [
1863
- "workflow_id",
1864
- "process_model_id",
1865
- "cycle_id",
1866
- "current_state",
1867
- "target_state",
1868
- "owner_role"
1869
- ]) {
1870
- requireString(result, field, label, errors);
1871
- }
1872
- for (const field of [
1873
- "allowed_files",
1874
- "forbidden_files",
1875
- "allowed_actions",
1876
- "required_gates",
1877
- "required_evidence",
1878
- "stop_conditions"
1879
- ]) {
1880
- requireArray(result, field, label, errors);
1881
- }
1882
- if (typeof result.approved_by_user !== "boolean") {
1883
- errors.push(`${label}.approved_by_user must be a boolean`);
1884
- }
1885
- const launchText = JSON.stringify(result).toLowerCase();
1886
- for (const requiredBoundary of ["not execution", "not implementation", "not approval", "not release"]) {
1887
- if (!launchText.includes(requiredBoundary)) {
1888
- warnings.push(`${label}.limitations should mention ${requiredBoundary}`);
1889
- }
1890
- }
1891
- }
1892
-
1893
- if (mode === "process-control-contract") {
1894
- for (const field of ["process_id", "cycle_id", "state_machine_id", "recovery_behavior"]) {
1895
- requireString(result, field, label, errors);
1896
- }
1897
- requireObject(result, "launch_record_policy", label, errors);
1898
- requireObject(result, "kaizen_policy", label, errors);
1899
- requireArray(result, "evidence_requirements", label, errors);
1900
- requireArray(result, "risk_controls", label, errors);
1901
- requireArray(result, "validators", label, errors);
1902
-
1903
- if (result.launch_record_policy && typeof result.launch_record_policy === "object") {
1904
- requireArray(result.launch_record_policy, "required_for_states", `${label}.launch_record_policy`, errors);
1905
- requireArray(result.launch_record_policy, "required_for_transitions", `${label}.launch_record_policy`, errors);
1906
- if (typeof result.launch_record_policy.approval_required !== "boolean") {
1907
- errors.push(`${label}.launch_record_policy.approval_required must be a boolean`);
1908
- }
1909
- }
1910
-
1911
- if (result.kaizen_policy && typeof result.kaizen_policy === "object") {
1912
- if (result.kaizen_policy.terminal_state_requires_review_or_skip !== true) {
1913
- errors.push(`${label}.kaizen_policy.terminal_state_requires_review_or_skip must be true`);
1914
- }
1915
- requireString(result.kaizen_policy, "accepted_skip_field", `${label}.kaizen_policy`, errors);
1916
- }
1917
-
1918
- if (result.technology_quality_feedback_policy !== undefined) {
1919
- requireObject(result, "technology_quality_feedback_policy", label, errors);
1920
- if (result.technology_quality_feedback_policy && typeof result.technology_quality_feedback_policy === "object") {
1921
- requireArray(result.technology_quality_feedback_policy, "required_for_transitions", `${label}.technology_quality_feedback_policy`, errors);
1922
- requireArray(result.technology_quality_feedback_policy, "accepted_verdicts", `${label}.technology_quality_feedback_policy`, errors);
1923
- if (result.technology_quality_feedback_policy.blocking_findings_stop_transition !== true) {
1924
- errors.push(`${label}.technology_quality_feedback_policy.blocking_findings_stop_transition must be true`);
1925
- }
1926
- }
1927
- }
1928
-
1929
- const validatorText = Array.isArray(result.validators) ? result.validators.join("\n") : "";
1930
- for (const requiredValidator of ["launch-record", "process-transition"]) {
1931
- if (!validatorText.includes(requiredValidator)) {
1932
- errors.push(`${label}.validators must include ${requiredValidator}`);
1933
- }
1934
- }
1935
- if (
1936
- result.technology_quality_feedback_policy !== undefined &&
1937
- !validatorText.includes("technology-quality-feedback")
1938
- ) {
1939
- errors.push(`${label}.validators must include technology-quality-feedback when technology_quality_feedback_policy is present`);
1940
- }
1941
- }
1942
-
1943
- if (mode === "technology-quality-feedback") {
1944
- const classifications = new Set([
1945
- "accepted",
1946
- "work_fix_required",
1947
- "test_gap",
1948
- "spec_gap",
1949
- "graph_update_proposal",
1950
- "process_improvement",
1951
- "release_blocker",
1952
- "security_blocker",
1953
- "defer_with_reason"
1954
- ]);
1955
- const verdicts = new Set([
1956
- "accepted",
1957
- "accepted_with_deferred_items",
1958
- "changes_requested",
1959
- "blocked_by_spec_gap",
1960
- "blocked_by_security",
1961
- "blocked_by_missing_evidence",
1962
- "release_not_ready"
1963
- ]);
1964
- const severities = new Set(["critical", "high", "medium", "low"]);
1965
- const acceptedVerdicts = new Set(["accepted", "accepted_with_deferred_items"]);
1966
-
1967
- for (const field of ["technology_ref", "process_id", "launch_record_ref", "verdict", "next_transition"]) {
1968
- requireString(result, field, label, errors);
1969
- }
1970
- for (const field of [
1971
- "work_evidence_refs",
1972
- "required_steps",
1973
- "completed_steps",
1974
- "missing_steps",
1975
- "review_dimensions",
1976
- "feedback_classification",
1977
- "blocking_findings",
1978
- "kaizen_refs"
1979
- ]) {
1980
- requireArray(result, field, label, errors);
1981
- }
1982
- requireJsonArray(result, "findings", label, errors);
1983
-
1984
- if (typeof result.verdict === "string" && !verdicts.has(result.verdict)) {
1985
- errors.push(`${label}.verdict has unsupported value ${result.verdict}`);
1986
- }
1987
-
1988
- const completedSteps = new Set(Array.isArray(result.completed_steps) ? result.completed_steps : []);
1989
- if (Array.isArray(result.required_steps)) {
1990
- for (const requiredStep of result.required_steps) {
1991
- if (!completedSteps.has(requiredStep)) {
1992
- errors.push(`${label}.completed_steps is missing required step ${requiredStep}`);
1993
- }
1994
- }
1995
- }
1996
- if (Array.isArray(result.missing_steps) && result.missing_steps.length > 0) {
1997
- errors.push(`${label}.missing_steps must be empty for a passing feedback report`);
1998
- }
1999
-
2000
- const feedbackClassifications = new Set(Array.isArray(result.feedback_classification) ? result.feedback_classification : []);
2001
- if (Array.isArray(result.feedback_classification)) {
2002
- for (const classification of result.feedback_classification) {
2003
- if (!classifications.has(classification)) {
2004
- errors.push(`${label}.feedback_classification has unsupported value ${classification}`);
2005
- }
2006
- }
2007
- }
2008
-
2009
- const blockingFindingRefs = new Set(Array.isArray(result.blocking_findings) ? result.blocking_findings : []);
2010
- let hasBlockingFinding = false;
2011
- let hasProcessImprovement = false;
2012
- let hasSpecGap = false;
2013
-
2014
- if (Array.isArray(result.findings)) {
2015
- for (const [index, finding] of result.findings.entries()) {
2016
- const findingLabel = `${label}.findings[${index}]`;
2017
- for (const field of ["id", "dimension", "classification", "severity", "summary", "next_route"]) {
2018
- requireString(finding, field, findingLabel, errors);
2019
- }
2020
- requireArray(finding, "evidence_refs", findingLabel, errors);
2021
- if (typeof finding.blocking !== "boolean") {
2022
- errors.push(`${findingLabel}.blocking must be a boolean`);
2023
- }
2024
-
2025
- if (typeof finding.classification === "string") {
2026
- if (!classifications.has(finding.classification)) {
2027
- errors.push(`${findingLabel}.classification has unsupported value ${finding.classification}`);
2028
- }
2029
- if (!feedbackClassifications.has(finding.classification)) {
2030
- errors.push(`${label}.feedback_classification must include finding classification ${finding.classification}`);
2031
- }
2032
- if (finding.classification === "process_improvement") {
2033
- hasProcessImprovement = true;
2034
- if (typeof finding.next_route !== "string" || !finding.next_route.toLowerCase().includes("kaizen")) {
2035
- errors.push(`${findingLabel}.next_route must route process_improvement to Kaizen`);
2036
- }
2037
- }
2038
- if (finding.classification === "spec_gap") {
2039
- hasSpecGap = true;
2040
- const route = typeof finding.next_route === "string" ? finding.next_route.toLowerCase() : "";
2041
- if (!route.includes("planning") && !route.includes("human_projection") && !route.includes("graph_sync")) {
2042
- errors.push(`${findingLabel}.next_route must route spec_gap to planning, human_projection or graph_sync`);
2043
- }
2044
- }
2045
- if (["release_blocker", "security_blocker"].includes(finding.classification) && finding.blocking !== true) {
2046
- errors.push(`${findingLabel}.blocking must be true for ${finding.classification}`);
2047
- }
2048
- }
2049
-
2050
- if (finding.blocking === true) {
2051
- hasBlockingFinding = true;
2052
- if (typeof finding.id === "string" && !blockingFindingRefs.has(finding.id)) {
2053
- errors.push(`${label}.blocking_findings must include blocking finding ${finding.id}`);
2054
- }
2055
- }
2056
-
2057
- if (typeof finding.severity === "string" && !severities.has(finding.severity)) {
2058
- errors.push(`${findingLabel}.severity has unsupported value ${finding.severity}`);
2059
- }
2060
- }
2061
- }
2062
-
2063
- if (hasProcessImprovement && (!Array.isArray(result.kaizen_refs) || result.kaizen_refs.length === 0)) {
2064
- errors.push(`${label}.kaizen_refs must not be empty when process_improvement is present`);
2065
- }
2066
-
2067
- if (hasSpecGap && typeof result.next_transition === "string") {
2068
- const transition = result.next_transition.toLowerCase();
2069
- if (!transition.includes("planning") && !transition.includes("human_projection") && !transition.includes("graph_sync")) {
2070
- errors.push(`${label}.next_transition must route spec_gap to planning, human_projection or graph_sync`);
2071
- }
2072
- }
2073
-
2074
- if (acceptedVerdicts.has(result.verdict) && (hasBlockingFinding || blockingFindingRefs.size > 0)) {
2075
- errors.push(`${label}.verdict cannot be accepted while blocking findings are present`);
2076
- }
2077
-
2078
- const feedbackText = JSON.stringify(result).toLowerCase();
2079
- const forbiddenBoundaryTerms = [
2080
- "evidence is approval",
2081
- "tests are acceptance",
2082
- "feedback directly updates",
2083
- "automatic canonical update",
2084
- "automatically updates canonical",
2085
- "proposal is controlled update",
2086
- "canonical_update"
2087
- ];
2088
- for (const forbiddenTerm of forbiddenBoundaryTerms) {
2089
- if (feedbackText.includes(forbiddenTerm)) {
2090
- errors.push(`${label} contains forbidden authorization boundary term: ${forbiddenTerm}`);
2091
- }
2092
- }
2093
-
2094
- const limitationText = Array.isArray(result.limitations) ? result.limitations.join("\n").toLowerCase() : "";
2095
- for (const expectedBoundary of ["tests", "evidence", "canonical", "acceptance"]) {
2096
- if (!limitationText.includes(expectedBoundary)) {
2097
- warnings.push(`${label}.limitations should mention ${expectedBoundary}`);
2098
- }
2099
- }
2100
- }
2101
-
2102
- if (mode === "development-cockpit") {
2103
- for (const field of ["subject_ref", "generated_at"]) {
2104
- requireString(result, field, label, errors);
2105
- }
2106
- requireJsonArray(result, "instruments", label, errors);
2107
- requireObject(result, "readiness", label, errors);
2108
- requireObject(result, "next_best_action", label, errors);
2109
- requireArray(result, "blocking_rules", label, errors);
2110
-
2111
- if (result.readiness && typeof result.readiness === "object") {
2112
- for (const field of [
2113
- "developer_test_readiness",
2114
- "product_readiness",
2115
- "production_readiness",
2116
- "external_user_testing_readiness"
2117
- ]) {
2118
- if (result.readiness[field] === undefined) {
2119
- errors.push(`${label}.readiness.${field} is required`);
2120
- }
2121
- }
2122
- }
2123
-
2124
- if (Array.isArray(result.instruments)) {
2125
- for (const [index, instrument] of result.instruments.entries()) {
2126
- const instrumentLabel = `${label}.instruments[${index}]`;
2127
- for (const field of ["id", "family", "band", "status", "reason"]) {
2128
- requireString(instrument, field, instrumentLabel, errors);
2129
- }
2130
- requireArray(instrument, "evidence_refs", instrumentLabel, errors);
2131
- if (typeof instrument.score !== "number" || instrument.score < 0 || instrument.score > 100) {
2132
- errors.push(`${instrumentLabel}.score must be a number between 0 and 100`);
2133
- }
2134
- if (Array.isArray(instrument.evidence_refs) && instrument.evidence_refs.length === 0) {
2135
- errors.push(`${instrumentLabel}.evidence_refs must not be empty`);
2136
- }
2137
- }
2138
- }
2139
-
2140
- if (result.next_best_action && typeof result.next_best_action === "object") {
2141
- requireString(result.next_best_action, "action", `${label}.next_best_action`, errors);
2142
- requireString(result.next_best_action, "target_cycle", `${label}.next_best_action`, errors);
2143
- requireArray(result.next_best_action, "required_gates", `${label}.next_best_action`, errors);
2144
- requireArray(result.next_best_action, "evidence_refs", `${label}.next_best_action`, errors);
2145
- if (
2146
- Array.isArray(result.next_best_action.required_gates) &&
2147
- result.next_best_action.required_gates.length === 0
2148
- ) {
2149
- errors.push(`${label}.next_best_action.required_gates must not be empty`);
2150
- }
2151
- }
2152
-
2153
- const limitationText = Array.isArray(result.limitations) ? result.limitations.join("\n").toLowerCase() : "";
2154
- for (const expectedBoundary of ["acceptance", "evidence", "canonical", "release"]) {
2155
- if (!limitationText.includes(expectedBoundary)) {
2156
- warnings.push(`${label}.limitations should mention ${expectedBoundary}`);
2157
- }
2158
- }
2159
- }
2160
-
2161
- if (mode === "feature-implementation-traceability") {
2162
- requireString(result, "subject_ref", label, errors);
2163
- requireJsonArray(result, "features", label, errors);
2164
- requireJsonArray(result, "implementation_mappings", label, errors);
2165
- requireJsonArray(result, "dependency_mappings", label, errors);
2166
- requireObject(result, "coverage_summary", label, errors);
2167
-
2168
- const featureIds = new Set();
2169
- if (Array.isArray(result.features)) {
2170
- for (const [index, feature] of result.features.entries()) {
2171
- const featureLabel = `${label}.features[${index}]`;
2172
- for (const field of ["id", "title", "status", "owner_ref"]) {
2173
- requireString(feature, field, featureLabel, errors);
2174
- }
2175
- requireArray(feature, "evidence_refs", featureLabel, errors);
2176
- if (typeof feature.id === "string") {
2177
- featureIds.add(feature.id);
2178
- }
2179
- }
2180
- }
2181
-
2182
- if (Array.isArray(result.implementation_mappings)) {
2183
- for (const [index, mapping] of result.implementation_mappings.entries()) {
2184
- const mappingLabel = `${label}.implementation_mappings[${index}]`;
2185
- requireString(mapping, "feature_ref", mappingLabel, errors);
2186
- for (const field of [
2187
- "implementation_refs",
2188
- "test_refs",
2189
- "review_refs",
2190
- "documentation_refs",
2191
- "evidence_refs",
2192
- "known_gaps"
2193
- ]) {
2194
- requireArray(mapping, field, mappingLabel, errors);
2195
- }
2196
- requireString(mapping, "status", mappingLabel, errors);
2197
- if (typeof mapping.confidence !== "number" || mapping.confidence < 0 || mapping.confidence > 1) {
2198
- errors.push(`${mappingLabel}.confidence must be a number between 0 and 1`);
2199
- }
2200
- if (typeof mapping.feature_ref === "string" && !featureIds.has(mapping.feature_ref)) {
2201
- errors.push(`${mappingLabel}.feature_ref references missing feature ${mapping.feature_ref}`);
2202
- }
2203
- if (
2204
- typeof mapping.status === "string" &&
2205
- ["implemented", "tested", "review_ready", "accepted", "released"].includes(mapping.status) &&
2206
- (!Array.isArray(mapping.evidence_refs) || mapping.evidence_refs.length === 0)
2207
- ) {
2208
- errors.push(`${mappingLabel}.evidence_refs must not be empty for status ${mapping.status}`);
2209
- }
2210
- if (
2211
- typeof mapping.status === "string" &&
2212
- ["accepted", "released"].includes(mapping.status) &&
2213
- (!Array.isArray(mapping.review_refs) || mapping.review_refs.length === 0)
2214
- ) {
2215
- errors.push(`${mappingLabel}.review_refs must not be empty for status ${mapping.status}`);
2216
- }
2217
- }
2218
- }
2219
-
2220
- const limitationText = Array.isArray(result.limitations) ? result.limitations.join("\n").toLowerCase() : "";
2221
- for (const expectedBoundary of ["mapped", "implementation", "acceptance", "release"]) {
2222
- if (!limitationText.includes(expectedBoundary)) {
2223
- warnings.push(`${label}.limitations should mention ${expectedBoundary}`);
2224
- }
2225
- }
2226
- }
2227
-
2228
- if (mode === "multi-source-quality-feedback") {
2229
- const classifications = new Set([
2230
- "accepted",
2231
- "work_fix_required",
2232
- "test_gap",
2233
- "spec_gap",
2234
- "graph_update_proposal",
2235
- "process_improvement",
2236
- "release_blocker",
2237
- "security_blocker",
2238
- "defer_with_reason"
2239
- ]);
2240
- const verdicts = new Set([
2241
- "accepted_for_transition",
2242
- "changes_requested",
2243
- "blocked",
2244
- "defer_with_reason",
2245
- "proposal_required"
2246
- ]);
2247
- const severities = new Set(["critical", "high", "medium", "low"]);
2248
-
2249
- requireString(result, "process_id", label, errors);
2250
- requireJsonArray(result, "sources", label, errors);
2251
- requireJsonArray(result, "findings", label, errors);
2252
- for (const field of ["feedback_classification", "blocking_findings", "kaizen_refs"]) {
2253
- requireArray(result, field, label, errors);
2254
- }
2255
- requireString(result, "verdict", label, errors);
2256
- requireString(result, "next_transition", label, errors);
2257
-
2258
- if (typeof result.verdict === "string" && !verdicts.has(result.verdict)) {
2259
- errors.push(`${label}.verdict has unsupported value ${result.verdict}`);
2260
- }
2261
-
2262
- if (Array.isArray(result.sources)) {
2263
- for (const [index, source] of result.sources.entries()) {
2264
- const sourceLabel = `${label}.sources[${index}]`;
2265
- for (const field of ["id", "kind", "verdict"]) {
2266
- requireString(source, field, sourceLabel, errors);
2267
- }
2268
- requireArray(source, "evidence_refs", sourceLabel, errors);
2269
- requireArray(source, "limitations", sourceLabel, errors);
2270
- if (Array.isArray(source.evidence_refs) && source.evidence_refs.length === 0) {
2271
- errors.push(`${sourceLabel}.evidence_refs must not be empty`);
2272
- }
2273
- }
2274
- }
2275
-
2276
- const feedbackClassifications = new Set(Array.isArray(result.feedback_classification) ? result.feedback_classification : []);
2277
- const blockingFindingRefs = new Set(Array.isArray(result.blocking_findings) ? result.blocking_findings : []);
2278
- let hasBlockingFinding = false;
2279
- let hasProcessImprovement = false;
2280
- let hasSpecGap = false;
2281
-
2282
- if (Array.isArray(result.findings)) {
2283
- for (const [index, finding] of result.findings.entries()) {
2284
- const findingLabel = `${label}.findings[${index}]`;
2285
- for (const field of ["id", "source_ref", "classification", "severity", "summary", "next_route"]) {
2286
- requireString(finding, field, findingLabel, errors);
2287
- }
2288
- requireArray(finding, "evidence_refs", findingLabel, errors);
2289
- if (typeof finding.blocking !== "boolean") {
2290
- errors.push(`${findingLabel}.blocking must be a boolean`);
2291
- }
2292
- if (typeof finding.classification === "string") {
2293
- if (!classifications.has(finding.classification)) {
2294
- errors.push(`${findingLabel}.classification has unsupported value ${finding.classification}`);
2295
- }
2296
- if (!feedbackClassifications.has(finding.classification)) {
2297
- errors.push(`${label}.feedback_classification must include finding classification ${finding.classification}`);
2298
- }
2299
- if (finding.classification === "process_improvement") {
2300
- hasProcessImprovement = true;
2301
- if (typeof finding.next_route !== "string" || !finding.next_route.toLowerCase().includes("kaizen")) {
2302
- errors.push(`${findingLabel}.next_route must route process_improvement to Kaizen`);
2303
- }
2304
- }
2305
- if (finding.classification === "spec_gap") {
2306
- hasSpecGap = true;
2307
- const route = typeof finding.next_route === "string" ? finding.next_route.toLowerCase() : "";
2308
- if (!route.includes("planning") && !route.includes("graph_sync")) {
2309
- errors.push(`${findingLabel}.next_route must route spec_gap to planning or graph_sync`);
2310
- }
2311
- }
2312
- if (["release_blocker", "security_blocker"].includes(finding.classification) && finding.blocking !== true) {
2313
- errors.push(`${findingLabel}.blocking must be true for ${finding.classification}`);
2314
- }
2315
- }
2316
- if (finding.blocking === true) {
2317
- hasBlockingFinding = true;
2318
- if (typeof finding.id === "string" && !blockingFindingRefs.has(finding.id)) {
2319
- errors.push(`${label}.blocking_findings must include blocking finding ${finding.id}`);
2320
- }
2321
- }
2322
- if (typeof finding.severity === "string" && !severities.has(finding.severity)) {
2323
- errors.push(`${findingLabel}.severity has unsupported value ${finding.severity}`);
2324
- }
2325
- }
2326
- }
2327
-
2328
- if (hasProcessImprovement && (!Array.isArray(result.kaizen_refs) || result.kaizen_refs.length === 0)) {
2329
- errors.push(`${label}.kaizen_refs must not be empty when process_improvement is present`);
2330
- }
2331
- if (hasSpecGap && typeof result.next_transition === "string") {
2332
- const transition = result.next_transition.toLowerCase();
2333
- if (!transition.includes("planning") && !transition.includes("graph_sync")) {
2334
- errors.push(`${label}.next_transition must route spec_gap to planning or graph_sync`);
2335
- }
2336
- }
2337
- if (hasBlockingFinding && result.verdict === "accepted_for_transition") {
2338
- errors.push(`${label}.verdict cannot be accepted_for_transition while blocking findings are present`);
2339
- }
2340
-
2341
- const feedbackText = JSON.stringify(result).toLowerCase();
2342
- for (const forbiddenTerm of [
2343
- "tests are acceptance",
2344
- "evidence is approval",
2345
- "automatic canonical update",
2346
- "feedback directly updates",
2347
- "proposal is controlled update"
2348
- ]) {
2349
- if (feedbackText.includes(forbiddenTerm)) {
2350
- errors.push(`${label} contains forbidden authorization boundary term: ${forbiddenTerm}`);
2351
- }
2352
- }
2353
- }
2354
-
2355
- if (mode === "recovery-resume-record") {
2356
- for (const field of [
2357
- "current_state",
2358
- "last_good_checkpoint",
2359
- "target_scope",
2360
- "last_validation_result",
2361
- "evidence_status",
2362
- "next_safe_command",
2363
- "rollback_option"
2364
- ]) {
2365
- requireString(result, field, label, errors);
2366
- }
2367
- requireArray(result, "blockers", label, errors);
2368
- if (typeof result.human_confirmation_required !== "boolean") {
2369
- errors.push(`${label}.human_confirmation_required must be a boolean`);
2370
- }
2371
- }
2372
-
2373
- if (mode === "risk-control-matrix") {
2374
- requireJsonArray(result, "risks", label, errors);
2375
- const severities = new Set(["critical", "high", "medium", "low"]);
2376
- if (Array.isArray(result.risks)) {
2377
- for (const [index, risk] of result.risks.entries()) {
2378
- const riskLabel = `${label}.risks[${index}]`;
2379
- for (const field of [
2380
- "id",
2381
- "severity",
2382
- "description",
2383
- "detection_signal",
2384
- "prevention",
2385
- "gate_or_validator",
2386
- "evidence_requirement",
2387
- "recovery_action",
2388
- "escalation_rule",
2389
- "owner_role"
2390
- ]) {
2391
- requireString(risk, field, riskLabel, errors);
2392
- }
2393
- if (typeof risk.severity === "string" && !severities.has(risk.severity)) {
2394
- errors.push(`${riskLabel}.severity has unsupported value ${risk.severity}`);
2395
- }
2396
- }
2397
- }
2398
- }
2399
-
2400
- if (mode === "multi-agent-coordination") {
2401
- requireArray(result, "roles", label, errors);
2402
- requireJsonArray(result, "reservations", label, errors);
2403
- requireArray(result, "locking_rules", label, errors);
2404
- requireString(result, "conflict_resolution", label, errors);
2405
- if (Array.isArray(result.reservations)) {
2406
- for (const [index, reservation] of result.reservations.entries()) {
2407
- const reservationLabel = `${label}.reservations[${index}]`;
2408
- for (const field of ["id", "owner_role", "scope", "evidence_path", "proposal_path"]) {
2409
- requireString(reservation, field, reservationLabel, errors);
2410
- }
2411
- requireArray(reservation, "allowed_actions", reservationLabel, errors);
2412
- }
2413
- }
2414
- }
2415
-
2416
- if (mode === "source-boundary-contract") {
2417
- requireJsonArray(result, "source_roles", label, errors);
2418
- requireString(result, "promotion_rule", label, errors);
2419
- requireArray(result, "rejected_promotion_targets", label, errors);
2420
- const roles = new Set();
2421
- if (Array.isArray(result.source_roles)) {
2422
- for (const [index, role] of result.source_roles.entries()) {
2423
- const roleLabel = `${label}.source_roles[${index}]`;
2424
- requireString(role, "role", roleLabel, errors);
2425
- requireString(role, "description", roleLabel, errors);
2426
- if (typeof role.canonical_write_allowed !== "boolean") {
2427
- errors.push(`${roleLabel}.canonical_write_allowed must be a boolean`);
2428
- }
2429
- if (typeof role.role === "string") {
2430
- roles.add(role.role);
2431
- }
2432
- }
2433
- }
2434
- for (const requiredRole of ["canonical", "generated", "curated_human", "workflow", "local_scratch"]) {
2435
- if (!roles.has(requiredRole)) {
2436
- errors.push(`${label}.source_roles must include ${requiredRole}`);
2437
- }
2438
- }
2439
- if (typeof result.promotion_rule === "string" && !result.promotion_rule.toLowerCase().includes("proposal")) {
2440
- errors.push(`${label}.promotion_rule must require proposal-based promotion`);
2441
- }
2442
- }
2443
-
2444
- return { errors, warnings, result };
2445
- }
2446
-
2447
- function validateDynamicEpisodeTrace(resultPath) {
2448
- const errors = [];
2449
- const warnings = [];
2450
- const result = readJson(resultPath);
2451
- const label = "dynamic_episode_trace";
2452
- const classifications = new Set([
2453
- "accepted",
2454
- "work_fix_required",
2455
- "test_gap",
2456
- "spec_gap",
2457
- "graph_update_proposal",
2458
- "process_improvement",
2459
- "release_blocker",
2460
- "security_blocker",
2461
- "defer_with_reason",
2462
- "scope_drift",
2463
- "package_boundary_violation",
2464
- "wrong_dependency_activation",
2465
- "unsupported_assumption",
2466
- "missing_evidence",
2467
- "wrong_workflow_selected",
2468
- "approval_gate_bypass",
2469
- "technology_step_skipped",
2470
- "evidence_treated_as_authorization",
2471
- "feedback_loss"
2472
- ]);
2473
- const severities = new Set(["critical", "high", "medium", "low"]);
2474
-
2475
- requireString(result, "schema_version", label, errors);
2476
- requireString(result, "id", label, errors);
2477
- requireString(result, "profile", label, errors);
2478
- requireString(result, "public_safety", label, errors);
2479
- requireObject(result, "event", label, errors);
2480
- requireObject(result, "source_refs", label, errors);
2481
- requireObject(result, "activated", label, errors);
2482
- requireJsonArray(result, "selected_path", label, errors);
2483
- requireJsonArray(result, "blocked_paths", label, errors);
2484
- requireJsonArray(result, "gates", label, errors);
2485
- requireJsonArray(result, "actions", label, errors);
2486
- requireJsonArray(result, "results", label, errors);
2487
- requireJsonArray(result, "findings", label, errors);
2488
- requireArray(result, "feedback_classification", label, errors);
2489
- requireArray(result, "kaizen_candidates", label, errors);
2490
- requireObject(result, "replay_regression", label, errors);
2491
- requireArray(result, "evidence_refs", label, errors);
2492
- requireArray(result, "limitations", label, errors);
2493
-
2494
- if (result.profile !== undefined && result.profile !== "dynamic_episode_layer") {
2495
- errors.push(`${label}.profile must be dynamic_episode_layer`);
2496
- }
2497
- if (result.public_safety !== undefined && result.public_safety !== "synthetic_public") {
2498
- errors.push(`${label}.public_safety must be synthetic_public`);
2499
- }
2500
- if (result.canonical_write_allowed !== false) {
2501
- errors.push(`${label}.canonical_write_allowed must be false`);
2502
- }
2503
-
2504
- if (result.event && typeof result.event === "object") {
2505
- for (const field of ["id", "type", "summary"]) {
2506
- requireString(result.event, field, `${label}.event`, errors);
2507
- }
2508
- }
2509
-
2510
- if (result.source_refs && typeof result.source_refs === "object") {
2511
- requireOptionalArray(result.source_refs, "spec_refs", `${label}.source_refs`, errors);
2512
- requireArray(result.source_refs, "graph_refs", `${label}.source_refs`, errors);
2513
- requireArray(result.source_refs, "workflow_refs", `${label}.source_refs`, errors);
2514
- requireString(result.source_refs, "launch_record_ref", `${label}.source_refs`, errors);
2515
- }
2516
-
2517
- if (result.activated && typeof result.activated === "object") {
2518
- for (const field of ["objects", "relations", "policies", "gates", "technology_steps"]) {
2519
- requireArray(result.activated, field, `${label}.activated`, errors);
2520
- }
2521
- }
2522
-
2523
- if (Array.isArray(result.selected_path) && result.selected_path.length === 0) {
2524
- errors.push(`${label}.selected_path must contain at least one step`);
2525
- }
2526
-
2527
- if (Array.isArray(result.blocked_paths)) {
2528
- for (const [index, blockedPath] of result.blocked_paths.entries()) {
2529
- const blockedLabel = `${label}.blocked_paths[${index}]`;
2530
- for (const field of ["id", "reason", "blocked_by"]) {
2531
- requireString(blockedPath, field, blockedLabel, errors);
2532
- }
2533
- }
2534
- }
2535
-
2536
- if (Array.isArray(result.gates)) {
2537
- for (const [index, gate] of result.gates.entries()) {
2538
- const gateLabel = `${label}.gates[${index}]`;
2539
- for (const field of ["id", "status"]) {
2540
- requireString(gate, field, gateLabel, errors);
2541
- }
2542
- }
2543
- }
2544
-
2545
- const feedbackClassifications = new Set(Array.isArray(result.feedback_classification) ? result.feedback_classification : []);
2546
- if (Array.isArray(result.feedback_classification)) {
2547
- for (const classification of result.feedback_classification) {
2548
- if (!classifications.has(classification)) {
2549
- errors.push(`${label}.feedback_classification has unsupported value ${classification}`);
2550
- }
2551
- }
2552
- }
2553
-
2554
- let hasProcessImprovement = false;
2555
- if (Array.isArray(result.findings)) {
2556
- for (const [index, finding] of result.findings.entries()) {
2557
- const findingLabel = `${label}.findings[${index}]`;
2558
- for (const field of ["id", "classification", "severity", "summary", "next_route"]) {
2559
- requireString(finding, field, findingLabel, errors);
2560
- }
2561
- requireArray(finding, "evidence_refs", findingLabel, errors);
2562
- if (typeof finding.blocking !== "boolean") {
2563
- errors.push(`${findingLabel}.blocking must be a boolean`);
2564
- }
2565
- if (typeof finding.classification === "string") {
2566
- if (!classifications.has(finding.classification)) {
2567
- errors.push(`${findingLabel}.classification has unsupported value ${finding.classification}`);
2568
- }
2569
- if (!feedbackClassifications.has(finding.classification)) {
2570
- errors.push(`${label}.feedback_classification must include finding classification ${finding.classification}`);
2571
- }
2572
- if (finding.classification === "process_improvement") {
2573
- hasProcessImprovement = true;
2574
- if (typeof finding.next_route !== "string" || !finding.next_route.toLowerCase().includes("kaizen")) {
2575
- errors.push(`${findingLabel}.next_route must route process_improvement to Kaizen`);
2576
- }
2577
- }
2578
- if (["release_blocker", "security_blocker", "approval_gate_bypass"].includes(finding.classification) && finding.blocking !== true) {
2579
- errors.push(`${findingLabel}.blocking must be true for ${finding.classification}`);
2580
- }
2581
- }
2582
- if (typeof finding.severity === "string" && !severities.has(finding.severity)) {
2583
- errors.push(`${findingLabel}.severity has unsupported value ${finding.severity}`);
2584
- }
2585
- }
2586
- }
2587
-
2588
- if (hasProcessImprovement && (!Array.isArray(result.kaizen_candidates) || result.kaizen_candidates.length === 0)) {
2589
- errors.push(`${label}.kaizen_candidates must not be empty when process_improvement is present`);
2590
- }
2591
-
2592
- if (result.replay_regression && typeof result.replay_regression === "object") {
2593
- if (typeof result.replay_regression.replay_ready !== "boolean") {
2594
- errors.push(`${label}.replay_regression.replay_ready must be a boolean`);
2595
- }
2596
- if (result.replay_regression.baseline_ref !== null && typeof result.replay_regression.baseline_ref !== "string") {
2597
- errors.push(`${label}.replay_regression.baseline_ref must be a string or null`);
2598
- }
2599
- if (result.replay_regression.regression_check_ref !== null && typeof result.replay_regression.regression_check_ref !== "string") {
2600
- errors.push(`${label}.replay_regression.regression_check_ref must be a string or null`);
2601
- }
2602
- }
2603
-
2604
- const traceText = JSON.stringify(result).toLowerCase();
2605
- const forbiddenBoundaryTerms = [
2606
- "evidence is approval",
2607
- "tests are acceptance",
2608
- "feedback directly updates",
2609
- "automatic canonical update",
2610
- "automatically updates canonical",
2611
- "runtime trace updates canonical",
2612
- "episode trace authorizes",
2613
- "trace authorizes"
2614
- ];
2615
- for (const forbiddenTerm of forbiddenBoundaryTerms) {
2616
- if (traceText.includes(forbiddenTerm)) {
2617
- errors.push(`${label} contains forbidden authorization boundary term: ${forbiddenTerm}`);
2618
- }
2619
- }
2620
-
2621
- const limitationText = Array.isArray(result.limitations) ? result.limitations.join("\n").toLowerCase() : "";
2622
- for (const expectedBoundary of ["synthetic", "evidence", "canonical"]) {
2623
- if (!limitationText.includes(expectedBoundary)) {
2624
- warnings.push(`${label}.limitations should mention ${expectedBoundary}`);
2625
- }
2626
- }
2627
-
2628
- return { errors, warnings, result };
2629
- }
2630
-
2631
- function validateProcessTransition(stateMachinePath, transitionRequestPath) {
2632
- const errors = [];
2633
- const warnings = [];
2634
- const stateMachine = readJson(stateMachinePath);
2635
- const request = readJson(transitionRequestPath);
2636
- const label = "process_transition";
2637
-
2638
- requireString(stateMachine, "schema_version", "state_machine", errors);
2639
- requireString(stateMachine, "id", "state_machine", errors);
2640
- requireString(stateMachine, "profile", "state_machine", errors);
2641
- requireString(stateMachine, "public_safety", "state_machine", errors);
2642
- requireArray(stateMachine, "states", "state_machine", errors);
2643
- requireJsonArray(stateMachine, "transitions", "state_machine", errors);
2644
- requireArray(stateMachine, "false_transition_guards", "state_machine", errors);
2645
-
2646
- requireString(request, "schema_version", label, errors);
2647
- requireString(request, "id", label, errors);
2648
- requireString(request, "profile", label, errors);
2649
- requireString(request, "public_safety", label, errors);
2650
- requireString(request, "process_id", label, errors);
2651
- requireString(request, "current_state", label, errors);
2652
- requireString(request, "target_state", label, errors);
2653
- requireArray(request, "evidence_refs", label, errors);
2654
- for (const optionalStringField of ["launch_record_ref", "kaizen_review_ref", "no_reusable_lessons_reason"]) {
2655
- if (typeof request[optionalStringField] !== "string") {
2656
- errors.push(`${label}.${optionalStringField} must be a string`);
2657
- }
2658
- }
2659
- requireArray(request, "limitations", label, errors);
2660
-
2661
- if (stateMachine.profile !== undefined && stateMachine.profile !== "implementation_control") {
2662
- errors.push("state_machine.profile must be implementation_control");
2663
- }
2664
- if (stateMachine.public_safety !== undefined && stateMachine.public_safety !== "synthetic_public") {
2665
- errors.push("state_machine.public_safety must be synthetic_public");
2666
- }
2667
- if (request.profile !== undefined && request.profile !== "implementation_control") {
2668
- errors.push(`${label}.profile must be implementation_control`);
2669
- }
2670
- if (request.public_safety !== undefined && request.public_safety !== "synthetic_public") {
2671
- errors.push(`${label}.public_safety must be synthetic_public`);
2672
- }
2673
-
2674
- const states = new Set(Array.isArray(stateMachine.states) ? stateMachine.states : []);
2675
- if (request.current_state && !states.has(request.current_state)) {
2676
- errors.push(`${label}.current_state references unknown state ${request.current_state}`);
2677
- }
2678
- if (request.target_state && !states.has(request.target_state)) {
2679
- errors.push(`${label}.target_state references unknown state ${request.target_state}`);
2680
- }
2681
-
2682
- const transitions = Array.isArray(stateMachine.transitions) ? stateMachine.transitions : [];
2683
- const transition = transitions.find((item) => (
2684
- item.from === request.current_state && item.to === request.target_state
2685
- ));
2686
- const requiredEvidence = transition && Array.isArray(transition.requires_evidence)
2687
- ? transition.requires_evidence
2688
- : [];
2689
- const providedEvidence = Array.isArray(request.evidence_refs) ? request.evidence_refs : [];
2690
- const missingEvidence = requiredEvidence.filter((requiredEvidenceRef) => (
2691
- !providedEvidence.includes(requiredEvidenceRef)
2692
- ));
2693
- const terminalStates = new Set(Array.isArray(stateMachine.terminal_states) ? stateMachine.terminal_states : []);
2694
- const terminalRequiresKaizen = transition && transition.terminal_requires_kaizen === true;
2695
- const terminalTransition = terminalStates.has(request.target_state) || terminalRequiresKaizen === true;
2696
- const launchRecordSatisfied = !(transition && transition.requires_launch_record === true) || Boolean(request.launch_record_ref);
2697
- const kaizenSatisfied = !terminalTransition || Boolean(request.kaizen_review_ref) || Boolean(request.no_reusable_lessons_reason);
2698
- const explanation = {
2699
- process_id: typeof request.process_id === "string" ? request.process_id : "",
2700
- current_state: typeof request.current_state === "string" ? request.current_state : "",
2701
- target_state: typeof request.target_state === "string" ? request.target_state : "",
2702
- matched_transition: Boolean(transition),
2703
- matched_transition_ref: transition ? `${transition.from}->${transition.to}` : "",
2704
- required_evidence: requiredEvidence,
2705
- provided_evidence: providedEvidence,
2706
- missing_evidence: missingEvidence,
2707
- requires_launch_record: Boolean(transition && transition.requires_launch_record === true),
2708
- launch_record_ref: typeof request.launch_record_ref === "string" ? request.launch_record_ref : "",
2709
- launch_record_satisfied: launchRecordSatisfied,
2710
- terminal_transition: terminalTransition,
2711
- terminal_requires_kaizen: Boolean(terminalRequiresKaizen),
2712
- kaizen_decision: {
2713
- status: kaizenSatisfied ? (terminalTransition ? "satisfied" : "not_required") : "missing",
2714
- kaizen_review_ref: typeof request.kaizen_review_ref === "string" ? request.kaizen_review_ref : "",
2715
- no_reusable_lessons_reason: typeof request.no_reusable_lessons_reason === "string" ? request.no_reusable_lessons_reason : ""
2716
- },
2717
- false_transition_guard_summary: Array.isArray(stateMachine.false_transition_guards)
2718
- ? stateMachine.false_transition_guards
2719
- : []
2720
- };
2721
- if (!transition) {
2722
- errors.push(`${label} transition ${request.current_state}->${request.target_state} is not allowed`);
2723
- }
2724
-
2725
- const evidence = new Set(Array.isArray(request.evidence_refs) ? request.evidence_refs : []);
2726
- if (transition) {
2727
- for (const requiredEvidenceRef of requiredEvidence) {
2728
- if (!evidence.has(requiredEvidenceRef)) {
2729
- errors.push(`${label} missing required evidence ${requiredEvidenceRef}`);
2730
- }
2731
- }
2732
- }
2733
-
2734
- if (transition && transition.requires_launch_record === true && !request.launch_record_ref) {
2735
- errors.push(`${label} requires launch_record_ref for ${request.current_state}->${request.target_state}`);
2736
- }
2737
-
2738
- if ((terminalStates.has(request.target_state) || terminalRequiresKaizen) && !request.kaizen_review_ref && !request.no_reusable_lessons_reason) {
2739
- errors.push(`${label} terminal transition requires kaizen_review_ref or no_reusable_lessons_reason`);
2740
- }
2741
-
2742
- const guardText = Array.isArray(stateMachine.false_transition_guards) ? stateMachine.false_transition_guards.join("\n").toLowerCase() : "";
2743
- for (const requiredGuard of ["ready", "tests", "sync", "released", "terminal"]) {
2744
- if (!guardText.includes(requiredGuard)) {
2745
- warnings.push(`state_machine.false_transition_guards should mention ${requiredGuard}`);
2746
- }
2747
- }
2748
-
2749
- return { errors, warnings, explanation };
2750
- }
2751
-
2752
- function validateSemanticIntentResolution(resultPath) {
2753
- const errors = [];
2754
- const warnings = [];
2755
- const result = readJson(resultPath);
2756
- const label = "semantic_intent_resolution";
2757
-
2758
- for (const field of [
2759
- "schema_version",
2760
- "id",
2761
- "user_request",
2762
- "intent_hypothesis",
2763
- "confidence",
2764
- "work_scale",
2765
- "selected_chain_id",
2766
- "process_model_id",
2767
- "owner_role",
2768
- "safe_default_action"
2769
- ]) {
2770
- requireString(result, field, label, errors);
2771
- }
2772
- for (const field of [
2773
- "required_context_slots",
2774
- "missing_context_slots",
2775
- "evidence_requirements",
2776
- "limitations"
2777
- ]) {
2778
- requireArray(result, field, label, errors);
2779
- }
2780
-
2781
- if (typeof result.execution_allowed !== "boolean") {
2782
- errors.push(`${label}.execution_allowed must be a boolean`);
2783
- }
2784
- if (typeof result.canonical_write_allowed !== "boolean") {
2785
- errors.push(`${label}.canonical_write_allowed must be a boolean`);
2786
- }
2787
- if (result.canonical_write_allowed !== false) {
2788
- errors.push(`${label}.canonical_write_allowed must be false`);
2789
- }
2790
-
2791
- const confidenceValues = new Set(["low", "medium", "high"]);
2792
- if (typeof result.confidence === "string" && !confidenceValues.has(result.confidence)) {
2793
- errors.push(`${label}.confidence has unsupported value ${result.confidence}`);
2794
- }
2795
-
2796
- const workScales = new Set(["checkpoint", "batch", "milestone", "goal", "track", "program", "vision", "unspecified"]);
2797
- if (typeof result.work_scale === "string" && !workScales.has(result.work_scale)) {
2798
- errors.push(`${label}.work_scale has unsupported value ${result.work_scale}`);
2799
- }
2800
-
2801
- if (result.confidence === "low" && result.execution_allowed === true) {
2802
- errors.push(`${label} low confidence must not allow execution`);
2803
- }
2804
- if (result.confidence === "low" && result.review_surface_required !== true) {
2805
- errors.push(`${label} low confidence requires review_surface_required=true`);
2806
- }
2807
-
2808
- const missingContext = Array.isArray(result.missing_context_slots) ? result.missing_context_slots : [];
2809
- const significantScales = new Set(["batch", "milestone", "goal", "track", "program", "vision"]);
2810
- if (missingContext.length > 0 && significantScales.has(result.work_scale) && result.execution_allowed === true) {
2811
- errors.push(`${label} missing context must not allow significant execution`);
2812
- }
2813
-
2814
- if (result.work_scale === "track" && !String(result.selected_chain_id || "").includes("track")) {
2815
- errors.push(`${label} track work must use a track chain`);
2816
- }
2817
-
2818
- if (result.work_scale === "goal") {
2819
- const evidence = Array.isArray(result.evidence_requirements) ? result.evidence_requirements.join("\n").toLowerCase() : "";
2820
- if (!["done_when", "stages", "batches", "gates", "evidence"].some((term) => evidence.includes(term))) {
2821
- errors.push(`${label} goal work must include goal-contract evidence`);
2822
- }
2823
- }
2824
-
2825
- const riskyFlags = new Set(Array.isArray(result.risk_flags) ? result.risk_flags : []);
2826
- const hasRisk = ["live", "destructive", "access", "data", "git_history", "secret"].some((flag) => riskyFlags.has(flag));
2827
- if (hasRisk && result.execution_allowed === true && (!Array.isArray(result.required_gates) || result.required_gates.length === 0)) {
2828
- errors.push(`${label} risky work requires gates before execution`);
2829
- }
2830
-
2831
- if (result.semantic_confidence_authorizes_action === true) {
2832
- errors.push(`${label} semantic confidence must not authorize action`);
2833
- }
2834
- if (result.generated_brief_is_approval === true) {
2835
- errors.push(`${label} generated brief must not be approval`);
2836
- }
2837
- if (result.proposal_updates_canonical === true) {
2838
- errors.push(`${label} generated proposal must not update canonical graph state`);
2839
- }
2840
-
2841
- const text = JSON.stringify(result).toLowerCase();
2842
- for (const forbiddenTerm of [
2843
- "/users/rim/documents/" + "github/",
2844
- "simai private",
2845
- "private runtime " + "trace",
2846
- "token",
2847
- "secret value",
2848
- "customer raw log"
2849
- ]) {
2850
- if (text.includes(forbiddenTerm)) {
2851
- errors.push(`${label} contains forbidden public-safety term: ${forbiddenTerm}`);
2852
- }
2853
- }
2854
-
2855
- for (const requiredBoundary of [
2856
- "not authorization",
2857
- "not approve",
2858
- "does not update canonical",
2859
- "does not prove production"
2860
- ]) {
2861
- if (!text.includes(requiredBoundary)) {
2862
- warnings.push(`${label}.limitations should mention ${requiredBoundary}`);
2863
- }
2864
- }
2865
-
2866
- return { errors, warnings, result };
2867
- }
2868
-
2869
- function validateGoalVectorQualityControl(resultPath) {
2870
- const errors = [];
2871
- const warnings = [];
2872
- const result = readJson(resultPath);
2873
- const label = "goal_vector_quality_control";
2874
-
2875
- for (const field of [
2876
- "schema_version",
2877
- "id",
2878
- "profile",
2879
- "public_safety",
2880
- "work_scale",
2881
- "quality_verdict"
2882
- ]) {
2883
- requireString(result, field, label, errors);
2884
- }
2885
- for (const field of [
2886
- "start_state",
2887
- "final_outcome",
2888
- "goal_vector",
2889
- "reverse_audit",
2890
- "completion_claim"
2891
- ]) {
2892
- requireObject(result, field, label, errors);
2893
- }
2894
- for (const field of [
2895
- "vector_segments",
2896
- "batch_vector_links",
2897
- "required_qualities",
2898
- "quality_evidence",
2899
- "drift_findings",
2900
- "correction_routes"
2901
- ]) {
2902
- requireJsonArray(result, field, label, errors);
2903
- }
2904
- for (const field of [
2905
- "limitations"
2906
- ]) {
2907
- requireArray(result, field, label, errors);
2908
- }
2909
-
2910
- if (typeof result.canonical_write_allowed !== "boolean") {
2911
- errors.push(`${label}.canonical_write_allowed must be a boolean`);
2912
- }
2913
- if (result.canonical_write_allowed !== false) {
2914
- errors.push(`${label}.canonical_write_allowed must be false`);
2915
- }
2916
-
2917
- const verdicts = new Set(["PASS", "PASS_WITH_NOTES", "PARTIAL", "CORRECTION_REQUIRED", "BLOCKED", "FAIL"]);
2918
- if (typeof result.quality_verdict === "string" && !verdicts.has(result.quality_verdict)) {
2919
- errors.push(`${label}.quality_verdict has unsupported value ${result.quality_verdict}`);
2920
- }
2921
-
2922
- const workScales = new Set(["checkpoint", "batch", "milestone", "goal", "track", "program", "vision"]);
2923
- if (typeof result.work_scale === "string" && !workScales.has(result.work_scale)) {
2924
- errors.push(`${label}.work_scale has unsupported value ${result.work_scale}`);
2925
- }
2926
-
2927
- if (result.start_state && typeof result.start_state === "object") {
2928
- requireString(result.start_state, "id", `${label}.start_state`, errors);
2929
- requireString(result.start_state, "summary", `${label}.start_state`, errors);
2930
- }
2931
- if (result.final_outcome && typeof result.final_outcome === "object") {
2932
- requireString(result.final_outcome, "id", `${label}.final_outcome`, errors);
2933
- requireString(result.final_outcome, "summary", `${label}.final_outcome`, errors);
2934
- }
2935
- if (result.goal_vector && typeof result.goal_vector === "object") {
2936
- for (const field of ["id", "from", "to", "summary"]) {
2937
- requireString(result.goal_vector, field, `${label}.goal_vector`, errors);
2938
- }
2939
- if (result.start_state && result.goal_vector.from && result.goal_vector.from !== result.start_state.id) {
2940
- errors.push(`${label}.goal_vector.from must match start_state.id`);
2941
- }
2942
- if (result.final_outcome && result.goal_vector.to && result.goal_vector.to !== result.final_outcome.id) {
2943
- errors.push(`${label}.goal_vector.to must match final_outcome.id`);
2944
- }
2945
- }
2946
-
2947
- const significantScales = new Set(["batch", "milestone", "goal", "track", "program", "vision"]);
2948
- if (significantScales.has(result.work_scale)) {
2949
- if (!Array.isArray(result.vector_segments) || result.vector_segments.length === 0) {
2950
- errors.push(`${label}.vector_segments must not be empty for significant work`);
2951
- }
2952
- if (!Array.isArray(result.batch_vector_links) || result.batch_vector_links.length === 0) {
2953
- errors.push(`${label}.batch_vector_links must not be empty for significant work`);
2954
- }
2955
- }
2956
-
2957
- const qualityIds = new Set();
2958
- if (Array.isArray(result.required_qualities)) {
2959
- for (const [index, quality] of result.required_qualities.entries()) {
2960
- const qualityLabel = `${label}.required_qualities[${index}]`;
2961
- for (const field of ["id", "summary"]) {
2962
- requireString(quality, field, qualityLabel, errors);
2963
- }
2964
- requireArray(quality, "evidence_required", qualityLabel, errors);
2965
- if (typeof quality.id === "string") {
2966
- qualityIds.add(quality.id);
2967
- }
2968
- if (Array.isArray(quality.evidence_required) && quality.evidence_required.length === 0) {
2969
- errors.push(`${qualityLabel}.evidence_required must not be empty`);
2970
- }
2971
- }
2972
- }
2973
-
2974
- const evidenceIds = new Set();
2975
- if (Array.isArray(result.quality_evidence)) {
2976
- for (const [index, evidence] of result.quality_evidence.entries()) {
2977
- const evidenceLabel = `${label}.quality_evidence[${index}]`;
2978
- for (const field of ["id", "supports_quality", "summary"]) {
2979
- requireString(evidence, field, evidenceLabel, errors);
2980
- }
2981
- if (typeof evidence.id === "string") {
2982
- evidenceIds.add(evidence.id);
2983
- }
2984
- if (typeof evidence.supports_quality === "string" && !qualityIds.has(evidence.supports_quality)) {
2985
- errors.push(`${evidenceLabel}.supports_quality must reference required_qualities`);
2986
- }
2987
- }
2988
- }
2989
-
2990
- if (Array.isArray(result.vector_segments)) {
2991
- for (const [index, segment] of result.vector_segments.entries()) {
2992
- const segmentLabel = `${label}.vector_segments[${index}]`;
2993
- for (const field of ["id", "from", "to", "advances"]) {
2994
- requireString(segment, field, segmentLabel, errors);
2995
- }
2996
- requireArray(segment, "evidence_refs", segmentLabel, errors);
2997
- if (Array.isArray(segment.evidence_refs) && segment.evidence_refs.length === 0) {
2998
- errors.push(`${segmentLabel}.evidence_refs must not be empty`);
2999
- }
3000
- }
3001
- }
3002
-
3003
- if (Array.isArray(result.batch_vector_links)) {
3004
- for (const [index, link] of result.batch_vector_links.entries()) {
3005
- const linkLabel = `${label}.batch_vector_links[${index}]`;
3006
- for (const field of ["batch_ref", "advances", "specific_contribution"]) {
3007
- requireString(link, field, linkLabel, errors);
3008
- }
3009
- requireArray(link, "evidence_refs", linkLabel, errors);
3010
- if (Array.isArray(link.evidence_refs) && link.evidence_refs.length === 0) {
3011
- errors.push(`${linkLabel}.evidence_refs must not be empty`);
3012
- }
3013
- if (result.goal_vector && typeof link.advances === "string" && link.advances !== result.goal_vector.id) {
3014
- errors.push(`${linkLabel}.advances must reference goal_vector.id`);
3015
- }
3016
- }
3017
- }
3018
-
3019
- if (result.reverse_audit && typeof result.reverse_audit === "object") {
3020
- if (result.reverse_audit.performed !== true) {
3021
- errors.push(`${label}.reverse_audit.performed must be true`);
3022
- }
3023
- requireString(result.reverse_audit, "from_final_outcome", `${label}.reverse_audit`, errors);
3024
- requireString(result.reverse_audit, "verdict", `${label}.reverse_audit`, errors);
3025
- requireArray(result.reverse_audit, "checked_qualities", `${label}.reverse_audit`, errors);
3026
- requireArray(result.reverse_audit, "evidence_refs", `${label}.reverse_audit`, errors);
3027
- if (result.final_outcome && result.reverse_audit.from_final_outcome !== result.final_outcome.id) {
3028
- errors.push(`${label}.reverse_audit.from_final_outcome must match final_outcome.id`);
3029
- }
3030
- if (Array.isArray(result.reverse_audit.checked_qualities) && result.reverse_audit.checked_qualities.length === 0) {
3031
- errors.push(`${label}.reverse_audit.checked_qualities must not be empty`);
3032
- }
3033
- if (Array.isArray(result.reverse_audit.evidence_refs) && result.reverse_audit.evidence_refs.length === 0) {
3034
- errors.push(`${label}.reverse_audit.evidence_refs must not be empty`);
3035
- }
3036
- }
3037
-
3038
- const correctionFindingRefs = new Set(Array.isArray(result.correction_routes)
3039
- ? result.correction_routes.map((route) => route.finding_ref).filter((value) => typeof value === "string")
3040
- : []);
3041
- let hasBlockingDrift = false;
3042
- let hasCorrectionFinding = false;
3043
- if (Array.isArray(result.drift_findings)) {
3044
- for (const [index, finding] of result.drift_findings.entries()) {
3045
- const findingLabel = `${label}.drift_findings[${index}]`;
3046
- for (const field of ["id", "classification", "severity", "summary"]) {
3047
- requireString(finding, field, findingLabel, errors);
3048
- }
3049
- requireArray(finding, "evidence_refs", findingLabel, errors);
3050
- if (typeof finding.blocking !== "boolean") {
3051
- errors.push(`${findingLabel}.blocking must be a boolean`);
3052
- }
3053
- if (finding.blocking === true) {
3054
- hasBlockingDrift = true;
3055
- }
3056
- if (["scope_drift", "goal_drift", "quality_gap", "process_improvement", "correction_required"].includes(finding.classification)) {
3057
- hasCorrectionFinding = true;
3058
- if (typeof finding.id === "string" && !correctionFindingRefs.has(finding.id)) {
3059
- errors.push(`${findingLabel} requires a correction route`);
3060
- }
3061
- }
3062
- }
3063
- }
3064
-
3065
- if (Array.isArray(result.correction_routes)) {
3066
- for (const [index, route] of result.correction_routes.entries()) {
3067
- const routeLabel = `${label}.correction_routes[${index}]`;
3068
- for (const field of ["finding_ref", "route", "owner_role"]) {
3069
- requireString(route, field, routeLabel, errors);
3070
- }
3071
- const routeValue = typeof route.route === "string" ? route.route.toLowerCase() : "";
3072
- if (!["correction", "kaizen", "planning", "graph_sync", "work_fix"].some((term) => routeValue.includes(term))) {
3073
- errors.push(`${routeLabel}.route must point to correction, Kaizen, planning, graph_sync or work_fix`);
3074
- }
3075
- }
3076
- }
3077
-
3078
- if (hasCorrectionFinding && (!Array.isArray(result.correction_routes) || result.correction_routes.length === 0)) {
3079
- errors.push(`${label}.correction_routes must not be empty when drift findings require correction`);
3080
- }
3081
-
3082
- if (result.completion_claim && typeof result.completion_claim === "object") {
3083
- if (typeof result.completion_claim.claimed_complete !== "boolean") {
3084
- errors.push(`${label}.completion_claim.claimed_complete must be a boolean`);
3085
- }
3086
- if (typeof result.completion_claim.accepted !== "boolean") {
3087
- errors.push(`${label}.completion_claim.accepted must be a boolean`);
3088
- }
3089
- requireString(result.completion_claim, "claim_ref", `${label}.completion_claim`, errors);
3090
- requireArray(result.completion_claim, "evidence_refs", `${label}.completion_claim`, errors);
3091
- if (result.completion_claim.claimed_complete === true && Array.isArray(result.completion_claim.evidence_refs) && result.completion_claim.evidence_refs.length === 0) {
3092
- errors.push(`${label}.completion_claim.evidence_refs must not be empty when completion is claimed`);
3093
- }
3094
- if (result.completion_claim.accepted === true) {
3095
- errors.push(`${label}.completion_claim.accepted must remain false; quality control is not acceptance`);
3096
- }
3097
- }
3098
-
3099
- if (["PASS", "PASS_WITH_NOTES"].includes(result.quality_verdict)) {
3100
- if (hasBlockingDrift) {
3101
- errors.push(`${label}.quality_verdict cannot pass with blocking drift findings`);
3102
- }
3103
- if (!result.reverse_audit || result.reverse_audit.performed !== true) {
3104
- errors.push(`${label}.quality_verdict requires reverse audit`);
3105
- }
3106
- if (!Array.isArray(result.quality_evidence) || result.quality_evidence.length === 0) {
3107
- errors.push(`${label}.quality_verdict requires quality evidence`);
3108
- }
3109
- }
3110
-
3111
- const text = JSON.stringify(result).toLowerCase();
3112
- for (const forbiddenTerm of [
3113
- "tests are acceptance",
3114
- "evidence is acceptance",
3115
- "goal vector authorizes",
3116
- "reverse audit approves",
3117
- "automatic canonical update",
3118
- "canonical_write_allowed\":true",
3119
- "/users/rim/documents/" + "github/",
3120
- "simai private",
3121
- "private runtime " + "trace",
3122
- "token",
3123
- "secret value",
3124
- "customer raw log"
3125
- ]) {
3126
- if (text.includes(forbiddenTerm)) {
3127
- errors.push(`${label} contains forbidden boundary/public-safety term: ${forbiddenTerm}`);
3128
- }
3129
- }
3130
-
3131
- const limitationText = Array.isArray(result.limitations) ? result.limitations.join("\n").toLowerCase() : "";
3132
- for (const expectedBoundary of [
3133
- "not authorization",
3134
- "not approval",
3135
- "evidence",
3136
- "tests",
3137
- "canonical",
3138
- "production"
3139
- ]) {
3140
- if (!limitationText.includes(expectedBoundary)) {
3141
- warnings.push(`${label}.limitations should mention ${expectedBoundary}`);
3142
- }
3143
- }
3144
-
3145
- return { errors, warnings, result };
3146
- }
3147
-
3148
- const rawArgs = process.argv.slice(2);
3149
- const outputFormat = rawArgs.includes("--markdown") ? "markdown" : "json";
3150
- const positionalArgs = rawArgs.filter((arg) => arg !== "--markdown" && arg !== "--json");
3151
- const modeOrPackageDir = positionalArgs[0];
3152
- if (!modeOrPackageDir) {
3153
- usage();
3154
- process.exit(2);
3155
- }
3156
-
3157
- try {
3158
- const isSeedMode = modeOrPackageDir === "seed";
3159
- const isProfileMode = modeOrPackageDir === "profile";
3160
- const isContextPackMode = modeOrPackageDir === "context-pack";
3161
- const isImplementationControlCycleMode = modeOrPackageDir === "implementation-control-cycle";
3162
- const isProcessTransitionMode = modeOrPackageDir === "process-transition";
3163
- const publicResultModes = new Set([
3164
- "launch-record",
3165
- "process-control-contract",
3166
- "technology-quality-feedback",
3167
- "character-layer-integration",
3168
- "model-portability-evidence",
3169
- "character-layer-readiness",
3170
- "development-cockpit",
3171
- "feature-implementation-traceability",
3172
- "multi-source-quality-feedback",
3173
- "dynamic-episode-trace",
3174
- "graph-dna-alignment",
3175
- "work-state-machine",
3176
- "recovery-resume-record",
3177
- "risk-control-matrix",
3178
- "multi-agent-coordination",
3179
- "source-boundary-contract",
3180
- "semantic-intent-resolution",
3181
- "goal-vector-quality-control"
3182
- ]);
3183
- const isPublicResultMode = publicResultModes.has(modeOrPackageDir);
3184
- const isDynamicEpisodeTraceMode = modeOrPackageDir === "dynamic-episode-trace";
3185
- const targetPath = isSeedMode || isProfileMode || isContextPackMode || isImplementationControlCycleMode || isProcessTransitionMode || isPublicResultMode ? positionalArgs[1] : modeOrPackageDir;
3186
- const contextPackPath = isContextPackMode ? positionalArgs[2] : null;
3187
- const transitionRequestPath = isProcessTransitionMode ? positionalArgs[2] : null;
3188
- if (!targetPath) {
3189
- usage();
3190
- process.exit(2);
3191
- }
3192
- if (isContextPackMode && !contextPackPath) {
3193
- usage();
3194
- process.exit(2);
3195
- }
3196
- if (isProcessTransitionMode && !transitionRequestPath) {
3197
- usage();
3198
- process.exit(2);
3199
- }
3200
- const result = isSeedMode
3201
- ? validateSeed(path.resolve(targetPath))
3202
- : isProfileMode
3203
- ? validateProfile(path.resolve(targetPath))
3204
- : isContextPackMode
3205
- ? validateContextPack(path.resolve(targetPath), path.resolve(contextPackPath))
3206
- : isImplementationControlCycleMode
3207
- ? validateImplementationControlCycle(path.resolve(targetPath))
3208
- : isProcessTransitionMode
3209
- ? validateProcessTransition(path.resolve(targetPath), path.resolve(transitionRequestPath))
3210
- : modeOrPackageDir === "character-layer-integration"
3211
- ? validateCharacterLayerIntegration(path.resolve(targetPath))
3212
- : modeOrPackageDir === "model-portability-evidence"
3213
- ? validateModelPortabilityEvidence(path.resolve(targetPath))
3214
- : modeOrPackageDir === "character-layer-readiness"
3215
- ? validateCharacterLayerReadiness(path.resolve(targetPath))
3216
- : isDynamicEpisodeTraceMode
3217
- ? validateDynamicEpisodeTrace(path.resolve(targetPath))
3218
- : modeOrPackageDir === "semantic-intent-resolution"
3219
- ? validateSemanticIntentResolution(path.resolve(targetPath))
3220
- : modeOrPackageDir === "goal-vector-quality-control"
3221
- ? validateGoalVectorQualityControl(path.resolve(targetPath))
3222
- : isPublicResultMode
3223
- ? validatePublicImplementationControlResult(path.resolve(targetPath), modeOrPackageDir)
3224
- : validatePackage(path.resolve(targetPath));
3225
- const output = {
3226
- mode: isSeedMode ? "seed" : isProfileMode ? "profile" : isContextPackMode ? "context_pack" : isImplementationControlCycleMode ? "implementation_control_cycle" : isProcessTransitionMode ? "process_transition" : isDynamicEpisodeTraceMode ? "dynamic_episode_trace" : isPublicResultMode ? modeOrPackageDir.replace(/-/g, "_") : "package",
3227
- target: isContextPackMode ? path.resolve(contextPackPath) : isProcessTransitionMode ? path.resolve(transitionRequestPath) : path.resolve(targetPath),
3228
- package: isContextPackMode ? path.resolve(targetPath) : undefined,
3229
- state_machine: isProcessTransitionMode ? path.resolve(targetPath) : undefined,
3230
- valid: result.errors.length === 0,
3231
- errors: result.errors,
3232
- warnings: result.warnings,
3233
- explanation: result.explanation,
3234
- result: isPublicResultMode || isDynamicEpisodeTraceMode ? result.result : undefined
3235
- };
3236
- if (outputFormat === "markdown") {
3237
- console.log(formatMarkdownReport(output));
3238
- } else {
3239
- console.log(JSON.stringify(output, null, 2));
3240
- }
3241
- process.exit(output.valid ? 0 : 1);
3242
- } catch (error) {
3243
- console.error(error.message);
3244
- process.exit(1);
3245
- }