@mutagent/helix 0.1.0-alpha.14

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 (357) hide show
  1. package/.claude/skills/mutagent-helix/SKILL.md +113 -0
  2. package/.claude/skills/mutagent-helix/scripts/cli/codex-transcode.ts +143 -0
  3. package/.claude/skills/mutagent-helix/scripts/cli/doctor.ts +111 -0
  4. package/.claude/skills/mutagent-helix/scripts/cli/init.ts +382 -0
  5. package/.claude/skills/mutagent-helix/scripts/cli/run.sh +61 -0
  6. package/CLAUDE.md +193 -0
  7. package/LICENSE +201 -0
  8. package/NOTICE +22 -0
  9. package/README.md +209 -0
  10. package/assets/adl-loop.svg +162 -0
  11. package/assets/system-status.svg +422 -0
  12. package/bin/mutagent-cli.mjs +9950 -0
  13. package/bin/mutagent-helix.mjs +78 -0
  14. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/CLAUDE.md +28 -0
  15. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/SKILL.md +138 -0
  16. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl +247 -0
  17. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/frameworks/doc-pins.md +53 -0
  18. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/principles.md +91 -0
  19. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/requirements.yaml +295 -0
  20. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md +302 -0
  21. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/doctor.ts +116 -0
  22. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/init.ts +230 -0
  23. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/run.sh +60 -0
  24. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts +199 -0
  25. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts +455 -0
  26. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/setup/detect.ts +67 -0
  27. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/validate/validate-spec.ts +93 -0
  28. package/mutagent-agentspec/LICENSE +201 -0
  29. package/mutagent-agentspec/NOTICE +19 -0
  30. package/mutagent-agentspec/README.md +44 -0
  31. package/mutagent-builder/.claude/skills/mutagent-builder/SKILL.md +100 -0
  32. package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md +312 -0
  33. package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md +357 -0
  34. package/mutagent-builder/.claude/skills/mutagent-builder/assets/templates/build-report.md.tpl +39 -0
  35. package/mutagent-builder/.claude/skills/mutagent-builder/references/principles.md +31 -0
  36. package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/build-protocol.md +61 -0
  37. package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/improve-handoff.md +23 -0
  38. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/cli/run.sh +60 -0
  39. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/handoff/validate-build-input.ts +72 -0
  40. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts +499 -0
  41. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts +182 -0
  42. package/mutagent-builder/CLAUDE.md +25 -0
  43. package/mutagent-builder/README.md +26 -0
  44. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/README.md +192 -0
  45. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/SKILL.md +352 -0
  46. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-architect.md +256 -0
  47. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-engineer.md +344 -0
  48. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/diagnostics-analyzer.md +576 -0
  49. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/discovery.md +425 -0
  50. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.json.tpl +24 -0
  51. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.md.tpl +49 -0
  52. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/config.yaml.tpl +100 -0
  53. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/pr-body.md.tpl +56 -0
  54. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/report.html.tpl +327 -0
  55. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/README.md +27 -0
  56. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl +125 -0
  57. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl +234 -0
  58. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl +152 -0
  59. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl +127 -0
  60. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl +1712 -0
  61. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md +59 -0
  62. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md +58 -0
  63. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md +44 -0
  64. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md +61 -0
  65. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md +69 -0
  66. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md +53 -0
  67. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md +60 -0
  68. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md +41 -0
  69. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md +75 -0
  70. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md +48 -0
  71. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md +43 -0
  72. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md +57 -0
  73. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md +52 -0
  74. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md +59 -0
  75. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-findings.json +92 -0
  76. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-meta.json +47 -0
  77. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/adapter-strategy.md +75 -0
  78. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config-migration.md +84 -0
  79. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config.md +159 -0
  80. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/filter-search-matrix.md +66 -0
  81. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/harness-knowledge.md +22 -0
  82. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/memory-format.md +78 -0
  83. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/onboarding-decisions.yaml +187 -0
  84. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/operation-inventory.md +59 -0
  85. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/overview.md +167 -0
  86. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/reference.md +119 -0
  87. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/script-index.md +101 -0
  88. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-adapter-contract.md +93 -0
  89. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/claude-code-transcripts.md +66 -0
  90. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex-transcripts.md +78 -0
  91. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex.md +145 -0
  92. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/install-paths.md +57 -0
  93. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/langfuse.md +178 -0
  94. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/local-jsonl.md +55 -0
  95. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/openobserve.md +102 -0
  96. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/otel.md +63 -0
  97. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/cloud-rest.md +84 -0
  98. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-claude.md +65 -0
  99. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cloud-agent-sdk.md +92 -0
  100. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-codex.md +72 -0
  101. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cursor.md +108 -0
  102. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-mastra.md +77 -0
  103. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-opencode.md +70 -0
  104. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/apply-pr-comment-format.md +82 -0
  105. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/diagnostics.md +35 -0
  106. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/handover-contract.md +247 -0
  107. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/onboarding.md +300 -0
  108. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/orchestrator-protocol.md +1861 -0
  109. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rca.md +331 -0
  110. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rendering-anatomy.md +314 -0
  111. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/schedule-prep.md +100 -0
  112. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/scope-model.md +128 -0
  113. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/verification-methodology.md +174 -0
  114. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/aggregate/sort-findings.ts +0 -0
  115. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/blind-spots.ts +167 -0
  116. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/llm-sample.ts +681 -0
  117. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/doctor.ts +215 -0
  118. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/init.ts +1013 -0
  119. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/install-agents.ts +350 -0
  120. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/run.sh +61 -0
  121. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/shared-templates.ts +79 -0
  122. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/load.ts +392 -0
  123. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/resolve-credential.ts +120 -0
  124. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/schema.ts +641 -0
  125. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/validate.ts +134 -0
  126. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/build-diagnosis-context.ts +417 -0
  127. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/load-context.ts +105 -0
  128. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/contract/types.ts +166 -0
  129. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/build-render-input.ts +1964 -0
  130. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/corpus-severity.ts +172 -0
  131. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/dismissal-match.ts +270 -0
  132. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/rank-remedies.ts +75 -0
  133. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/install-hooks.sh +46 -0
  134. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/pre-push.sh +78 -0
  135. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/invocation/parse-brief.ts +188 -0
  136. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/match.ts +114 -0
  137. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/paths.ts +95 -0
  138. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/store.ts +535 -0
  139. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/types.ts +181 -0
  140. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/lint/template-inline-js.ts +267 -0
  141. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/append.ts +188 -0
  142. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/read.ts +218 -0
  143. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/platforms/entity-context.ts +686 -0
  144. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/read-unitf.ts +267 -0
  145. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/trace.ts +1078 -0
  146. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-adapter.ts +0 -0
  147. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-types.ts +213 -0
  148. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/persist-selections.ts +174 -0
  149. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/render.ts +3254 -0
  150. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/diagnose.ts +64 -0
  151. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/session.ts +167 -0
  152. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/caps.ts +345 -0
  153. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/deep-read-gate.ts +424 -0
  154. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/representative.ts +584 -0
  155. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/objection.ts +224 -0
  156. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/trajectory.ts +489 -0
  157. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/dispatch.ts +135 -0
  158. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/probe.ts +170 -0
  159. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/detect.ts +307 -0
  160. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/ensure-cli.ts +315 -0
  161. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/reconfigure.ts +77 -0
  162. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/verify-agents.ts +207 -0
  163. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/slicer.ts +166 -0
  164. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/claude-code.ts +17 -0
  165. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/codex.ts +11 -0
  166. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/langfuse.ts +17 -0
  167. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/local-jsonl.ts +12 -0
  168. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/otel.ts +12 -0
  169. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/index.ts +54 -0
  170. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/registry.ts +45 -0
  171. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/types.ts +86 -0
  172. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/stale-detector.ts +74 -0
  173. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/test/render-playwright.cli.ts +477 -0
  174. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/claude-code.ts +133 -0
  175. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/langfuse.ts +143 -0
  176. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0-scan.ts +423 -0
  177. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/completeness-check.ts +436 -0
  178. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/doc-refs.ts +190 -0
  179. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/finalize-gate.ts +417 -0
  180. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/findings-contract.ts +628 -0
  181. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/render-js-syntax.ts +188 -0
  182. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/report-checklist.yaml +217 -0
  183. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/trace-shape.ts +262 -0
  184. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/wave6-checklist.ts +326 -0
  185. package/mutagent-diagnostics/CLAUDE.md +41 -0
  186. package/mutagent-diagnostics/LICENSE +201 -0
  187. package/mutagent-diagnostics/NOTICE +18 -0
  188. package/mutagent-diagnostics/README.md +343 -0
  189. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/SKILL.md +548 -0
  190. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/audit-executor.md +169 -0
  191. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md +160 -0
  192. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/discovery.md +425 -0
  193. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md +1108 -0
  194. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/theme.css +213 -0
  195. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/wordmark.html +9 -0
  196. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/context-flow-lens.md +85 -0
  197. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/data-lens.md +47 -0
  198. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/decision-lens.md +48 -0
  199. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md +53 -0
  200. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/trajectory-lens.md +44 -0
  201. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/build-review-interface.md +83 -0
  202. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/edd-loop.md +134 -0
  203. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/error-analysis.md +113 -0
  204. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-audit.md +154 -0
  205. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-stage.md +168 -0
  206. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/generate-synthetic-data.md +81 -0
  207. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/grounded-adjudication.md +221 -0
  208. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/memory-format.md +65 -0
  209. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/methodology.md +201 -0
  210. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/operation-inventory.md +197 -0
  211. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/validate-evaluator.md +125 -0
  212. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/workflows/orchestrator-protocol.md +300 -0
  213. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/write-judge-prompt.md +123 -0
  214. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/behavior-tree.schema.yaml +73 -0
  215. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/dataset.schema.yaml +66 -0
  216. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/edd-change-request.schema.yaml +114 -0
  217. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/eval-matrix.schema.yaml +74 -0
  218. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-graph.schema.yaml +69 -0
  219. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-profile.schema.yaml +49 -0
  220. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml +40 -0
  221. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/scorecard.schema.yaml +85 -0
  222. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts +0 -0
  223. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts +543 -0
  224. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/artifact-paths.ts +115 -0
  225. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/assemble-scorecard.ts +172 -0
  226. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-dataset.ts +186 -0
  227. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-evals.ts +93 -0
  228. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts +393 -0
  229. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/check-method-router.ts +170 -0
  230. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/aggregate.ts +112 -0
  231. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/audit-run.ts +182 -0
  232. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/doctor.ts +211 -0
  233. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/dogfood.ts +133 -0
  234. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/init.ts +601 -0
  235. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/methodology-review.ts +122 -0
  236. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts +295 -0
  237. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts +165 -0
  238. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/run.sh +56 -0
  239. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/variance-check.ts +105 -0
  240. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-eval.ts +248 -0
  241. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts +285 -0
  242. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/codegen-evals.ts +173 -0
  243. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-project.ts +151 -0
  244. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-sampler.ts +267 -0
  245. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/load.ts +343 -0
  246. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/schema.ts +380 -0
  247. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts +85 -0
  248. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/dataset.ts +149 -0
  249. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-engine.ts +118 -0
  250. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts +577 -0
  251. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts +1074 -0
  252. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/flow-graph.ts +194 -0
  253. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/types.ts +303 -0
  254. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/validation.ts +193 -0
  255. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/derive-dataset.ts +152 -0
  256. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts +219 -0
  257. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/diff-discriminate.ts +160 -0
  258. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/discover-criteria.ts +348 -0
  259. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts +232 -0
  260. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts +210 -0
  261. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/variance-gate.ts +186 -0
  262. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/emit-completeness.ts +111 -0
  263. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/eval-engine.ts +160 -0
  264. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/evaluate.ts +333 -0
  265. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/flow-graph.ts +230 -0
  266. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts +253 -0
  267. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-provider.ts +135 -0
  268. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-grounding.ts +229 -0
  269. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-uniformity.ts +168 -0
  270. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/living-suite.ts +109 -0
  271. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-bundle.ts +203 -0
  272. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile-vocab.ts +64 -0
  273. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile.ts +106 -0
  274. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/mask.ts +138 -0
  275. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts +113 -0
  276. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts +750 -0
  277. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/append.ts +215 -0
  278. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/read.ts +168 -0
  279. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/persist-eval-criteria.ts +232 -0
  280. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts +125 -0
  281. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/profile-subject.ts +310 -0
  282. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/publish-report.ts +131 -0
  283. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts +81 -0
  284. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts +195 -0
  285. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-discover-report.ts +1640 -0
  286. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts +3838 -0
  287. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-report.ts +212 -0
  288. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-credential.ts +110 -0
  289. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-ref.ts +98 -0
  290. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/result-verify.ts +129 -0
  291. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/route-failures.ts +330 -0
  292. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-deterministic.ts +367 -0
  293. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts +719 -0
  294. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-judge.ts +155 -0
  295. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts +175 -0
  296. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sample-traces.ts +210 -0
  297. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/self-audit.ts +387 -0
  298. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/source-map.ts +106 -0
  299. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts +134 -0
  300. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/substrate.ts +162 -0
  301. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts +244 -0
  302. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/ui-slots.ts +119 -0
  303. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts +284 -0
  304. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/validate-judge.ts +358 -0
  305. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/variance-compare.ts +177 -0
  306. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/behavior-tree.yaml +140 -0
  307. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/eval-matrix.yaml +1270 -0
  308. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/methodology-review.yaml +105 -0
  309. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/audit.workflow.js +82 -0
  310. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/data-leak.workflow.js +236 -0
  311. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/variance.workflow.js +163 -0
  312. package/mutagent-evaluator/CLAUDE.md +45 -0
  313. package/mutagent-evaluator/LICENSE +201 -0
  314. package/mutagent-evaluator/NOTICE +23 -0
  315. package/mutagent-evaluator/README.md +88 -0
  316. package/mutagent-optimize/.claude/skills/mutagent-optimize/SKILL.md +287 -0
  317. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/contracts/amend-request.ts +503 -0
  318. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/improve-loop-run.ts +304 -0
  319. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state-cli.ts +300 -0
  320. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state.ts +440 -0
  321. package/mutagent-optimize/CLAUDE.md +49 -0
  322. package/mutagent-optimize/README.md +26 -0
  323. package/mutagent-orchestrator/CLAUDE.md +102 -0
  324. package/mutagent-orchestrator/README.md +20 -0
  325. package/mutagent-orchestrator/assets/agents/discovery.md +425 -0
  326. package/mutagent-orchestrator/assets/agents/dogfood-monitor.md +266 -0
  327. package/mutagent-orchestrator/assets/agents/monitor.md +258 -0
  328. package/mutagent-orchestrator/orchestrator.md +782 -0
  329. package/mutagent-orchestrator/references/MONITORING.md +209 -0
  330. package/mutagent-orchestrator/references/config-fields.md +132 -0
  331. package/mutagent-orchestrator/references/config-migration.md +132 -0
  332. package/mutagent-orchestrator/references/index-registry.md +92 -0
  333. package/mutagent-orchestrator/routing.yaml +391 -0
  334. package/mutagent-orchestrator/scripts/config-schema.ts +1010 -0
  335. package/mutagent-orchestrator/scripts/dispatch.ts +439 -0
  336. package/mutagent-orchestrator/scripts/dogfood/extract-feedback.ts +203 -0
  337. package/mutagent-orchestrator/scripts/dogfood/reconstruct-trajectory.ts +327 -0
  338. package/mutagent-orchestrator/scripts/dogfood/render-dogfood-report.ts +347 -0
  339. package/mutagent-orchestrator/scripts/dogfood/resolve-subagents.ts +160 -0
  340. package/mutagent-orchestrator/scripts/dogfood/run-report.ts +264 -0
  341. package/mutagent-orchestrator/scripts/dogfood/slack-thread.ts +106 -0
  342. package/mutagent-orchestrator/scripts/dogfood/types.ts +257 -0
  343. package/mutagent-orchestrator/scripts/eval-routing.ts +753 -0
  344. package/mutagent-orchestrator/scripts/gate.ts +219 -0
  345. package/mutagent-orchestrator/scripts/handover-contract.ts +362 -0
  346. package/mutagent-orchestrator/scripts/index/build-index.ts +351 -0
  347. package/mutagent-orchestrator/scripts/index/render-index.ts +110 -0
  348. package/mutagent-orchestrator/scripts/monitor/slack-notify.ts +111 -0
  349. package/mutagent-orchestrator/scripts/monitor/triggers.ts +162 -0
  350. package/mutagent-orchestrator/scripts/onboarding-check.ts +369 -0
  351. package/mutagent-orchestrator/scripts/render-roster.ts +308 -0
  352. package/mutagent-orchestrator/scripts/resolve-credential.ts +185 -0
  353. package/mutagent-orchestrator/scripts/resolve-paths.ts +114 -0
  354. package/mutagent-orchestrator/scripts/slack/format.ts +63 -0
  355. package/mutagent-orchestrator/scripts/slack/post.ts +115 -0
  356. package/mutagent-orchestrator/scripts/sync-index.ts +311 -0
  357. package/package.json +64 -0
