@aperant/framework 0.17.0 → 0.20.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 (242) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/agents/apt-executor.md +6 -0
  3. package/agents/apt-planner.md +3 -2
  4. package/bin/features-reconcile-check.mjs +77 -0
  5. package/dist/cli/artifacts/self-stage.d.mts.map +1 -1
  6. package/dist/cli/artifacts/self-stage.mjs +2 -1
  7. package/dist/cli/artifacts/self-stage.mjs.map +1 -1
  8. package/dist/cli/cli-wrappers/features-reconcile.d.mts +2 -0
  9. package/dist/cli/cli-wrappers/features-reconcile.d.mts.map +1 -0
  10. package/dist/cli/cli-wrappers/features-reconcile.mjs +9 -0
  11. package/dist/cli/cli-wrappers/features-reconcile.mjs.map +1 -0
  12. package/dist/cli/commands/ci-watch.mjs +49 -2
  13. package/dist/cli/commands/ci-watch.mjs.map +1 -1
  14. package/dist/cli/commands/commit.mjs +3 -3
  15. package/dist/cli/commands/commit.mjs.map +1 -1
  16. package/dist/cli/commands/event.mjs +16 -16
  17. package/dist/cli/commands/event.mjs.map +1 -1
  18. package/dist/cli/commands/features-reconcile.d.mts +2 -0
  19. package/dist/cli/commands/features-reconcile.d.mts.map +1 -0
  20. package/dist/cli/commands/features-reconcile.mjs +143 -0
  21. package/dist/cli/commands/features-reconcile.mjs.map +1 -0
  22. package/dist/cli/commands/health-check.d.mts +2 -2
  23. package/dist/cli/commands/health-check.mjs +2 -2
  24. package/dist/cli/commands/merge-integrate.mjs +3 -3
  25. package/dist/cli/commands/merge-integrate.mjs.map +1 -1
  26. package/dist/cli/commands/produce.d.mts +9 -0
  27. package/dist/cli/commands/produce.d.mts.map +1 -0
  28. package/dist/cli/commands/produce.mjs +1345 -0
  29. package/dist/cli/commands/produce.mjs.map +1 -0
  30. package/dist/cli/commands/task.d.mts +16 -1
  31. package/dist/cli/commands/task.d.mts.map +1 -1
  32. package/dist/cli/commands/task.mjs +434 -266
  33. package/dist/cli/commands/task.mjs.map +1 -1
  34. package/dist/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
  35. package/dist/cli/coordination/auto-emit-artifact-ready.mjs.map +1 -1
  36. package/dist/cli/coordination/event-schema.d.mts +5 -3
  37. package/dist/cli/coordination/event-schema.d.mts.map +1 -1
  38. package/dist/cli/coordination/event-schema.mjs +245 -21
  39. package/dist/cli/coordination/event-schema.mjs.map +1 -1
  40. package/dist/cli/coordination/store.d.mts +2 -2
  41. package/dist/cli/coordination/store.mjs +4 -4
  42. package/dist/cli/coordination/store.mjs.map +1 -1
  43. package/dist/cli/dispatch.d.mts.map +1 -1
  44. package/dist/cli/dispatch.mjs +4 -2
  45. package/dist/cli/dispatch.mjs.map +1 -1
  46. package/dist/cli/features/area-shape.d.mts +11 -0
  47. package/dist/cli/features/area-shape.d.mts.map +1 -0
  48. package/dist/cli/features/area-shape.mjs +141 -0
  49. package/dist/cli/features/area-shape.mjs.map +1 -0
  50. package/dist/cli/features/delta.d.mts +78 -0
  51. package/dist/cli/features/delta.d.mts.map +1 -0
  52. package/dist/cli/features/delta.mjs +591 -0
  53. package/dist/cli/features/delta.mjs.map +1 -0
  54. package/dist/cli/features/reconcile.d.mts +236 -0
  55. package/dist/cli/features/reconcile.d.mts.map +1 -0
  56. package/dist/cli/features/reconcile.mjs +1126 -0
  57. package/dist/cli/features/reconcile.mjs.map +1 -0
  58. package/dist/cli/features/surface-map.d.mts +63 -0
  59. package/dist/cli/features/surface-map.d.mts.map +1 -0
  60. package/dist/cli/features/surface-map.mjs +191 -0
  61. package/dist/cli/features/surface-map.mjs.map +1 -0
  62. package/dist/cli/{commands/features-audit.d.mts → features/write-root.d.mts} +4 -3
  63. package/dist/cli/features/write-root.d.mts.map +1 -0
  64. package/dist/cli/features/write-root.mjs +137 -0
  65. package/dist/cli/features/write-root.mjs.map +1 -0
  66. package/dist/cli/gate/gates/features-reconciled.d.mts +36 -0
  67. package/dist/cli/gate/gates/features-reconciled.d.mts.map +1 -0
  68. package/dist/cli/gate/gates/features-reconciled.mjs +67 -0
  69. package/dist/cli/gate/gates/features-reconciled.mjs.map +1 -0
  70. package/dist/cli/gate/gates/index.mjs +1 -0
  71. package/dist/cli/gate/gates/index.mjs.map +1 -1
  72. package/dist/cli/help.d.mts.map +1 -1
  73. package/dist/cli/help.mjs +31 -1
  74. package/dist/cli/help.mjs.map +1 -1
  75. package/dist/cli/install/legacy-paths.d.mts.map +1 -1
  76. package/dist/cli/install/legacy-paths.mjs +2 -0
  77. package/dist/cli/install/legacy-paths.mjs.map +1 -1
  78. package/dist/cli/produce/blind-probe.d.mts +85 -0
  79. package/dist/cli/produce/blind-probe.d.mts.map +1 -0
  80. package/dist/cli/produce/blind-probe.mjs +217 -0
  81. package/dist/cli/produce/blind-probe.mjs.map +1 -0
  82. package/dist/cli/produce/claim.d.mts +188 -0
  83. package/dist/cli/produce/claim.d.mts.map +1 -0
  84. package/dist/cli/produce/claim.mjs +518 -0
  85. package/dist/cli/produce/claim.mjs.map +1 -0
  86. package/dist/cli/produce/done-gate.d.mts +87 -0
  87. package/dist/cli/produce/done-gate.d.mts.map +1 -0
  88. package/dist/cli/produce/done-gate.mjs +200 -0
  89. package/dist/cli/produce/done-gate.mjs.map +1 -0
  90. package/dist/cli/produce/events.d.mts +77 -0
  91. package/dist/cli/produce/events.d.mts.map +1 -0
  92. package/dist/cli/produce/events.mjs +126 -0
  93. package/dist/cli/produce/events.mjs.map +1 -0
  94. package/dist/cli/produce/evidence-oracle.d.mts +63 -0
  95. package/dist/cli/produce/evidence-oracle.d.mts.map +1 -0
  96. package/dist/cli/produce/evidence-oracle.mjs +122 -0
  97. package/dist/cli/produce/evidence-oracle.mjs.map +1 -0
  98. package/dist/cli/produce/ledger.d.mts +140 -0
  99. package/dist/cli/produce/ledger.d.mts.map +1 -0
  100. package/dist/cli/produce/ledger.mjs +272 -0
  101. package/dist/cli/produce/ledger.mjs.map +1 -0
  102. package/dist/cli/produce/probe-family.d.mts +53 -0
  103. package/dist/cli/produce/probe-family.d.mts.map +1 -0
  104. package/dist/cli/produce/probe-family.mjs +160 -0
  105. package/dist/cli/produce/probe-family.mjs.map +1 -0
  106. package/dist/cli/produce/projection.d.mts +55 -0
  107. package/dist/cli/produce/projection.d.mts.map +1 -0
  108. package/dist/cli/produce/projection.mjs +97 -0
  109. package/dist/cli/produce/projection.mjs.map +1 -0
  110. package/dist/cli/produce/run-id.d.mts +42 -0
  111. package/dist/cli/produce/run-id.d.mts.map +1 -0
  112. package/dist/cli/produce/run-id.mjs +79 -0
  113. package/dist/cli/produce/run-id.mjs.map +1 -0
  114. package/dist/cli/produce/saga.d.mts +180 -0
  115. package/dist/cli/produce/saga.d.mts.map +1 -0
  116. package/dist/cli/produce/saga.mjs +290 -0
  117. package/dist/cli/produce/saga.mjs.map +1 -0
  118. package/dist/cli/produce/scheduler.d.mts +165 -0
  119. package/dist/cli/produce/scheduler.d.mts.map +1 -0
  120. package/dist/cli/produce/scheduler.mjs +399 -0
  121. package/dist/cli/produce/scheduler.mjs.map +1 -0
  122. package/dist/cli/produce/setpoint.d.mts +52 -0
  123. package/dist/cli/produce/setpoint.d.mts.map +1 -0
  124. package/dist/cli/produce/setpoint.mjs +113 -0
  125. package/dist/cli/produce/setpoint.mjs.map +1 -0
  126. package/dist/cli/produce/verification-ttl.d.mts +75 -0
  127. package/dist/cli/produce/verification-ttl.d.mts.map +1 -0
  128. package/dist/cli/produce/verification-ttl.mjs +169 -0
  129. package/dist/cli/produce/verification-ttl.mjs.map +1 -0
  130. package/dist/cli/release-notes/ship-autodraft.mjs +2 -2
  131. package/dist/cli/roadmap/{conductor-view.d.mts → showrunner-view.d.mts} +3 -3
  132. package/dist/cli/roadmap/showrunner-view.d.mts.map +1 -0
  133. package/dist/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +7 -7
  134. package/dist/cli/roadmap/showrunner-view.mjs.map +1 -0
  135. package/dist/cli/variant/gallery.d.mts.map +1 -1
  136. package/dist/cli/variant/gallery.mjs +7 -3
  137. package/dist/cli/variant/gallery.mjs.map +1 -1
  138. package/dist/plugin/.claude-plugin/plugin.json +2 -1
  139. package/dist/plugin/agents/apt-executor.md +6 -0
  140. package/dist/plugin/agents/apt-planner.md +3 -2
  141. package/dist/plugin/skills/apt/SKILL.md +112 -38
  142. package/dist/plugin/skills/apt-close-task/SKILL.md +2 -2
  143. package/dist/plugin/skills/apt-debug/SKILL.md +22 -24
  144. package/dist/plugin/skills/apt-execute/SKILL.md +35 -26
  145. package/dist/plugin/skills/apt-fan-out/SKILL.md +4 -4
  146. package/dist/plugin/skills/apt-handoff/SKILL.md +1 -1
  147. package/dist/plugin/skills/apt-mockup/SKILL.md +1 -1
  148. package/dist/plugin/skills/apt-plan/SKILL.md +5 -5
  149. package/dist/plugin/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
  150. package/dist/plugin/skills/apt-produce/SKILL.md +606 -0
  151. package/dist/plugin/skills/apt-quick/SKILL.md +27 -33
  152. package/dist/plugin/skills/apt-review/SKILL.md +14 -11
  153. package/dist/plugin/skills/apt-run/SKILL.md +132 -3
  154. package/dist/plugin/skills/apt-ship/SKILL.md +29 -5
  155. package/dist/plugin/skills/apt-spar/SKILL.md +5 -3
  156. package/dist/plugin/skills/apt-watch-ci/SKILL.md +6 -4
  157. package/dist/schemas/feature-registry.d.ts.map +1 -1
  158. package/dist/schemas/feature-registry.js +34 -3
  159. package/dist/schemas/feature-registry.js.map +1 -1
  160. package/dist/types/config.d.ts +8 -5
  161. package/dist/types/config.d.ts.map +1 -1
  162. package/package.json +4 -4
  163. package/prompts/{conductor-framework-context.md → showrunner-framework-context.md} +1 -1
  164. package/prompts/{conductor-status-check.md → showrunner-status-check.md} +1 -1
  165. package/prompts/{conductor-sub-agent.md → showrunner-sub-agent.md} +6 -6
  166. package/prompts/{conductor-system.md → showrunner-system.md} +8 -8
  167. package/skills/apt/SKILL.md +112 -38
  168. package/skills/apt-close-task/SKILL.md +2 -2
  169. package/skills/apt-debug/SKILL.md +22 -24
  170. package/skills/apt-execute/SKILL.md +35 -26
  171. package/skills/apt-fan-out/SKILL.md +4 -4
  172. package/skills/apt-handoff/SKILL.md +1 -1
  173. package/skills/apt-mockup/SKILL.md +1 -1
  174. package/skills/apt-plan/SKILL.md +5 -5
  175. package/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
  176. package/skills/apt-produce/SKILL.md +606 -0
  177. package/skills/apt-quick/SKILL.md +27 -33
  178. package/skills/apt-review/SKILL.md +14 -11
  179. package/skills/apt-run/SKILL.md +132 -3
  180. package/skills/apt-ship/SKILL.md +29 -5
  181. package/skills/apt-spar/SKILL.md +5 -3
  182. package/skills/apt-watch-ci/SKILL.md +6 -4
  183. package/src/cli/artifacts/self-stage.mjs +2 -1
  184. package/src/cli/cli-wrappers/features-reconcile.mjs +9 -0
  185. package/src/cli/commands/ci-watch.mjs +51 -2
  186. package/src/cli/commands/commit.mjs +3 -3
  187. package/src/cli/commands/event.mjs +16 -16
  188. package/src/cli/commands/features-reconcile.mjs +157 -0
  189. package/src/cli/commands/health-check.mjs +2 -2
  190. package/src/cli/commands/merge-integrate.mjs +3 -3
  191. package/src/cli/commands/produce.mjs +1466 -0
  192. package/src/cli/commands/task.mjs +482 -285
  193. package/src/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
  194. package/src/cli/coordination/event-schema.d.ts +4 -2
  195. package/src/cli/coordination/event-schema.mjs +276 -21
  196. package/src/cli/coordination/store.mjs +4 -4
  197. package/src/cli/dispatch.mjs +4 -2
  198. package/src/cli/features/area-shape.mjs +140 -0
  199. package/src/cli/features/delta.mjs +625 -0
  200. package/src/cli/features/reconcile.mjs +1169 -0
  201. package/src/cli/features/surface-map.mjs +192 -0
  202. package/src/cli/features/write-root.mjs +140 -0
  203. package/src/cli/gate/gates/features-reconciled.mjs +70 -0
  204. package/src/cli/gate/gates/index.mjs +1 -0
  205. package/src/cli/help.mjs +31 -1
  206. package/src/cli/install/legacy-paths.mjs +2 -0
  207. package/src/cli/produce/blind-probe.mjs +245 -0
  208. package/src/cli/produce/claim.mjs +543 -0
  209. package/src/cli/produce/done-gate.mjs +238 -0
  210. package/src/cli/produce/events.mjs +131 -0
  211. package/src/cli/produce/evidence-oracle.mjs +133 -0
  212. package/src/cli/produce/ledger.mjs +284 -0
  213. package/src/cli/produce/probe-family.mjs +168 -0
  214. package/src/cli/produce/projection.mjs +105 -0
  215. package/src/cli/produce/run-id.mjs +84 -0
  216. package/src/cli/produce/saga.mjs +303 -0
  217. package/src/cli/produce/scheduler.mjs +423 -0
  218. package/src/cli/produce/setpoint.mjs +122 -0
  219. package/src/cli/produce/verification-ttl.mjs +191 -0
  220. package/src/cli/release-notes/ship-autodraft.mjs +2 -2
  221. package/src/cli/roadmap/showrunner-view.d.ts +10 -0
  222. package/src/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +6 -6
  223. package/src/cli/variant/gallery.mjs +7 -3
  224. package/templates/aperant-claude-md-appendix.md +2 -2
  225. package/workflows/scan-features.md +17 -11
  226. package/dist/cli/cli-wrappers/features-audit.d.mts +0 -2
  227. package/dist/cli/cli-wrappers/features-audit.d.mts.map +0 -1
  228. package/dist/cli/cli-wrappers/features-audit.mjs +0 -8
  229. package/dist/cli/cli-wrappers/features-audit.mjs.map +0 -1
  230. package/dist/cli/commands/features-audit.d.mts.map +0 -1
  231. package/dist/cli/commands/features-audit.mjs +0 -293
  232. package/dist/cli/commands/features-audit.mjs.map +0 -1
  233. package/dist/cli/features/registry-audit.d.mts +0 -56
  234. package/dist/cli/features/registry-audit.d.mts.map +0 -1
  235. package/dist/cli/features/registry-audit.mjs +0 -264
  236. package/dist/cli/features/registry-audit.mjs.map +0 -1
  237. package/dist/cli/roadmap/conductor-view.d.mts.map +0 -1
  238. package/dist/cli/roadmap/conductor-view.mjs.map +0 -1
  239. package/src/cli/cli-wrappers/features-audit.mjs +0 -8
  240. package/src/cli/commands/features-audit.mjs +0 -302
  241. package/src/cli/features/registry-audit.mjs +0 -254
  242. package/src/cli/roadmap/conductor-view.d.ts +0 -10