@@ -0,0 +1,215 @@
1
+ /**
2
+ * scripts/memory/append.ts — project-level AutoMemory: APPEND (dated + classified).
3
+ * ---------------------------------------------------------------------------
4
+ * Append an operator-feedback entry to the project-level AutoMemory store
5
+ * (`.mutagent/memory/`) in the Claude-Code AutoMemory format
6
+ * (`references/memory-format.md`). The SUBJECT is the TOOL + operator preferences
7
+ * — NOT the evaluated agent (subject findings go to the living-suite, never here).
8
+ *
9
+ * The store: one FACT per `<slug>.md` file + an index `MEMORY.md`
10
+ * (`- [Title](<slug>.md) — <hook>` one line/entry). Every entry is DATED
11
+ * (`metadata.created`) + lifecycle-tagged. DEDUPE on append: an entry with the
12
+ * same slug is UPDATED (body + refreshed date), never duplicated.
13
+ *
14
+ * Determinism (coding-rules): the CORES are PURE — `now` (the date) is INJECTED,
15
+ * never read from a clock; fs is done only in the thin writer at the bottom. Tests
16
+ * exercise the pure cores with a fixed `now`. Standalone: no cross-skill import
17
+ * (mirrors the diagnostics library-store APPEND DISCIPLINE, not its per-entity
18
+ * keying — this store is flat + tool-scoped).
19
+ */
20
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
21
+ import { join } from "node:path";
22
+
23
+ // ── Categorical constants (no magic strings) ─────────────────────────────────
24
+
25
+ /** Claude Code's four memory types (the classification target). */
26
+ export const MemoryType = {
27
+ User: "user",
28
+ Feedback: "feedback",
29
+ Project: "project",
30
+ Reference: "reference",
31
+ } as const;
32
+ export type MemoryTypeValue = (typeof MemoryType)[keyof typeof MemoryType];
33
+
34
+ /** The ADL lifecycle tag (the recall filter axis). */
35
+ export const Lifecycle = {
36
+ Spec: "spec",
37
+ Build: "build",
38
+ Evaluate: "evaluate",
39
+ Diagnose: "diagnose",
40
+ Improve: "improve",
41
+ General: "general",
42
+ } as const;
43
+ export type LifecycleValue = (typeof Lifecycle)[keyof typeof Lifecycle];
44
+
45
+ // ── Classification (the memory-format.md rubric — first match wins) ───────────
46
+
47
+ /** The raw operator feedback to classify + persist. */
48
+ export interface FeedbackInput {
49
+ /** the fact to store (verbatim operator text or a distilled summary). */
50
+ text: string;
51
+ /** optional caller hint (a URL / path) — strengthens the `reference` signal. */
52
+ resourceHint?: string;
53
+ }
54
+
55
+ /**
56
+ * Classify feedback into one of the four Claude-Code types by the memory-format.md
57
+ * decision order (FIRST match wins): reference → user → feedback → project. PURE,
58
+ * deterministic — regex + explicit hint, no I/O, no LLM. A caller may OVERRIDE the
59
+ * classification explicitly (an operator who knows the type); this is the default.
60
+ */
61
+ export function classifyFeedback(fb: FeedbackInput): MemoryTypeValue {
62
+ const t = fb.text.trim();
63
+ // 1 — external resource (URL / dashboard / ticket / dataset path).
64
+ if (
65
+ fb.resourceHint !== undefined ||
66
+ /\bhttps?:\/\/\S+/i.test(t) ||
67
+ /\b(?:dashboard|ticket|dataset|\S+\.(?:ndjson|jsonl|csv|parquet)(?:\.gz)?)\b/i.test(t)
68
+ ) {
69
+ return MemoryType.Reference;
70
+ }
71
+ // 2 — who the operator is (identity / standing preference about themselves).
72
+ if (/\bI['’]?m\b|\bI am\b|\bmy (?:role|team|preference)\b|\bas the (?:lead|operator|owner)\b/i.test(t)) {
73
+ return MemoryType.User;
74
+ }
75
+ // 3 — how the TOOL should behave (behavioral steer).
76
+ if (/\b(?:stop|don['’]?t|do not|too verbose|next time|always|never|prefer)\b/i.test(t)) {
77
+ return MemoryType.Feedback;
78
+ }
79
+ // 4 — ongoing work / goals / constraints (default).
80
+ return MemoryType.Project;
81
+ }
82
+
83
+ // ── Slug + entry formatting ───────────────────────────────────────────────────
84
+
85
+ /** Kebab-case a title into a stable slug (deterministic — no random). */
86
+ export function slugify(title: string): string {
87
+ const s = title
88
+ .toLowerCase()
89
+ .replace(/['’"]/g, "")
90
+ .replace(/[^a-z0-9]+/g, "-")
91
+ .replace(/^-+|-+$/g, "");
92
+ return s === "" ? "untitled" : s;
93
+ }
94
+
95
+ export interface MemoryEntry {
96
+ /** kebab-case slug (the file name stem + `name:` frontmatter). */
97
+ slug: string;
98
+ /** one-line description (recall relevance). */
99
+ description: string;
100
+ type: MemoryTypeValue;
101
+ lifecycle: LifecycleValue;
102
+ /** YYYY-MM-DD (INJECTED — never a live clock). */
103
+ created: string;
104
+ /** the fact body (feedback/project carry **Why:** + **How to apply:** lines). */
105
+ body: string;
106
+ }
107
+
108
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
109
+
110
+ /** Render a MemoryEntry to its `<slug>.md` file text (Claude-Code AutoMemory format). */
111
+ export function renderEntryMarkdown(entry: MemoryEntry): string {
112
+ if (!DATE_RE.test(entry.created)) {
113
+ throw new Error(
114
+ `renderEntryMarkdown: created must be YYYY-MM-DD (got '${entry.created}'). Every memory is DATED — ` +
115
+ "inject `now`, never read a clock.",
116
+ );
117
+ }
118
+ return (
119
+ "---\n" +
120
+ `name: ${entry.slug}\n` +
121
+ `description: ${entry.description}\n` +
122
+ "metadata:\n" +
123
+ ` type: ${entry.type}\n` +
124
+ ` lifecycle: ${entry.lifecycle}\n` +
125
+ ` created: ${entry.created}\n` +
126
+ "---\n\n" +
127
+ entry.body.trimEnd() +
128
+ "\n"
129
+ );
130
+ }
131
+
132
+ /** The one index line for an entry (`- [Title](<slug>.md) — <hook>`). */
133
+ export function indexLine(entry: MemoryEntry): string {
134
+ return `- [${entry.slug}](${entry.slug}.md) — ${entry.description}`;
135
+ }
136
+
137
+ /**
138
+ * Fold an entry's index line into an existing `MEMORY.md`, DEDUPED by slug (an
139
+ * existing line for the same slug is REPLACED in place; a new slug is appended).
140
+ * PURE — string in, string out. Preserves a leading title/header block.
141
+ */
142
+ export function upsertIndex(existingIndex: string, entry: MemoryEntry): string {
143
+ const newLine = indexLine(entry);
144
+ const lineRe = new RegExp(`^- \\[${entry.slug}\\]\\(${entry.slug}\\.md\\).*$`);
145
+ const lines = existingIndex.split("\n");
146
+ let replaced = false;
147
+ const out = lines.map((l) => {
148
+ if (lineRe.test(l)) {
149
+ replaced = true;
150
+ return newLine;
151
+ }
152
+ return l;
153
+ });
154
+ if (replaced) return out.join("\n");
155
+ // Append (ensure a header exists + trailing newline hygiene).
156
+ const base =
157
+ existingIndex.trim() === ""
158
+ ? "# AutoMemory — index\n\n> Project-level operator-feedback + tool self-learning. One line per entry.\n"
159
+ : existingIndex.replace(/\n*$/, "\n");
160
+ return base + newLine + "\n";
161
+ }
162
+
163
+ // ── Filesystem writer (the ONLY impure edge) ──────────────────────────────────
164
+
165
+ export interface AppendResult {
166
+ slug: string;
167
+ entryFile: string;
168
+ indexFile: string;
169
+ /** true when an existing entry was UPDATED (dedupe hit) rather than created. */
170
+ updated: boolean;
171
+ }
172
+
173
+ /**
174
+ * Append (or UPDATE) an AutoMemory entry under `<memoryDir>/`. Writes the
175
+ * `<slug>.md` file + upserts the `MEMORY.md` index line. DEDUPE: an existing
176
+ * `<slug>.md` is overwritten (not duplicated) and its index line replaced.
177
+ * `now` (YYYY-MM-DD) is INJECTED. The pure cores above do the formatting; this is
178
+ * the thin fs edge.
179
+ */
180
+ export function appendMemory(
181
+ memoryDir: string,
182
+ input: { title: string; description: string; lifecycle: LifecycleValue; feedback: FeedbackInput; type?: MemoryTypeValue },
183
+ now: string,
184
+ ): AppendResult {
185
+ const slug = slugify(input.title);
186
+ const type = input.type ?? classifyFeedback(input.feedback);
187
+ const entry: MemoryEntry = {
188
+ slug,
189
+ description: input.description,
190
+ type,
191
+ lifecycle: input.lifecycle,
192
+ created: now,
193
+ body: input.feedback.text.trim(),
194
+ };
195
+
196
+ mkdirSync(memoryDir, { recursive: true });
197
+ const entryFile = join(memoryDir, `${slug}.md`);
198
+ const updated = existsSync(entryFile);
199
+ writeFileSync(entryFile, renderEntryMarkdown(entry));
200
+
201
+ const indexFile = join(memoryDir, "MEMORY.md");
202
+ const existingIndex = existsSync(indexFile) ? readFileSync(indexFile, "utf8") : "";
203
+ writeFileSync(indexFile, upsertIndex(existingIndex, entry));
204
+
205
+ return { slug, entryFile, indexFile, updated };
206
+ }
207
+
208
+ /** List the entry slugs currently in a memory dir (PURE-ish fs read; [] if absent). */
209
+ export function listEntrySlugs(memoryDir: string): string[] {
210
+ if (!existsSync(memoryDir)) return [];
211
+ return readdirSync(memoryDir)
212
+ .filter((f) => f.endsWith(".md") && f !== "MEMORY.md")
213
+ .map((f) => f.replace(/\.md$/, ""))
214
+ .sort();
215
+ }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * scripts/memory/read.ts — project-level AutoMemory: READ (filter by lifecycle).
3
+ * ---------------------------------------------------------------------------
4
+ * Read the project-level AutoMemory store (`.mutagent/memory/`) at run START and
5
+ * return the entries relevant to THIS stage. The evaluator reads entries whose
6
+ * `lifecycle ∈ {evaluate, general}` (the run-start injection surface). The subject
7
+ * is the TOOL + operator preferences — NOT the evaluated agent.
8
+ *
9
+ * Determinism (coding-rules): the PARSE + FILTER cores are PURE (string in, data
10
+ * out); fs is confined to `readMemoryDir`. Tests exercise the pure cores against
11
+ * committed fixture text. Standalone — no cross-skill import.
12
+ *
13
+ * Format: one FACT per `<slug>.md`, Claude-Code AutoMemory frontmatter
14
+ * (`references/memory-format.md`). A malformed / partial entry is SKIPPED (never
15
+ * throws) so one bad file can't blind a run.
16
+ */
17
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
18
+ import { join } from "node:path";
19
+ import {
20
+ Lifecycle,
21
+ MemoryType,
22
+ type LifecycleValue,
23
+ type MemoryTypeValue,
24
+ } from "./append.ts";
25
+
26
+ export interface ParsedMemoryEntry {
27
+ slug: string;
28
+ description: string;
29
+ type: MemoryTypeValue;
30
+ lifecycle: LifecycleValue;
31
+ created: string;
32
+ body: string;
33
+ }
34
+
35
+ const LIFECYCLE_VALUES = new Set<string>(Object.values(Lifecycle));
36
+ const TYPE_VALUES = new Set<string>(Object.values(MemoryType));
37
+
38
+ /**
39
+ * Parse ONE `<slug>.md` entry (frontmatter + body). Returns null on a malformed /
40
+ * partial entry (missing frontmatter, unknown type/lifecycle, absent date) — a bad
41
+ * file is SKIPPED, never fatal. PURE — string in, entry out. `fallbackSlug` is the
42
+ * file stem, used when the `name:` field is absent.
43
+ */
44
+ export function parseMemoryEntry(text: string, fallbackSlug: string): ParsedMemoryEntry | null {
45
+ const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(text);
46
+ if (m === null) return null;
47
+ const front = m[1] ?? "";
48
+ const body = (m[2] ?? "").trim();
49
+
50
+ const scalar = (key: string): string | undefined => {
51
+ // top-level `key: value` OR nested ` key: value` (metadata block).
52
+ const re = new RegExp(`^\\s*${key}:\\s*(.+?)\\s*$`, "m");
53
+ const mm = re.exec(front);
54
+ return mm ? (mm[1] as string).trim() : undefined;
55
+ };
56
+
57
+ const slug = scalar("name") ?? fallbackSlug;
58
+ const description = scalar("description") ?? "";
59
+ const type = scalar("type");
60
+ const lifecycle = scalar("lifecycle");
61
+ const created = scalar("created");
62
+
63
+ if (type === undefined || !TYPE_VALUES.has(type)) return null;
64
+ if (lifecycle === undefined || !LIFECYCLE_VALUES.has(lifecycle)) return null;
65
+ if (created === undefined || !/^\d{4}-\d{2}-\d{2}$/.test(created)) return null;
66
+
67
+ return {
68
+ slug,
69
+ description,
70
+ type: type as MemoryTypeValue,
71
+ lifecycle: lifecycle as LifecycleValue,
72
+ created,
73
+ body,
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Keep only entries whose `lifecycle` is in `stages` (the recall filter). PURE.
79
+ * For the evaluator run start: `stages = [Evaluate, General]`.
80
+ */
81
+ export function filterByLifecycle(
82
+ entries: ParsedMemoryEntry[],
83
+ stages: LifecycleValue[],
84
+ ): ParsedMemoryEntry[] {
85
+ const want = new Set<string>(stages);
86
+ return entries.filter((e) => want.has(e.lifecycle));
87
+ }
88
+
89
+ /** The default recall filter for an EVALUATE run: {evaluate, general}. */
90
+ export const EVALUATE_RECALL: LifecycleValue[] = [Lifecycle.Evaluate, Lifecycle.General];
91
+
92
+ export interface ReadMemoryResult {
93
+ exists: boolean;
94
+ /** entries matching the lifecycle filter, sorted by slug (deterministic). */
95
+ entries: ParsedMemoryEntry[];
96
+ /** files that failed to parse (skipped) — surfaced for honesty, never fatal. */
97
+ skipped: string[];
98
+ }
99
+
100
+ /**
101
+ * Read `<memoryDir>/*.md` (excluding the `MEMORY.md` index), parse each, and
102
+ * return the entries matching `stages` (default = EVALUATE_RECALL). A missing dir
103
+ * → `{ exists:false, entries:[] }`. A malformed file is SKIPPED (listed in
104
+ * `skipped`). Deterministic: entries sorted by slug. The ONLY impure edge.
105
+ */
106
+ export function readMemoryDir(
107
+ memoryDir: string,
108
+ stages: LifecycleValue[] = EVALUATE_RECALL,
109
+ ): ReadMemoryResult {
110
+ if (!existsSync(memoryDir)) return { exists: false, entries: [], skipped: [] };
111
+
112
+ const files = readdirSync(memoryDir)
113
+ .filter((f) => f.endsWith(".md") && f !== "MEMORY.md")
114
+ .sort();
115
+
116
+ const parsed: ParsedMemoryEntry[] = [];
117
+ const skipped: string[] = [];
118
+ for (const f of files) {
119
+ const stem = f.replace(/\.md$/, "");
120
+ let text: string;
121
+ try {
122
+ text = readFileSync(join(memoryDir, f), "utf8");
123
+ } catch {
124
+ skipped.push(f);
125
+ continue;
126
+ }
127
+ const entry = parseMemoryEntry(text, stem);
128
+ if (entry === null) {
129
+ skipped.push(f);
130
+ continue;
131
+ }
132
+ parsed.push(entry);
133
+ }
134
+
135
+ return { exists: true, entries: filterByLifecycle(parsed, stages), skipped };
136
+ }
137
+
138
+ /**
139
+ * Render the recalled entries as a compact operator-preference context block for
140
+ * injection at run start (one bullet per entry: type · slug · description). PURE.
141
+ * EMPTY string when nothing recalled (a run with no AutoMemory is byte-identical
142
+ * to the legacy no-memory path).
143
+ */
144
+ export function renderRecallContext(entries: ParsedMemoryEntry[]): string {
145
+ if (entries.length === 0) return "";
146
+ const bullets = entries
147
+ .map((e) => `- [${e.type}] ${e.slug} — ${e.description}`)
148
+ .join("\n");
149
+ return `AutoMemory (operator preferences · evaluate + general):\n${bullets}`;
150
+ }
151
+
152
+ // ── CLI — thin wrapper (print the recalled entries for a project root) ─────────
153
+ // bun scripts/memory/read.ts [project-root]
154
+
155
+ function memoryDirFor(projectRoot: string): string {
156
+ return join(projectRoot, ".mutagent", "memory");
157
+ }
158
+
159
+ const isMain =
160
+ typeof import.meta !== "undefined" &&
161
+ (import.meta as unknown as { main?: boolean }).main === true;
162
+ if (isMain) {
163
+ const argv = typeof Bun !== "undefined" ? Bun.argv : process.argv;
164
+ const projectRoot = argv[2] ?? process.cwd();
165
+ const result = readMemoryDir(memoryDirFor(projectRoot));
166
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
167
+ process.exit(0);
168
+ }
@@ -0,0 +1,232 @@
1
+ /**
2
+ * scripts/persist-eval-criteria.ts — the EVAL-LEG on-disk WRITER (Wave-2 FU57 · KP-003).
3
+ * ---------------------------------------------------------------------------
4
+ * The IO half of the eval-leg reconcile. `sync-eval-criteria.ts` COMPUTES the grown
5
+ * criteria set as DATA (`reconcileEvalCriteria` — pure upsert-by-id, monotonic, never
6
+ * drops); it never touches disk. This module is the deterministic WRITER the evaluator
7
+ * SESSION calls to PERSIST that computed set back to the located eval-suite criteria
8
+ * artifact — the write that bumps the artifact's freshness and thereby returns the eval
9
+ * leg of `#sync-spec` to `in-sync` (the builder freshness probe reads the artifact's
10
+ * mtime / `updatedAt`; a fresh write makes the eval criteria as new as the amended impl).
11
+ *
12
+ * SEPARATION OF CONCERNS (mirrors `artifact-paths.ts` + `aggregate-discover.ts` doing IO
13
+ * while `living-suite.ts` stays pure): the reconcile COMPUTE is pure/C-PIN; this WRITE is
14
+ * the IO layer. The SERIALIZATION here is still deterministic (stable key order, no clock
15
+ * embedded unless the caller passes an explicit `updatedAt`), so a persisted artifact
16
+ * round-trips byte-faithful.
17
+ *
18
+ * JUDGE-ONLY PRESERVED (EV-051): this file writes CRITERIA (the evaluator maintaining its
19
+ * own eval-suite / code-quality criteria set) — it NEVER scores a subject, NEVER decides a
20
+ * pass/fail, and NEVER dispatches an agent (Model-B: code is a deterministic writer; the
21
+ * reconcile REASONING is the ai-architect's, session-dispatched).
22
+ *
23
+ * LOCATION + FORMAT (mirror the living-suite persistence; FLAGGED-for-operator, see
24
+ * `EVAL_CRITERIA_ARTIFACT_FILENAMES`): the artifact lands under the evaluator's namespaced
25
+ * `.mutagent/evaluator/living-suite/` root (`artifact-paths.ts` `livingSuiteDir`, auto-
26
+ * gitignored, no-spillover-guarded) as one JSON file per LEG — the same dir + extension the
27
+ * builder `check-sync-spec.ts` `locateEvalCriteria` auto-discovers.
28
+ */
29
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
30
+ import { dirname, join } from "node:path";
31
+ import { type Static, Type } from "@sinclair/typebox";
32
+ import { Value } from "@sinclair/typebox/value";
33
+
34
+ import { assertUnderRoot, livingSuiteDir } from "./artifact-paths.ts";
35
+ import {
36
+ EvalCriterionSchema,
37
+ EvalLegKind,
38
+ reconcileEvalCriteria,
39
+ type EvalCriteriaReconcileRequest,
40
+ type EvalCriteriaReconcileResult,
41
+ type EvalCriterion,
42
+ type EvalLegKindValue,
43
+ } from "./sync-eval-criteria.ts";
44
+
45
+ // ── the on-disk artifact shape (mirror LivingSuite `{ …, provenance }`) ───────
46
+
47
+ /**
48
+ * The persisted eval-criteria artifact — one per LEG. Mirrors the living-suite shape
49
+ * (a keyed collection + provenance), specialized to the reconcile result: the maintained
50
+ * `criteria` set, the reconcile `provenance` counters, and an OPTIONAL `updatedAt`
51
+ * freshness marker. `updatedAt` is the ONE clock-bearing field and it is NEVER generated
52
+ * here — the caller (the session, Model-B) passes it when it wants a content-level
53
+ * freshness stamp the builder probe's `parseEvalUpdatedAt` can read; omitted, freshness
54
+ * rides on the file's mtime alone (write bumps it). `additionalProperties: false` keeps the
55
+ * header tight while each criterion stays forward-parsing (EvalCriterionSchema is open).
56
+ */
57
+ export const EvalCriteriaArtifactSchema = Type.Object(
58
+ {
59
+ subjectId: Type.String({ minLength: 1 }),
60
+ leg: Type.Union([
61
+ Type.Literal(EvalLegKind.EvalSuite),
62
+ Type.Literal(EvalLegKind.CodeQuality),
63
+ ]),
64
+ criteria: Type.Array(EvalCriterionSchema),
65
+ provenance: Type.Object(
66
+ { added: Type.Number(), updated: Type.Number(), total: Type.Number() },
67
+ { additionalProperties: false },
68
+ ),
69
+ updatedAt: Type.Optional(Type.String({ minLength: 1 })),
70
+ },
71
+ { additionalProperties: false },
72
+ );
73
+ export type EvalCriteriaArtifact = Static<typeof EvalCriteriaArtifactSchema>;
74
+
75
+ /**
76
+ * FLAGGED-for-operator: the per-leg artifact FILENAME under `.mutagent/evaluator/living-suite/`.
77
+ * The sensible default that mirrors the living-suite location AND the builder probe's
78
+ * conventional fallback names (`eval-criteria` / `code-quality-criteria`), one file per leg
79
+ * so the two legs never collide. Both are `.json` under the dir `check-sync-spec.ts`
80
+ * `locateEvalCriteria` walks (`*.{yaml,yml,json}`), so a written artifact is auto-discovered
81
+ * as the eval-leg freshness anchor with no extra wiring. (A workspace evaluates ONE subject,
82
+ * so only its leg's file exists; multi-subject-per-workspace would want a `<subjectId>/`
83
+ * sub-dir — deferred, flagged.)
84
+ */
85
+ export const EVAL_CRITERIA_ARTIFACT_FILENAMES: Readonly<Record<EvalLegKindValue, string>> = {
86
+ [EvalLegKind.EvalSuite]: "eval-suite.criteria.json",
87
+ [EvalLegKind.CodeQuality]: "code-quality.criteria.json",
88
+ };
89
+
90
+ /**
91
+ * Resolve the located eval-criteria artifact path for a leg:
92
+ * `<cwd>/.mutagent/evaluator/living-suite/<leg>.criteria.json`. Routes through the
93
+ * `artifact-paths.ts` no-spillover guard (`assertUnderRoot`), so the writer can NEVER
94
+ * escape the evaluator's namespaced root. `cwd` passed in (pure path construction).
95
+ */
96
+ export function evalCriteriaArtifactPath(leg: EvalLegKindValue, cwd?: string): string {
97
+ return assertUnderRoot(join(livingSuiteDir(cwd), EVAL_CRITERIA_ARTIFACT_FILENAMES[leg]), cwd);
98
+ }
99
+
100
+ // ── serialize / build (pure, deterministic — no clock) ───────────────────────
101
+
102
+ /** Build the on-disk artifact from a reconcile RESULT. Pure. `updatedAt` passed in. */
103
+ export function evalCriteriaArtifactFromResult(
104
+ result: EvalCriteriaReconcileResult,
105
+ updatedAt?: string,
106
+ ): EvalCriteriaArtifact {
107
+ return {
108
+ subjectId: result.subjectId,
109
+ leg: result.leg,
110
+ criteria: result.criteria,
111
+ provenance: result.provenance,
112
+ ...(updatedAt !== undefined ? { updatedAt } : {}),
113
+ };
114
+ }
115
+
116
+ /**
117
+ * Serialize an artifact to its on-disk JSON — DETERMINISTIC: explicit key order, 2-space
118
+ * indent, trailing newline. Same artifact → byte-identical string (round-trip faithful);
119
+ * no clock unless the artifact already carries a caller-supplied `updatedAt`.
120
+ */
121
+ export function serializeEvalCriteriaArtifact(artifact: EvalCriteriaArtifact): string {
122
+ const ordered: EvalCriteriaArtifact = {
123
+ subjectId: artifact.subjectId,
124
+ leg: artifact.leg,
125
+ criteria: artifact.criteria,
126
+ provenance: artifact.provenance,
127
+ ...(artifact.updatedAt !== undefined ? { updatedAt: artifact.updatedAt } : {}),
128
+ };
129
+ return `${JSON.stringify(ordered, null, 2)}\n`;
130
+ }
131
+
132
+ /** Guarded parse of a persisted artifact. THROWS with the first schema error. PURE. */
133
+ export function parseEvalCriteriaArtifact(value: unknown): EvalCriteriaArtifact {
134
+ if (!Value.Check(EvalCriteriaArtifactSchema, value)) {
135
+ const first = [...Value.Errors(EvalCriteriaArtifactSchema, value)][0];
136
+ throw new Error(
137
+ `parseEvalCriteriaArtifact: schema violation at '${first?.path ?? "(root)"}': ` +
138
+ `${first?.message ?? "invalid eval-criteria artifact"}`,
139
+ );
140
+ }
141
+ return value;
142
+ }
143
+
144
+ // ── the WRITER + reader (the IO layer) ───────────────────────────────────────
145
+
146
+ /** The result of a persist: WHERE it landed + WHAT was written (artifact + bytes). */
147
+ export interface PersistEvalCriteriaResult {
148
+ /** the located artifact path the criteria were written to. */
149
+ path: string;
150
+ /** the artifact that was serialized. */
151
+ artifact: EvalCriteriaArtifact;
152
+ /** the exact bytes written (for a byte-faithful round-trip assertion). */
153
+ json: string;
154
+ }
155
+
156
+ /**
157
+ * PERSIST a reconcile result's `criteria` back to the located eval-suite criteria artifact
158
+ * — the WRITE that returns the eval leg to `in-sync`. Resolves the per-leg path under
159
+ * `.mutagent/evaluator/living-suite/` (no-spillover-guarded via `artifact-paths.ts`),
160
+ * ensures the dir, and writes the deterministic JSON. Handles BOTH legs by `result.leg`:
161
+ * the eval-suite leg (agent/skill/composite subject) and the code-quality leg (a code
162
+ * subject, incl. an operator-overridden code-quality set). The freshness bump is the file
163
+ * write itself (mtime advances → the builder probe reads the eval leg as fresh); pass
164
+ * `options.updatedAt` (ISO 8601) to ALSO stamp a content-level freshness marker the probe's
165
+ * `parseEvalUpdatedAt` reads. IO — NOT pure (that is its job); serialization is deterministic.
166
+ */
167
+ export function persistEvalCriteria(
168
+ result: EvalCriteriaReconcileResult,
169
+ options: { cwd?: string; updatedAt?: string } = {},
170
+ ): PersistEvalCriteriaResult {
171
+ const artifact = evalCriteriaArtifactFromResult(result, options.updatedAt);
172
+ const path = evalCriteriaArtifactPath(result.leg, options.cwd);
173
+ const json = serializeEvalCriteriaArtifact(artifact);
174
+ mkdirSync(dirname(path), { recursive: true });
175
+ writeFileSync(path, json);
176
+ return { path, artifact, json };
177
+ }
178
+
179
+ /** Read + validate a persisted artifact (round-trip). THROWS on a schema violation. */
180
+ export function readEvalCriteriaArtifact(path: string): EvalCriteriaArtifact {
181
+ return parseEvalCriteriaArtifact(JSON.parse(readFileSync(path, "utf8")) as unknown);
182
+ }
183
+
184
+ /**
185
+ * Load the CURRENTLY-persisted criteria for a leg (the `existing` set the next reconcile
186
+ * grows). Returns `[]` when no artifact exists yet (the cold / first-reconcile case) so a
187
+ * caller can feed it straight into an `EvalCriteriaReconcileRequest.existing`. Reads only.
188
+ */
189
+ export function loadExistingEvalCriteria(leg: EvalLegKindValue, cwd?: string): EvalCriterion[] {
190
+ const path = evalCriteriaArtifactPath(leg, cwd);
191
+ if (!existsSync(path)) return [];
192
+ return readEvalCriteriaArtifact(path).criteria;
193
+ }
194
+
195
+ /**
196
+ * The eval-criteria artifact's effective freshness epoch (seconds) — the evaluator-side
197
+ * MIRROR of the builder `check-sync-spec.ts` eval-leg compare: `max(updatedAt, mtime)`
198
+ * (git omitted — kept in-package + git-independent). `null` when the artifact is absent.
199
+ * Feed this as `evalCriteriaEpoch` to `flagEvalLegDrift` to confirm a fresh write closed
200
+ * the loop (`in-sync`). Reads mtime (IO).
201
+ */
202
+ export function evalCriteriaEffectiveEpoch(path: string): number | null {
203
+ if (!existsSync(path)) return null;
204
+ const epochs: number[] = [];
205
+ try {
206
+ const parsed = readEvalCriteriaArtifact(path);
207
+ if (parsed.updatedAt !== undefined) {
208
+ const ms = Date.parse(parsed.updatedAt);
209
+ if (Number.isFinite(ms)) epochs.push(Math.floor(ms / 1000));
210
+ }
211
+ } catch {
212
+ // a corrupt artifact still has an mtime — fall back to it for freshness.
213
+ }
214
+ epochs.push(Math.floor(statSync(path).mtimeMs / 1000));
215
+ return Math.max(...epochs);
216
+ }
217
+
218
+ /**
219
+ * Convenience for the session: COMPUTE the reconcile (pure) THEN PERSIST it (IO) in one
220
+ * call — the exact "reconcile → write → in-sync" step the `#sync-spec` eval leg performs.
221
+ * Still Model-B: the criteria DELTA (`request.proposed`) is the ai-architect's reasoning;
222
+ * this only applies it deterministically and writes it. Returns the compute result + the
223
+ * persist result together.
224
+ */
225
+ export function reconcileAndPersistEvalCriteria(
226
+ request: EvalCriteriaReconcileRequest,
227
+ options: { cwd?: string; updatedAt?: string } = {},
228
+ ): { result: EvalCriteriaReconcileResult; persisted: PersistEvalCriteriaResult } {
229
+ const result = reconcileEvalCriteria(request);
230
+ const persisted = persistEvalCriteria(result, options);
231
+ return { result, persisted };
232
+ }