@@ -0,0 +1,200 @@
1
+ /**
2
+ * @internal
3
+ * produce/done-gate.mjs — the real two-gate done adjudication + canary (M2,
4
+ * ID-M2-04 / AC8-AC11).
5
+ *
6
+ * A milestone flips to `done` ONLY when the VISIBLE oracle AND the BLIND probe
7
+ * both agree — otherwise it stays open and the reward-hacking canary logs the
8
+ * gap. The Showrunner still cannot self-attest: `done` is reachable ONLY through
9
+ * recorded external evidence + a blind cross-family probe (ID-03 preserved). Any
10
+ * missing / same-family / stale seal fails closed.
11
+ *
12
+ * The CLI is deterministic — it reads recorded evidence (verify-proof's verdict
13
+ * file + the recorded `produce.oracle.judged` / `produce.probe.run` /
14
+ * `produce.probe.frozen` seals) and computes the gate. The (LLM) oracle-judge +
15
+ * probe-run steps are driven cross-family by the skill; the CLI records + gates.
16
+ */
17
+ import { appendProduceEvent, readImplementerFamily, readProduceRunEventsMatching, } from './events.mjs';
18
+ import { prepareOracleInput } from './evidence-oracle.mjs';
19
+ import { normalizeFamily } from './probe-family.mjs';
20
+ import { projectRoadmap, writeProjectionCache } from './projection.mjs';
21
+ /** The last event matching `matchOp` for a milestone, or null. */
22
+ function latestForMilestone(projectDir, runId, milestoneId, matchOp) {
23
+ const events = readProduceRunEventsMatching(projectDir, runId, matchOp);
24
+ let last = null;
25
+ for (const e of events) {
26
+ if (e.data && e.data.milestone_id === milestoneId)
27
+ last = e;
28
+ }
29
+ return last;
30
+ }
31
+ /** Whether any event matching `matchOp` (with a cross-family predicate) exists. */
32
+ function anyForMilestone(projectDir, runId, milestoneId, matchOp, predicate) {
33
+ const events = readProduceRunEventsMatching(projectDir, runId, matchOp);
34
+ return events.some((e) => e.data && e.data.milestone_id === milestoneId && predicate(e.data));
35
+ }
36
+ /**
37
+ * Evaluate the RECORDED gate seals for a milestone (no verify-proof file read —
38
+ * that live half is added by `adjudicateDone`). Pure read.
39
+ *
40
+ * @param {string} projectDir
41
+ * @param {string} runId
42
+ * @param {string} milestoneId
43
+ * @returns {{
44
+ * implementer_family: string | null,
45
+ * oracle_pass_cross_family: boolean,
46
+ * probe_pass_cross_family: boolean,
47
+ * frozen_cross_family: boolean,
48
+ * blind_gate: boolean,
49
+ * }}
50
+ */
51
+ export function evaluateRecordedGates(projectDir, runId, milestoneId) {
52
+ const implementer = readImplementerFamily(projectDir, runId, milestoneId);
53
+ const impl = implementer ? normalizeFamily(implementer) : null;
54
+ const oracle = latestForMilestone(projectDir, runId, milestoneId, (op) => op === 'produce.oracle.judged');
55
+ const oracle_pass_cross_family = !!impl &&
56
+ !!oracle &&
57
+ oracle.data.verdict === 'pass' &&
58
+ normalizeFamily(oracle.data.oracle_family) !== impl;
59
+ const probeRun = latestForMilestone(projectDir, runId, milestoneId, (op) => op === 'produce.probe.run');
60
+ const probe_pass_cross_family = !!impl &&
61
+ !!probeRun &&
62
+ probeRun.data.result === 'pass' &&
63
+ normalizeFamily(probeRun.data.probe_family) !== impl;
64
+ const frozen_cross_family = !!impl &&
65
+ anyForMilestone(projectDir, runId, milestoneId, (op) => op === 'produce.probe.frozen', (d) => normalizeFamily(d.author_family) !== impl);
66
+ return {
67
+ implementer_family: implementer,
68
+ oracle_pass_cross_family,
69
+ probe_pass_cross_family,
70
+ frozen_cross_family,
71
+ blind_gate: probe_pass_cross_family && frozen_cross_family,
72
+ };
73
+ }
74
+ /**
75
+ * Adjudicate a milestone `done` (ID-M2-04). `done` accepted iff:
76
+ * visible_gate = verify-proof verdict === 'approved' AND recorded
77
+ * produce.oracle.judged.verdict === 'pass' with oracle_family !== implementer;
78
+ * blind_gate = recorded produce.probe.run.result === 'pass' with
79
+ * probe_family !== implementer AND a produce.probe.frozen exists with
80
+ * author_family !== implementer.
81
+ * visible && blind → append produce.oracle.verdict{done} +
82
+ * produce.roadmap.milestone_status_changed{done} + refresh the cache → ok.
83
+ * visible && !blind → append produce.oracle.probe_gap → err (stays open).
84
+ * !visible → err not-adjudicable. Absent implementer → err fail-closed.
85
+ *
86
+ * @param {{ projectDir: string, runId: string, milestoneId: string, verdictPath: string }} args
87
+ * @returns {{ ok: true, milestone_id: string, roadmap: object }
88
+ * | { ok: false, reason: string, visible_gate: boolean, blind_gate: boolean, detail?: object }}
89
+ */
90
+ export function adjudicateDone({ projectDir, runId, milestoneId, verdictPath }) {
91
+ const gates = evaluateRecordedGates(projectDir, runId, milestoneId);
92
+ if (!gates.implementer_family)
93
+ return { ok: false, reason: 'no_recorded_implementer', visible_gate: false, blind_gate: false };
94
+ // The live half of the visible gate: verify-proof's v2 verdict === 'approved'.
95
+ const prepared = prepareOracleInput(verdictPath);
96
+ const visible_gate = prepared.approved && gates.oracle_pass_cross_family;
97
+ const blind_gate = gates.blind_gate;
98
+ if (!visible_gate)
99
+ return {
100
+ ok: false,
101
+ reason: 'not_adjudicable',
102
+ visible_gate,
103
+ blind_gate,
104
+ detail: {
105
+ verify_proof_verdict: prepared.verdict,
106
+ verify_proof_approved: prepared.approved,
107
+ oracle_pass_cross_family: gates.oracle_pass_cross_family,
108
+ },
109
+ };
110
+ if (!blind_gate) {
111
+ // Visible passed, blind failed — the reward-hacking near-miss. Log the
112
+ // canary event; the milestone STAYS OPEN (AC9).
113
+ appendProduceEvent(projectDir, 'produce.oracle.probe_gap', {
114
+ run_id: runId,
115
+ milestone_id: milestoneId,
116
+ });
117
+ return {
118
+ ok: false,
119
+ reason: 'probe_gap',
120
+ visible_gate,
121
+ blind_gate,
122
+ detail: {
123
+ probe_pass_cross_family: gates.probe_pass_cross_family,
124
+ frozen_cross_family: gates.frozen_cross_family,
125
+ },
126
+ };
127
+ }
128
+ // Both gates agree — the ONLY path to done. Record the verdict + flip status.
129
+ appendProduceEvent(projectDir, 'produce.oracle.verdict', {
130
+ run_id: runId,
131
+ milestone_id: milestoneId,
132
+ verdict: 'done',
133
+ });
134
+ appendProduceEvent(projectDir, 'produce.roadmap.milestone_status_changed', {
135
+ run_id: runId,
136
+ milestone_id: milestoneId,
137
+ status: 'done',
138
+ });
139
+ const roadmap = writeProjectionCache(projectDir, runId);
140
+ return { ok: true, milestone_id: milestoneId, roadmap };
141
+ }
142
+ /**
143
+ * The reward-hacking canary (ID-M2-06 / AC10): green-on-visible MINUS
144
+ * green-on-blind over the run's milestones, from RECORDED seals. Each
145
+ * `produce.oracle.probe_gap` is one visible-pass + blind-fail near-miss. The
146
+ * metric surfaces the divergence — it does not average it away.
147
+ *
148
+ * @param {string} projectDir
149
+ * @param {string} runId
150
+ * @returns {{
151
+ * run_id: string,
152
+ * green_on_visible: number,
153
+ * green_on_blind: number,
154
+ * gap: number,
155
+ * probe_gap_events: number,
156
+ * per_milestone: Array<{ milestone_id: string, title: string, status: string, visible: boolean, blind: boolean, probe_gaps: number }>,
157
+ * }}
158
+ */
159
+ export function computeCanary(projectDir, runId) {
160
+ const roadmap = projectRoadmap(projectDir, runId);
161
+ const gapEvents = readProduceRunEventsMatching(projectDir, runId, (op) => op === 'produce.oracle.probe_gap');
162
+ const gapCountByMilestone = new Map();
163
+ for (const e of gapEvents) {
164
+ const id = e.data && typeof e.data.milestone_id === 'string' ? e.data.milestone_id : null;
165
+ if (id)
166
+ gapCountByMilestone.set(id, (gapCountByMilestone.get(id) || 0) + 1);
167
+ }
168
+ let greenOnVisible = 0;
169
+ let greenOnBlind = 0;
170
+ const perMilestone = roadmap.milestones.map((m) => {
171
+ const gates = evaluateRecordedGates(projectDir, runId, m.id);
172
+ // The recorded (append-log) half of the visible gate — a recorded
173
+ // cross-family oracle pass. In the production flow the oracle is recorded
174
+ // only after verify-proof `approved` (the skill gates `oracle prepare` on
175
+ // it), so this is the durable visible-gate signal for the canary.
176
+ const visible = gates.oracle_pass_cross_family;
177
+ const blind = gates.blind_gate;
178
+ if (visible)
179
+ greenOnVisible += 1;
180
+ if (blind)
181
+ greenOnBlind += 1;
182
+ return {
183
+ milestone_id: m.id,
184
+ title: m.title,
185
+ status: m.status,
186
+ visible,
187
+ blind,
188
+ probe_gaps: gapCountByMilestone.get(m.id) || 0,
189
+ };
190
+ });
191
+ return {
192
+ run_id: runId,
193
+ green_on_visible: greenOnVisible,
194
+ green_on_blind: greenOnBlind,
195
+ gap: greenOnVisible - greenOnBlind,
196
+ probe_gap_events: gapEvents.length,
197
+ per_milestone: perMilestone,
198
+ };
199
+ }
200
+ //# sourceMappingURL=done-gate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"done-gate.mjs","sourceRoot":"","sources":["../../../src/cli/produce/done-gate.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Append one produce event through the schema-gated, O_APPEND coordination
3
+ * store. `data.run_id` also tags the event's top-level `task` field so the
4
+ * forensic trail is queryable by run. Returns the store's append result (null
5
+ * on schema violation — fail-closed).
6
+ *
7
+ * @param {string} projectDir
8
+ * @param {string} op
9
+ * @param {Record<string, unknown>} data
10
+ */
11
+ export function appendProduceEvent(projectDir: string, op: string, data: Record<string, unknown>): {
12
+ file: string;
13
+ record: {
14
+ t: string;
15
+ agent: any;
16
+ pid: any;
17
+ hostname: any;
18
+ incarnation: any;
19
+ op: any;
20
+ task: any;
21
+ data: any;
22
+ };
23
+ } | null;
24
+ /**
25
+ * Fold the run's produce events matching `opMatches(op)` in chronological
26
+ * (append) order. The window starts at the setpoint's frozen day and ends today
27
+ * (UTC). Events are filtered to `data.run_id === runId`.
28
+ *
29
+ * This is the shared reader over the run's day-bucket window. `matchOp` selects
30
+ * which produce ops to fold — the roadmap projection folds ONLY the
31
+ * `produce.roadmap.*` prefix (see `readProduceEventsForRun`), while the M2
32
+ * oracle/probe consumers select `produce.milestone.implemented` /
33
+ * `produce.probe.*` / `produce.oracle.*`. It reads ONLY the append-only event
34
+ * log — it NEVER opens the frozen probe-content file (probe-blindness, ID-M2-03).
35
+ *
36
+ * @param {string} projectDir
37
+ * @param {string} runId
38
+ * @param {(op: string) => boolean} matchOp
39
+ * @returns {Array<{ op: string, data: Record<string, unknown>, t?: string }>}
40
+ */
41
+ export function readProduceRunEventsMatching(projectDir: string, runId: string, matchOp: (op: string) => boolean): Array<{
42
+ op: string;
43
+ data: Record<string, unknown>;
44
+ t?: string;
45
+ }>;
46
+ /**
47
+ * Fold the run's `produce.roadmap.*` events in chronological (append) order.
48
+ * The projection consumes ONLY this reader, so the roadmap the Showrunner
49
+ * re-reads each tick can never surface a `produce.probe.*` / `produce.oracle.*`
50
+ * event (structural probe-blindness, AC5).
51
+ *
52
+ * @param {string} projectDir
53
+ * @param {string} runId
54
+ * @returns {Array<{ op: string, data: Record<string, unknown>, t?: string }>}
55
+ */
56
+ export function readProduceEventsForRun(projectDir: string, runId: string): Array<{
57
+ op: string;
58
+ data: Record<string, unknown>;
59
+ t?: string;
60
+ }>;
61
+ /**
62
+ * Read the recorded implementer family for a run + milestone from the
63
+ * append-only `produce.milestone.implemented` trail (ID-M2-02 — the recorded
64
+ * disjointness anchor the cross-family rule is enforced against). Returns the
65
+ * LATEST recorded `implementer_family` for the milestone, or null when none is
66
+ * recorded (fail-closed — you cannot enforce disjointness against an unknown
67
+ * implementer).
68
+ *
69
+ * @param {string} projectDir
70
+ * @param {string} runId
71
+ * @param {string} milestoneId
72
+ * @returns {string | null}
73
+ */
74
+ export function readImplementerFamily(projectDir: string, runId: string, milestoneId: string): string | null;
75
+ /** The op-prefix the projection folds. */
76
+ export const ROADMAP_OP_PREFIX: "produce.roadmap.";
77
+ //# sourceMappingURL=events.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.mts","sourceRoot":"","sources":["../../../src/cli/produce/events.mjs"],"names":[],"mappings":"AAsBA;;;;;;;;;GASG;AACH,+CAJW,MAAM,MACN,MAAM,QACN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;SAMjC;AAkBD;;;;;;;;;;;;;;;;GAgBG;AACH,yDALW,MAAM,SACN,MAAM,WACN,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GACrB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB5E;AAED;;;;;;;;;GASG;AACH,oDAJW,MAAM,SACN,MAAM,GACJ,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAI5E;AAED;;;;;;;;;;;;GAYG;AACH,kDALW,MAAM,SACN,MAAM,eACN,MAAM,GACJ,MAAM,GAAG,IAAI,CAiBzB;AA/GD,0CAA0C;AAC1C,gCAAiC,kBAAkB,CAAA"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @internal
3
+ * produce/events.mjs — append + read the run-scoped produce event trail (M1).
4
+ *
5
+ * Writes go through `createCoordinationStore(dir).appendEvent` → the O_APPEND
6
+ * `.aperant/events/*.jsonl` log, schema-gated by event-schema.mjs (ID-04). The
7
+ * append is atomic across concurrent writers (POSIX O_APPEND under PIPE_BUF),
8
+ * so N parallel `add-milestone` writers never lose updates (parent TD-06).
9
+ *
10
+ * Reads fold the run's `produce.roadmap.*` events across the day buckets from
11
+ * the run's start day (setpoint.json.frozen_at) to today (UTC), filtered by
12
+ * `data.run_id`. Bounded + deterministic (ID-06).
13
+ */
14
+ import { readLifecycleEventsForDay } from '../coordination/event-log.mjs';
15
+ import { createCoordinationStore } from '../coordination/store.mjs';
16
+ import { resolveRunDir } from './run-id.mjs';
17
+ import { readSetpoint } from './setpoint.mjs';
18
+ /** The op-prefix the projection folds. */
19
+ export const ROADMAP_OP_PREFIX = 'produce.roadmap.';
20
+ /**
21
+ * Append one produce event through the schema-gated, O_APPEND coordination
22
+ * store. `data.run_id` also tags the event's top-level `task` field so the
23
+ * forensic trail is queryable by run. Returns the store's append result (null
24
+ * on schema violation — fail-closed).
25
+ *
26
+ * @param {string} projectDir
27
+ * @param {string} op
28
+ * @param {Record<string, unknown>} data
29
+ */
30
+ export function appendProduceEvent(projectDir, op, data) {
31
+ const store = createCoordinationStore(projectDir);
32
+ const runId = data && typeof data.run_id === 'string' ? data.run_id : null;
33
+ return store.appendEvent({ op, task: runId, data: data || {} });
34
+ }
35
+ /** Inclusive list of 'YYYY-MM-DD' UTC day buckets from startDay to endDay. */
36
+ function dayBucketsInclusive(startDay, endDay) {
37
+ const cur = new Date(`${startDay}T00:00:00.000Z`);
38
+ const end = new Date(`${endDay}T00:00:00.000Z`);
39
+ // Inverted / malformed range → just today's bucket (defensive).
40
+ if (Number.isNaN(cur.getTime()) || Number.isNaN(end.getTime()) || cur > end)
41
+ return [endDay];
42
+ const out = [];
43
+ while (cur <= end) {
44
+ out.push(cur.toISOString().slice(0, 10));
45
+ cur.setUTCDate(cur.getUTCDate() + 1);
46
+ // Safety cap — a real run's window is days, not a decade.
47
+ if (out.length > 3660)
48
+ break;
49
+ }
50
+ return out;
51
+ }
52
+ /**
53
+ * Fold the run's produce events matching `opMatches(op)` in chronological
54
+ * (append) order. The window starts at the setpoint's frozen day and ends today
55
+ * (UTC). Events are filtered to `data.run_id === runId`.
56
+ *
57
+ * This is the shared reader over the run's day-bucket window. `matchOp` selects
58
+ * which produce ops to fold — the roadmap projection folds ONLY the
59
+ * `produce.roadmap.*` prefix (see `readProduceEventsForRun`), while the M2
60
+ * oracle/probe consumers select `produce.milestone.implemented` /
61
+ * `produce.probe.*` / `produce.oracle.*`. It reads ONLY the append-only event
62
+ * log — it NEVER opens the frozen probe-content file (probe-blindness, ID-M2-03).
63
+ *
64
+ * @param {string} projectDir
65
+ * @param {string} runId
66
+ * @param {(op: string) => boolean} matchOp
67
+ * @returns {Array<{ op: string, data: Record<string, unknown>, t?: string }>}
68
+ */
69
+ export function readProduceRunEventsMatching(projectDir, runId, matchOp) {
70
+ const setpoint = readSetpoint(resolveRunDir(projectDir, runId));
71
+ const today = new Date().toISOString().slice(0, 10);
72
+ const startDay = setpoint && typeof setpoint.frozen_at === 'string' ? setpoint.frozen_at.slice(0, 10) : today;
73
+ const out = [];
74
+ for (const day of dayBucketsInclusive(startDay, today)) {
75
+ for (const e of readLifecycleEventsForDay(projectDir, day)) {
76
+ if (typeof e.op !== 'string')
77
+ continue;
78
+ if (!matchOp(e.op))
79
+ continue;
80
+ if (!e.data || e.data.run_id !== runId)
81
+ continue;
82
+ out.push(e);
83
+ }
84
+ }
85
+ return out;
86
+ }
87
+ /**
88
+ * Fold the run's `produce.roadmap.*` events in chronological (append) order.
89
+ * The projection consumes ONLY this reader, so the roadmap the Showrunner
90
+ * re-reads each tick can never surface a `produce.probe.*` / `produce.oracle.*`
91
+ * event (structural probe-blindness, AC5).
92
+ *
93
+ * @param {string} projectDir
94
+ * @param {string} runId
95
+ * @returns {Array<{ op: string, data: Record<string, unknown>, t?: string }>}
96
+ */
97
+ export function readProduceEventsForRun(projectDir, runId) {
98
+ return readProduceRunEventsMatching(projectDir, runId, (op) => op.startsWith(ROADMAP_OP_PREFIX));
99
+ }
100
+ /**
101
+ * Read the recorded implementer family for a run + milestone from the
102
+ * append-only `produce.milestone.implemented` trail (ID-M2-02 — the recorded
103
+ * disjointness anchor the cross-family rule is enforced against). Returns the
104
+ * LATEST recorded `implementer_family` for the milestone, or null when none is
105
+ * recorded (fail-closed — you cannot enforce disjointness against an unknown
106
+ * implementer).
107
+ *
108
+ * @param {string} projectDir
109
+ * @param {string} runId
110
+ * @param {string} milestoneId
111
+ * @returns {string | null}
112
+ */
113
+ export function readImplementerFamily(projectDir, runId, milestoneId) {
114
+ const events = readProduceRunEventsMatching(projectDir, runId, (op) => op === 'produce.milestone.implemented');
115
+ let family = null;
116
+ for (const e of events) {
117
+ const d = e.data || {};
118
+ if (d.milestone_id !== milestoneId)
119
+ continue;
120
+ if (typeof d.implementer_family === 'string' && d.implementer_family.length > 0) {
121
+ family = d.implementer_family;
122
+ }
123
+ }
124
+ return family;
125
+ }
126
+ //# sourceMappingURL=events.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.mjs","sourceRoot":"","sources":["../../../src/cli/produce/events.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Read verify-proof's `verification.json` at `verdictPath` and extract the
3
+ * v2 verdict + the tests[] {surface, evidence, result} rows into a structured
4
+ * judge-input payload. The verdict is read from `meta.verdict` (or a top-level
5
+ * `verdict`) and must be EXACTLY `approved` — anything else (or a
6
+ * missing/unreadable artifact) is NOT approved (fail-closed).
7
+ *
8
+ * @param {string} verdictPath — absolute/relative path to verification.json.
9
+ * @returns {{
10
+ * ok: boolean,
11
+ * approved: boolean,
12
+ * verdict: string | null,
13
+ * reason: string | null,
14
+ * tests: Array<{ id: string | null, surface: string | null, evidence: string | null, result: string | null }>,
15
+ * judge_input: { verdict: string | null, task_id: string | null, spec: string | null, tests: Array<object> } | null,
16
+ * }}
17
+ */
18
+ export function prepareOracleInput(verdictPath: string): {
19
+ ok: boolean;
20
+ approved: boolean;
21
+ verdict: string | null;
22
+ reason: string | null;
23
+ tests: Array<{
24
+ id: string | null;
25
+ surface: string | null;
26
+ evidence: string | null;
27
+ result: string | null;
28
+ }>;
29
+ judge_input: {
30
+ verdict: string | null;
31
+ task_id: string | null;
32
+ spec: string | null;
33
+ tests: Array<object>;
34
+ } | null;
35
+ };
36
+ /**
37
+ * Record the independent evidence-quality oracle's verdict. REFUSES fail-closed
38
+ * when the oracle family equals the recorded implementer family (cross-family
39
+ * enforcement, ID-08) or when no implementer family is recorded (ID-M2-02). On
40
+ * acceptance appends `produce.oracle.judged {run_id, milestone_id, verdict,
41
+ * oracle_family}`.
42
+ *
43
+ * @param {string} projectDir
44
+ * @param {{ runId: string, milestoneId: string, verdict: string, oracleFamily: string }} args
45
+ * @returns {{ ok: true, verdict: string, oracle_family: string, implementer_family: string }
46
+ * | { ok: false, reason: string, implementer_family?: string | null }}
47
+ */
48
+ export function recordOracleVerdict(projectDir: string, { runId, milestoneId, verdict, oracleFamily }: {
49
+ runId: string;
50
+ milestoneId: string;
51
+ verdict: string;
52
+ oracleFamily: string;
53
+ }): {
54
+ ok: true;
55
+ verdict: string;
56
+ oracle_family: string;
57
+ implementer_family: string;
58
+ } | {
59
+ ok: false;
60
+ reason: string;
61
+ implementer_family?: string | null;
62
+ };
63
+ //# sourceMappingURL=evidence-oracle.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-oracle.d.mts","sourceRoot":"","sources":["../../../src/cli/produce/evidence-oracle.mjs"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;GAgBG;AACH,gDAVW,MAAM,GACJ;IACR,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC5G,WAAW,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;CACnH,CA0DH;AAED;;;;;;;;;;;GAWG;AACH,gDALW,MAAM,iDACN;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,GACtF;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAsBvE"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @internal
3
+ * produce/evidence-oracle.mjs — the independent evidence-quality oracle (M2, AC7).
4
+ *
5
+ * verify-proof issues a deterministic two-gate verdict over captured evidence;
6
+ * the evidence-oracle is a SECOND opinion — a cross-family judge deciding
7
+ * whether that captured evidence actually supports "done" (US-3 / ID-06). The
8
+ * CLI is deterministic: `prepareOracleInput` extracts the verdict + the tests[]
9
+ * evidence into a structured judge payload the skill sends to the cross-family
10
+ * model; `recordOracleVerdict` records the judge's pass/fail, refusing
11
+ * fail-closed when the oracle family equals the implementer family (the oracle
12
+ * that judged the work must not be the family that produced it — ID-08).
13
+ *
14
+ * The verify-proof verdict is read as the v2 closed-set `approved` ONLY
15
+ * (ID-M2-05): a legacy middle-band verdict, `needs_human`, `rejected`, or a
16
+ * missing/unreadable artifact is NOT `approved` → not adjudicable (fail-closed).
17
+ */
18
+ import { readJsonIfExists } from '../util/io.mjs';
19
+ import { appendProduceEvent, readImplementerFamily } from './events.mjs';
20
+ import { normalizeFamily } from './probe-family.mjs';
21
+ /** The single verdict verify-proof v2 treats as a pass (ID-M2-05). */
22
+ const APPROVED = 'approved';
23
+ /**
24
+ * Read verify-proof's `verification.json` at `verdictPath` and extract the
25
+ * v2 verdict + the tests[] {surface, evidence, result} rows into a structured
26
+ * judge-input payload. The verdict is read from `meta.verdict` (or a top-level
27
+ * `verdict`) and must be EXACTLY `approved` — anything else (or a
28
+ * missing/unreadable artifact) is NOT approved (fail-closed).
29
+ *
30
+ * @param {string} verdictPath — absolute/relative path to verification.json.
31
+ * @returns {{
32
+ * ok: boolean,
33
+ * approved: boolean,
34
+ * verdict: string | null,
35
+ * reason: string | null,
36
+ * tests: Array<{ id: string | null, surface: string | null, evidence: string | null, result: string | null }>,
37
+ * judge_input: { verdict: string | null, task_id: string | null, spec: string | null, tests: Array<object> } | null,
38
+ * }}
39
+ */
40
+ export function prepareOracleInput(verdictPath) {
41
+ if (!verdictPath)
42
+ return {
43
+ ok: false,
44
+ approved: false,
45
+ verdict: null,
46
+ reason: 'no_verdict_path',
47
+ tests: [],
48
+ judge_input: null,
49
+ };
50
+ const doc = readJsonIfExists(verdictPath);
51
+ if (!doc || typeof doc !== 'object')
52
+ return {
53
+ ok: false,
54
+ approved: false,
55
+ verdict: null,
56
+ reason: 'verdict_unreadable',
57
+ tests: [],
58
+ judge_input: null,
59
+ };
60
+ const meta = doc.meta && typeof doc.meta === 'object' ? doc.meta : {};
61
+ const verdict = typeof meta.verdict === 'string'
62
+ ? meta.verdict
63
+ : typeof doc.verdict === 'string'
64
+ ? doc.verdict
65
+ : null;
66
+ const tests = Array.isArray(doc.tests)
67
+ ? doc.tests.map((t) => ({
68
+ id: t && typeof t.id === 'string' ? t.id : null,
69
+ surface: t && typeof t.surface === 'string' ? t.surface : null,
70
+ evidence: t && typeof t.evidence === 'string' ? t.evidence : null,
71
+ result: t && typeof t.result === 'string' ? t.result : null,
72
+ }))
73
+ : [];
74
+ // EXACTLY `approved` — the legacy middle-band verdict is NOT
75
+ // approved (verify-proof v2 deleted it; ID-M2-05).
76
+ const approved = verdict === APPROVED;
77
+ return {
78
+ ok: approved,
79
+ approved,
80
+ verdict,
81
+ reason: approved ? null : 'verdict_not_approved',
82
+ tests,
83
+ judge_input: {
84
+ verdict,
85
+ task_id: typeof meta.task_id === 'string' ? meta.task_id : null,
86
+ spec: typeof meta.spec === 'string' ? meta.spec : null,
87
+ tests,
88
+ },
89
+ };
90
+ }
91
+ /**
92
+ * Record the independent evidence-quality oracle's verdict. REFUSES fail-closed
93
+ * when the oracle family equals the recorded implementer family (cross-family
94
+ * enforcement, ID-08) or when no implementer family is recorded (ID-M2-02). On
95
+ * acceptance appends `produce.oracle.judged {run_id, milestone_id, verdict,
96
+ * oracle_family}`.
97
+ *
98
+ * @param {string} projectDir
99
+ * @param {{ runId: string, milestoneId: string, verdict: string, oracleFamily: string }} args
100
+ * @returns {{ ok: true, verdict: string, oracle_family: string, implementer_family: string }
101
+ * | { ok: false, reason: string, implementer_family?: string | null }}
102
+ */
103
+ export function recordOracleVerdict(projectDir, { runId, milestoneId, verdict, oracleFamily }) {
104
+ if (verdict !== 'pass' && verdict !== 'fail')
105
+ return { ok: false, reason: 'invalid_verdict' };
106
+ if (!oracleFamily)
107
+ return { ok: false, reason: 'no_oracle_family' };
108
+ const implementerFamily = readImplementerFamily(projectDir, runId, milestoneId);
109
+ if (!implementerFamily)
110
+ return { ok: false, reason: 'no_recorded_implementer', implementer_family: null };
111
+ // Cross-family enforcement (normalized so claude-code === claude).
112
+ if (normalizeFamily(oracleFamily) === normalizeFamily(implementerFamily))
113
+ return { ok: false, reason: 'same_family_oracle', implementer_family: implementerFamily };
114
+ appendProduceEvent(projectDir, 'produce.oracle.judged', {
115
+ run_id: runId,
116
+ milestone_id: milestoneId,
117
+ verdict,
118
+ oracle_family: oracleFamily,
119
+ });
120
+ return { ok: true, verdict, oracle_family: oracleFamily, implementer_family: implementerFamily };
121
+ }
122
+ //# sourceMappingURL=evidence-oracle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-oracle.mjs","sourceRoot":"","sources":["../../../src/cli/produce/evidence-oracle.mjs"],"names":[],"mappings":"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"}