@aperant/framework 0.16.0 → 0.19.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 (174) hide show
  1. package/CHANGELOG.md +185 -1
  2. package/dist/cli/commands/ci-watch.mjs +49 -2
  3. package/dist/cli/commands/ci-watch.mjs.map +1 -1
  4. package/dist/cli/commands/commit.mjs +3 -3
  5. package/dist/cli/commands/commit.mjs.map +1 -1
  6. package/dist/cli/commands/event.mjs +16 -16
  7. package/dist/cli/commands/event.mjs.map +1 -1
  8. package/dist/cli/commands/merge-integrate.mjs +3 -3
  9. package/dist/cli/commands/merge-integrate.mjs.map +1 -1
  10. package/dist/cli/commands/produce.d.mts +9 -0
  11. package/dist/cli/commands/produce.d.mts.map +1 -0
  12. package/dist/cli/commands/produce.mjs +1345 -0
  13. package/dist/cli/commands/produce.mjs.map +1 -0
  14. package/dist/cli/commands/spar-resolve-partner.d.mts +9 -0
  15. package/dist/cli/commands/spar-resolve-partner.d.mts.map +1 -0
  16. package/dist/cli/commands/spar-resolve-partner.mjs +82 -0
  17. package/dist/cli/commands/spar-resolve-partner.mjs.map +1 -0
  18. package/dist/cli/commands/task.d.mts +16 -1
  19. package/dist/cli/commands/task.d.mts.map +1 -1
  20. package/dist/cli/commands/task.mjs +434 -266
  21. package/dist/cli/commands/task.mjs.map +1 -1
  22. package/dist/cli/config/gitignore-drift.d.mts.map +1 -1
  23. package/dist/cli/config/gitignore-drift.mjs +1 -0
  24. package/dist/cli/config/gitignore-drift.mjs.map +1 -1
  25. package/dist/cli/config/post-merge-sweep.d.mts.map +1 -1
  26. package/dist/cli/config/post-merge-sweep.mjs +1 -0
  27. package/dist/cli/config/post-merge-sweep.mjs.map +1 -1
  28. package/dist/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
  29. package/dist/cli/coordination/auto-emit-artifact-ready.mjs.map +1 -1
  30. package/dist/cli/coordination/event-schema.d.mts +5 -3
  31. package/dist/cli/coordination/event-schema.d.mts.map +1 -1
  32. package/dist/cli/coordination/event-schema.mjs +245 -21
  33. package/dist/cli/coordination/event-schema.mjs.map +1 -1
  34. package/dist/cli/coordination/store.d.mts +2 -2
  35. package/dist/cli/coordination/store.mjs +4 -4
  36. package/dist/cli/coordination/store.mjs.map +1 -1
  37. package/dist/cli/dispatch.d.mts.map +1 -1
  38. package/dist/cli/dispatch.mjs +4 -0
  39. package/dist/cli/dispatch.mjs.map +1 -1
  40. package/dist/cli/help.d.mts.map +1 -1
  41. package/dist/cli/help.mjs +31 -0
  42. package/dist/cli/help.mjs.map +1 -1
  43. package/dist/cli/host/codex-config.d.mts +78 -0
  44. package/dist/cli/host/codex-config.d.mts.map +1 -0
  45. package/dist/cli/host/codex-config.mjs +169 -0
  46. package/dist/cli/host/codex-config.mjs.map +1 -0
  47. package/dist/cli/install/legacy-paths.d.mts.map +1 -1
  48. package/dist/cli/install/legacy-paths.mjs +2 -0
  49. package/dist/cli/install/legacy-paths.mjs.map +1 -1
  50. package/dist/cli/produce/blind-probe.d.mts +85 -0
  51. package/dist/cli/produce/blind-probe.d.mts.map +1 -0
  52. package/dist/cli/produce/blind-probe.mjs +217 -0
  53. package/dist/cli/produce/blind-probe.mjs.map +1 -0
  54. package/dist/cli/produce/claim.d.mts +188 -0
  55. package/dist/cli/produce/claim.d.mts.map +1 -0
  56. package/dist/cli/produce/claim.mjs +518 -0
  57. package/dist/cli/produce/claim.mjs.map +1 -0
  58. package/dist/cli/produce/done-gate.d.mts +87 -0
  59. package/dist/cli/produce/done-gate.d.mts.map +1 -0
  60. package/dist/cli/produce/done-gate.mjs +200 -0
  61. package/dist/cli/produce/done-gate.mjs.map +1 -0
  62. package/dist/cli/produce/events.d.mts +77 -0
  63. package/dist/cli/produce/events.d.mts.map +1 -0
  64. package/dist/cli/produce/events.mjs +126 -0
  65. package/dist/cli/produce/events.mjs.map +1 -0
  66. package/dist/cli/produce/evidence-oracle.d.mts +63 -0
  67. package/dist/cli/produce/evidence-oracle.d.mts.map +1 -0
  68. package/dist/cli/produce/evidence-oracle.mjs +122 -0
  69. package/dist/cli/produce/evidence-oracle.mjs.map +1 -0
  70. package/dist/cli/produce/ledger.d.mts +140 -0
  71. package/dist/cli/produce/ledger.d.mts.map +1 -0
  72. package/dist/cli/produce/ledger.mjs +272 -0
  73. package/dist/cli/produce/ledger.mjs.map +1 -0
  74. package/dist/cli/produce/probe-family.d.mts +53 -0
  75. package/dist/cli/produce/probe-family.d.mts.map +1 -0
  76. package/dist/cli/produce/probe-family.mjs +160 -0
  77. package/dist/cli/produce/probe-family.mjs.map +1 -0
  78. package/dist/cli/produce/projection.d.mts +55 -0
  79. package/dist/cli/produce/projection.d.mts.map +1 -0
  80. package/dist/cli/produce/projection.mjs +97 -0
  81. package/dist/cli/produce/projection.mjs.map +1 -0
  82. package/dist/cli/produce/run-id.d.mts +42 -0
  83. package/dist/cli/produce/run-id.d.mts.map +1 -0
  84. package/dist/cli/produce/run-id.mjs +79 -0
  85. package/dist/cli/produce/run-id.mjs.map +1 -0
  86. package/dist/cli/produce/saga.d.mts +180 -0
  87. package/dist/cli/produce/saga.d.mts.map +1 -0
  88. package/dist/cli/produce/saga.mjs +290 -0
  89. package/dist/cli/produce/saga.mjs.map +1 -0
  90. package/dist/cli/produce/scheduler.d.mts +165 -0
  91. package/dist/cli/produce/scheduler.d.mts.map +1 -0
  92. package/dist/cli/produce/scheduler.mjs +399 -0
  93. package/dist/cli/produce/scheduler.mjs.map +1 -0
  94. package/dist/cli/produce/setpoint.d.mts +52 -0
  95. package/dist/cli/produce/setpoint.d.mts.map +1 -0
  96. package/dist/cli/produce/setpoint.mjs +113 -0
  97. package/dist/cli/produce/setpoint.mjs.map +1 -0
  98. package/dist/cli/produce/verification-ttl.d.mts +75 -0
  99. package/dist/cli/produce/verification-ttl.d.mts.map +1 -0
  100. package/dist/cli/produce/verification-ttl.mjs +169 -0
  101. package/dist/cli/produce/verification-ttl.mjs.map +1 -0
  102. package/dist/cli/roadmap/{conductor-view.d.mts → showrunner-view.d.mts} +3 -3
  103. package/dist/cli/roadmap/showrunner-view.d.mts.map +1 -0
  104. package/dist/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +7 -7
  105. package/dist/cli/roadmap/showrunner-view.mjs.map +1 -0
  106. package/dist/cli/wfrun/run.d.mts.map +1 -1
  107. package/dist/cli/wfrun/run.mjs +1 -0
  108. package/dist/cli/wfrun/run.mjs.map +1 -1
  109. package/dist/plugin/.claude-plugin/plugin.json +2 -1
  110. package/dist/plugin/skills/apt/SKILL.md +112 -38
  111. package/dist/plugin/skills/apt-debug/SKILL.md +14 -24
  112. package/dist/plugin/skills/apt-fan-out/SKILL.md +4 -4
  113. package/dist/plugin/skills/apt-handoff/SKILL.md +1 -1
  114. package/dist/plugin/skills/apt-plan/SKILL.md +5 -5
  115. package/dist/plugin/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
  116. package/dist/plugin/skills/apt-produce/SKILL.md +606 -0
  117. package/dist/plugin/skills/apt-quick/SKILL.md +14 -22
  118. package/dist/plugin/skills/apt-run/SKILL.md +126 -3
  119. package/dist/plugin/skills/apt-ship/SKILL.md +2 -0
  120. package/dist/plugin/skills/apt-spar/SKILL.md +19 -9
  121. package/dist/plugin/skills/apt-watch-ci/SKILL.md +4 -4
  122. package/package.json +4 -4
  123. package/prompts/{conductor-framework-context.md → showrunner-framework-context.md} +1 -1
  124. package/prompts/{conductor-status-check.md → showrunner-status-check.md} +1 -1
  125. package/prompts/{conductor-sub-agent.md → showrunner-sub-agent.md} +6 -6
  126. package/prompts/{conductor-system.md → showrunner-system.md} +8 -8
  127. package/skills/apt/SKILL.md +112 -38
  128. package/skills/apt-debug/SKILL.md +14 -24
  129. package/skills/apt-fan-out/SKILL.md +4 -4
  130. package/skills/apt-handoff/SKILL.md +1 -1
  131. package/skills/apt-plan/SKILL.md +5 -5
  132. package/skills/apt-plan/adapters/{conductor.md → showrunner.md} +16 -16
  133. package/skills/apt-produce/SKILL.md +606 -0
  134. package/skills/apt-quick/SKILL.md +14 -22
  135. package/skills/apt-run/SKILL.md +126 -3
  136. package/skills/apt-ship/SKILL.md +2 -0
  137. package/skills/apt-spar/SKILL.md +19 -9
  138. package/skills/apt-watch-ci/SKILL.md +4 -4
  139. package/src/cli/commands/ci-watch.mjs +51 -2
  140. package/src/cli/commands/commit.mjs +3 -3
  141. package/src/cli/commands/event.mjs +16 -16
  142. package/src/cli/commands/merge-integrate.mjs +3 -3
  143. package/src/cli/commands/produce.mjs +1466 -0
  144. package/src/cli/commands/spar-resolve-partner.mjs +85 -0
  145. package/src/cli/commands/task.mjs +482 -285
  146. package/src/cli/config/gitignore-drift.mjs +1 -0
  147. package/src/cli/config/post-merge-sweep.mjs +1 -0
  148. package/src/cli/coordination/auto-emit-artifact-ready.mjs +5 -5
  149. package/src/cli/coordination/event-schema.d.ts +4 -2
  150. package/src/cli/coordination/event-schema.mjs +276 -21
  151. package/src/cli/coordination/store.mjs +4 -4
  152. package/src/cli/dispatch.mjs +4 -0
  153. package/src/cli/help.mjs +31 -0
  154. package/src/cli/host/codex-config.mjs +165 -0
  155. package/src/cli/install/legacy-paths.mjs +2 -0
  156. package/src/cli/produce/blind-probe.mjs +245 -0
  157. package/src/cli/produce/claim.mjs +543 -0
  158. package/src/cli/produce/done-gate.mjs +238 -0
  159. package/src/cli/produce/events.mjs +131 -0
  160. package/src/cli/produce/evidence-oracle.mjs +133 -0
  161. package/src/cli/produce/ledger.mjs +284 -0
  162. package/src/cli/produce/probe-family.mjs +168 -0
  163. package/src/cli/produce/projection.mjs +105 -0
  164. package/src/cli/produce/run-id.mjs +84 -0
  165. package/src/cli/produce/saga.mjs +303 -0
  166. package/src/cli/produce/scheduler.mjs +423 -0
  167. package/src/cli/produce/setpoint.mjs +122 -0
  168. package/src/cli/produce/verification-ttl.mjs +191 -0
  169. package/src/cli/roadmap/showrunner-view.d.ts +10 -0
  170. package/src/cli/roadmap/{conductor-view.mjs → showrunner-view.mjs} +6 -6
  171. package/src/cli/wfrun/run.mjs +1 -0
  172. package/dist/cli/roadmap/conductor-view.d.mts.map +0 -1
  173. package/dist/cli/roadmap/conductor-view.mjs.map +0 -1
  174. package/src/cli/roadmap/conductor-view.d.ts +0 -10
package/dist/cli/help.mjs CHANGED
@@ -27,6 +27,7 @@ Commands:
27
27
  risk-check <dir> --paths <p1> [--operation <type>] Classify file paths by risk level
28
28
 
29
29
  task create <dir> --description <text> [--scope <s>] [--milestone <id>] [--phase <id>] [--roadmap-ref-url <url>] [--depends-on <refs>] [--track <T>] [--autonomy <N>] Create isolated task
30
+ task ensure <dir> --description <text> --intent <create-new|require-existing|self-managed|none> [--track <T>] [--autonomy <N>] [--scope <s>] [--id <id>] Deterministic idempotent allocator: create-new provisions a per-task worktree (idempotent on re-run), require-existing resolves the active task without minting, none/self-managed allocate nothing
30
31
  task list <dir> [--scope <s>] [--blocked-by <id>] List active tasks (optionally filtered)
31
32
  task get <dir> --id <task-id> Get task details and artifacts
32
33
  task update <dir> --id <id> [--lifecycle-phase <p>] [--pr-url <url>] [--subtasks-total <N>] [--depends-on <refs>] Update non-linkage task state; --pr-url may arm ci-watch per ci_watch.after_ship
@@ -108,6 +109,7 @@ Commands:
108
109
  toolchain-detect <project-dir> Detect project toolchain (linter, formatter, typecheck, test, build)
109
110
  health-check <project-dir> Detect dirty state, stale locks, orphaned events, version drift
110
111
  host-detect Detect which AI CLI is running and its capability matrix
112
+ spar-resolve-partner [--partner codex|claude|gemini] apt:spar live partner-model resolution — reads ~/.codex/config.toml LIVE (fail-closed, no baked default); codex returns {available,model,source,reason} + a transport-walk preference, claude/gemini return self_resolving
111
113
  reconcile <project-dir> Resolve orchestration preferences against host capabilities
112
114
 
113
115
  migrate-pr-reviews <project-dir> Migrate legacy .aperant/reviews/ → .aperant/pr-reviews/pr-{N}/rounds/{R}/ (idempotent)
@@ -133,6 +135,35 @@ Commands:
133
135
  ci-watch start|stop|status|tick <dir> [--pr <N>] [...] /apt:watch-ci primitives — see SKILL.md for full flag matrix
134
136
  ci-watch sweep <dir> --orphaned [--dry-run] BUG-027: enumerate ci-watches state files, query gh per PR, remove terminal-state (MERGED|CLOSED) entries (manual GC; rate-limited)
135
137
 
138
+ produce start <dir> --outcome "<o>" [--run-id <id>] /apt:produce M1 — freeze an immutable acceptance setpoint under .aperant/produce/<run-id>/ (idempotent-reuse on --run-id, never overwrites); emits produce.run.started + produce.setpoint.frozen
139
+ produce add-milestone <dir> --run-id <id> --title "<t>" [--id <mid>] Append produce.roadmap.milestone_added + refresh the derived roadmap.json projection cache
140
+ produce set-milestone-status <dir> --run-id <id> --milestone <mid> --status <planned|in_progress|done> [--verdict-path <p>] Append produce.roadmap.milestone_status_changed; --status done is the M2 two-gate adjudication (visible oracle AND blind probe)
141
+ produce status <dir> --run-id <id> Re-project the roadmap from the append-only event log (no in-memory authority)
142
+ produce tick <dir> --run-id <id> Run exactly ONE wake tick — re-project from disk, emit produce.tick, compute next_action + next_tick_hint, then exit (no loop)
143
+ produce record-implementer <dir> --run-id <id> --milestone <mid> --implementer-family <fam> /apt:produce M2 — record the implementer family (the cross-family disjointness anchor)
144
+ produce resolve-probe-family <dir> --run-id <id> [--milestone <mid>] [--implementer-family <fam>] [--host-family <fam>] [--available-families a,b,c] M2 — resolve a probe/oracle family DISJOINT from the implementer + a LIVE model (never hardcoded); available:false when none
145
+ produce oracle prepare <dir> --run-id <id> --milestone <mid> --verdict-path <p> M2 — extract verify-proof's v2 verdict (must be approved) + tests[] evidence into a cross-family judge payload
146
+ produce oracle record <dir> --run-id <id> --milestone <mid> --verdict <pass|fail> --oracle-family <fam> M2 — record produce.oracle.judged (refused when oracle_family === implementer)
147
+ produce probe freeze <dir> --run-id <id> --milestone <mid> --probe-file <p> --author-family <fam> M2 — freeze an immutable held-out probe set (hash + family only; refused when author_family === implementer)
148
+ produce probe record <dir> --run-id <id> --milestone <mid> --result <pass|fail> --probe-family <fam> --head-sha <sha> M2 — record produce.probe.run (result/family/sha only; refused when probe_family === implementer)
149
+ produce probe sweep <dir> --run-id <id> [--sample N] M2 — deterministic rotating sample of already-done milestones to blind-re-probe against HEAD
150
+ produce canary <dir> --run-id <id> M2 — green-on-visible MINUS green-on-blind + per-milestone breakdown (the reward-hacking canary)
151
+ produce declare-criteria <dir> --run-id <id> --milestone <mid> --criterion "<text>" [--criterion-id <cid>] [--scope-change "<reason>"] /apt:produce M3 — open one acceptance criterion (V += 1); rejected after descent unless --scope-change justifies the increase (anti-windup)
152
+ produce progress <dir> --run-id <id> M3 — re-read the Lyapunov V-series from the log: open-criteria count strictly decreasing across shipped milestones + any un-sanctioned-increase violations (flags, never rejects)
153
+ produce saga enter <dir> --run-id <id> --milestone <mid> --phase <plan|execute|verify|review|ship> /apt:produce M4 — append produce.saga.phase_entered (separate fold from the roadmap projection)
154
+ produce saga complete <dir> --run-id <id> --milestone <mid> --phase <plan|execute|verify|review|ship> M4 — append produce.saga.phase_completed
155
+ produce saga compensate <dir> --run-id <id> --milestone <mid> --phase <p> [--reason "<r>"] M4 — fire the FORWARD compensator (verify|review|ship ships a revert + reopens + re-plans; NEVER rolls back a merged PR); records the descriptor, does not execute it
156
+ produce saga resolve-reviewer <dir> --run-id <id> --milestone <mid> [--host-family <fam>] [--available-families a,b,c] M4 — resolve a REVIEW-phase reviewer family DISJOINT from the implementer + a LIVE model (reuses resolveProbeFamily; never hardcoded); available:false when none
157
+ produce saga review <dir> --run-id <id> --milestone <mid> --verdict <pass|fail> --reviewer-family <fam> M4 — record produce.saga.reviewed (refused when reviewer_family === implementer)
158
+ produce saga status <dir> --run-id <id> M4 — re-project per-milestone saga phase state + pending compensation from the log (no roadmap status mutation)
159
+ produce ttl select <dir> --run-id <id> --head-sha <sha> [--sample N] M4 — deterministic rotating sample of OLD done milestones STALE against HEAD (reuses the M2 rotation; a milestone re-verified against current HEAD is excluded as fresh)
160
+ produce ttl reverify <dir> --run-id <id> --milestone <mid> --result <pass|fail> --probe-family <fam> --head-sha <sha> M4 — cross-family re-verify; --result fail appends ttl.reverified + ttl.regression_detected + fires the FORWARD compensator (ships a revert, not a rollback)
161
+ produce schedule <dir> --run-id <id> [--wip N] /apt:produce M5 — WSJF-rank the ready milestones (cost-of-delay / job-size) + a WIP-limited pick; dependency-aware readiness (blocked / cycle), M4-regression re-entry; read-only
162
+ produce claim declare <dir> --run-id <id> --profile <p> --claim-file <path> [--claim-id <id>] /apt:produce M6 — validate + freeze an immutable Claim Envelope to claims/<claim-id>.json (interop, not a 4th store); rejects a global/unbounded scope, empty preconditions, or missing expiry fail-closed; logs produce.claim.declared (content_hash only)
163
+ produce claim list <dir> --run-id <id> M6 — re-project the claim ledger (declared − expired) folded from the append-only log; produce.claim.* never enters the roadmap projection
164
+ produce claim expire <dir> --run-id <id> --claim-id <id> [--reason "<r>"] M6 — append produce.claim.expired; the claim drops out of the ledger's active set (anti-corrosion manual expiry)
165
+ produce claim consume <dir> --run-id <id> [--milestone <mid>] M6 — emit the STRUCTURED delta {claim_id, targets:[{kind, requirement, ref?}]} derived from resolution_verifier (never a lesson-text paste); skips expired / HEAD-invalidated / precondition-unmatched claims
166
+
136
167
  followups check <dir> --task-id <id> G45: derive the expected follow-up universe (Out of Scope ∪ raw review rows ∪ qa findings) + report missing/unadjudicated/unfixed/undispositioned rows; exit 1 when the ledger is dishonest
137
168
  followups disposition <dir> --task-id <id> --row <row-id> --kind <filed_task|executed_commit|parked_note|dropped_by_user> --ref <ref> [--reason <text>] G45: flip a ledger row to dispositioned (atomic; dropped_by_user requires --reason)
138
169
  followups policy <dir> --task-id <id> G45: effective disposition policy (ask|file|chain + max_chain_depth) from config.followups when set, else autonomy-derived
@@ -1 +1 @@
1
- {"version":3,"file":"help.mjs","sourceRoot":"","sources":["../../src/cli/help.mjs"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,MAAM,UAAU,SAAS;IACxB,MAAM,IAAI,GAAG,GAAG,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA0IT,CAAA;IAEnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;AAClC,CAAC"}
1
+ {"version":3,"file":"help.mjs","sourceRoot":"","sources":["../../src/cli/help.mjs"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,MAAM,UAAU,SAAS;IACxB,MAAM,IAAI,GAAG,GAAG,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAyKT,CAAA;IAEnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;AAClC,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @typedef {Object} ParsedCodexModel
3
+ * @property {string|null} model — the resolved top-level model, or null.
4
+ * @property {null|'no_model_key'|'unparseable'} reason — null when a model
5
+ * resolved; a machine reason otherwise.
6
+ */
7
+ /**
8
+ * Parse the FIRST top-level `model = "<value>"` assignment from codex
9
+ * `config.toml` text. Scans line-by-line, stops at the first `[section]`
10
+ * header (top-level scope ends there), skips comment lines, and resolves the
11
+ * first top-level `model` key.
12
+ *
13
+ * Handles (refinement #1): a leading UTF-8 BOM, an inline `# comment` after the
14
+ * value, a no-space `model="x"` assignment, single-quoted TOML literal strings,
15
+ * and commented-out `#model = "x"` keys (skipped). A malformed / unterminated /
16
+ * escaped-quote value returns `reason: 'unparseable'` — never a truncated
17
+ * string. The first top-level `model` line is decisive: if it is malformed the
18
+ * parser returns `unparseable` rather than scanning for a later valid line
19
+ * (TOML forbids duplicate keys, and a later-line search would be too loose).
20
+ *
21
+ * @param {string} tomlText
22
+ * @returns {ParsedCodexModel}
23
+ */
24
+ export function parseTopLevelCodexModel(tomlText: string): ParsedCodexModel;
25
+ /**
26
+ * @typedef {Object} CodexSparModelResolution
27
+ * @property {boolean} available — true iff a live top-level model resolved.
28
+ * @property {string|null} model — the resolved model, or null when unavailable.
29
+ * @property {string} source — the config source label (`~/.codex/config.toml`).
30
+ * @property {null|'config_missing'|'no_model_key'|'unparseable'} reason
31
+ */
32
+ /**
33
+ * Read `<home>/.codex/config.toml` LIVE and resolve the top-level model.
34
+ * Fail-closed (Decision C / ID-03): a missing file, a missing top-level `model`
35
+ * key, or an unparseable value returns `available: false` with a machine reason
36
+ * and `model: null`. It NEVER substitutes a default. There is no module-level
37
+ * cached value — the file is re-read on every call.
38
+ *
39
+ * `existsSync` / `readFileSync` are injected so tests stay hermetic (no real
40
+ * `$HOME` read).
41
+ *
42
+ * @param {{ home: string, existsSync: (p: string) => boolean, readFileSync: (p: string, enc: string) => string }} deps
43
+ * @returns {CodexSparModelResolution}
44
+ */
45
+ export function resolveCodexSparModel({ home, existsSync, readFileSync }: {
46
+ home: string;
47
+ existsSync: (p: string) => boolean;
48
+ readFileSync: (p: string, enc: string) => string;
49
+ }): CodexSparModelResolution;
50
+ /** Human-facing source label the SKILL + envelope reference. */
51
+ export const CODEX_CONFIG_SOURCE: "~/.codex/config.toml";
52
+ export type ParsedCodexModel = {
53
+ /**
54
+ * — the resolved top-level model, or null.
55
+ */
56
+ model: string | null;
57
+ /**
58
+ * — null when a model
59
+ * resolved; a machine reason otherwise.
60
+ */
61
+ reason: null | "no_model_key" | "unparseable";
62
+ };
63
+ export type CodexSparModelResolution = {
64
+ /**
65
+ * — true iff a live top-level model resolved.
66
+ */
67
+ available: boolean;
68
+ /**
69
+ * — the resolved model, or null when unavailable.
70
+ */
71
+ model: string | null;
72
+ /**
73
+ * — the config source label (`~/.codex/config.toml`).
74
+ */
75
+ source: string;
76
+ reason: null | "config_missing" | "no_model_key" | "unparseable";
77
+ };
78
+ //# sourceMappingURL=codex-config.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-config.d.mts","sourceRoot":"","sources":["../../../src/cli/host/codex-config.mjs"],"names":[],"mappings":"AA4BA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,kDAHW,MAAM,GACJ,gBAAgB,CAyB5B;AAmDD;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AACH,0EAHW;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,GACpG,wBAAwB,CAmBpC;AA3ID,gEAAgE;AAChE,kCAAmC,sBAAsB,CAAA;;;;;WAI3C,MAAM,GAAC,IAAI;;;;;YACX,IAAI,GAAC,cAAc,GAAC,aAAa;;;;;;eAiGjC,OAAO;;;;WACP,MAAM,GAAC,IAAI;;;;YACX,MAAM;YACN,IAAI,GAAC,gBAAgB,GAAC,cAAc,GAAC,aAAa"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * host/codex-config.mjs — live codex model resolution for `apt:spar` (Decision B + C).
3
+ *
4
+ * Aperant holds ZERO model names. The only source of truth for the codex
5
+ * partner's model is the user's live `~/.codex/config.toml`, read at invocation
6
+ * time with NO fallback default — mirroring the app's "Model selection —
7
+ * resolver-only, provider-is-output, LIVE" rule.
8
+ *
9
+ * Two exports:
10
+ * - `parseTopLevelCodexModel(tomlText)` — a deterministic top-level TOML
11
+ * `model = "<value>"` line parser (ID-04: top-level only; `[profiles.*]`
12
+ * sections are inactive without `--profile`, which spar never passes).
13
+ * - `resolveCodexSparModel({ home, existsSync, readFileSync })` — reads
14
+ * `<home>/.codex/config.toml` LIVE each call and returns a fail-closed
15
+ * `{ available, model, source, reason }` envelope. NEVER a baked constant.
16
+ *
17
+ * Parser hardening (plan-gate spar refinement #1). The bias rule is
18
+ * fail-closed: when a value is ambiguous, return `reason: 'unparseable'` rather
19
+ * than a wrong or truncated model. A too-strict parse that loses the MCP rung
20
+ * (falling through to the self-resolving plugin/CLI rungs) is acceptable; a
21
+ * too-loose parse that passes a wrong model is a bug.
22
+ */
23
+ import { join } from 'node:path';
24
+ /** Human-facing source label the SKILL + envelope reference. */
25
+ export const CODEX_CONFIG_SOURCE = '~/.codex/config.toml';
26
+ /**
27
+ * @typedef {Object} ParsedCodexModel
28
+ * @property {string|null} model — the resolved top-level model, or null.
29
+ * @property {null|'no_model_key'|'unparseable'} reason — null when a model
30
+ * resolved; a machine reason otherwise.
31
+ */
32
+ /**
33
+ * Parse the FIRST top-level `model = "<value>"` assignment from codex
34
+ * `config.toml` text. Scans line-by-line, stops at the first `[section]`
35
+ * header (top-level scope ends there), skips comment lines, and resolves the
36
+ * first top-level `model` key.
37
+ *
38
+ * Handles (refinement #1): a leading UTF-8 BOM, an inline `# comment` after the
39
+ * value, a no-space `model="x"` assignment, single-quoted TOML literal strings,
40
+ * and commented-out `#model = "x"` keys (skipped). A malformed / unterminated /
41
+ * escaped-quote value returns `reason: 'unparseable'` — never a truncated
42
+ * string. The first top-level `model` line is decisive: if it is malformed the
43
+ * parser returns `unparseable` rather than scanning for a later valid line
44
+ * (TOML forbids duplicate keys, and a later-line search would be too loose).
45
+ *
46
+ * @param {string} tomlText
47
+ * @returns {ParsedCodexModel}
48
+ */
49
+ export function parseTopLevelCodexModel(tomlText) {
50
+ if (typeof tomlText !== 'string')
51
+ return { model: null, reason: 'unparseable' };
52
+ // Strip a leading UTF-8 BOM so `model = "x"` still resolves.
53
+ let text = tomlText;
54
+ if (text.charCodeAt(0) === 0xfeff)
55
+ text = text.slice(1);
56
+ const lines = text.split(/\r?\n/);
57
+ for (const rawLine of lines) {
58
+ const line = rawLine.trimStart();
59
+ // A `[section]` (or `[[array.of.tables]]`) header ends the top-level
60
+ // scope — stop scanning; a model below this point is profile-scoped.
61
+ if (line.startsWith('['))
62
+ break;
63
+ // Comment lines (incl. a commented-out `#model = "x"`) are skipped.
64
+ if (line.startsWith('#'))
65
+ continue;
66
+ // Top-level `model` assignment? The key must be EXACTLY `model` —
67
+ // `\s*=` rejects `model_provider`, `models`, `mcp_model`, etc.
68
+ const assign = line.match(/^model\s*=\s*(.*)$/);
69
+ if (!assign)
70
+ continue;
71
+ // First top-level model line is decisive (fail-closed on malformed).
72
+ return parseQuotedValue(assign[1]);
73
+ }
74
+ return { model: null, reason: 'no_model_key' };
75
+ }
76
+ /**
77
+ * Parse a quoted TOML string value (the RHS of `model =`). Accepts a
78
+ * double-quoted basic string or a single-quoted literal string, each optionally
79
+ * followed by whitespace and/or an inline `# comment`. Any other shape
80
+ * (unquoted, unterminated, escaped, empty, or trailing non-comment junk) is
81
+ * fail-closed `unparseable`.
82
+ *
83
+ * @param {string} value — the text after `model\s*=\s*`.
84
+ * @returns {ParsedCodexModel}
85
+ */
86
+ function parseQuotedValue(value) {
87
+ const first = value[0];
88
+ if (first === '"') {
89
+ const m = value.match(/^"([^"\n]*)"(.*)$/);
90
+ if (!m)
91
+ return { model: null, reason: 'unparseable' }; // unterminated
92
+ const inner = m[1];
93
+ // A backslash means TOML escapes are in play — do NOT attempt to
94
+ // unescape; fail closed rather than risk a wrong/truncated model.
95
+ if (inner.includes('\\'))
96
+ return { model: null, reason: 'unparseable' };
97
+ if (!isOnlyTrailingComment(m[2]))
98
+ return { model: null, reason: 'unparseable' };
99
+ if (inner.length === 0)
100
+ return { model: null, reason: 'unparseable' };
101
+ return { model: inner, reason: null };
102
+ }
103
+ if (first === "'") {
104
+ // TOML literal strings carry no escapes.
105
+ const m = value.match(/^'([^'\n]*)'(.*)$/);
106
+ if (!m)
107
+ return { model: null, reason: 'unparseable' };
108
+ const inner = m[1];
109
+ if (!isOnlyTrailingComment(m[2]))
110
+ return { model: null, reason: 'unparseable' };
111
+ if (inner.length === 0)
112
+ return { model: null, reason: 'unparseable' };
113
+ return { model: inner, reason: null };
114
+ }
115
+ // Unquoted / bare value — codex `model` is always a quoted string; bias
116
+ // fail-closed so a malformed line never yields a wrong model.
117
+ return { model: null, reason: 'unparseable' };
118
+ }
119
+ /**
120
+ * The text after a closing quote must be empty, whitespace, or an inline
121
+ * `# comment`. Anything else is malformed → fail closed.
122
+ *
123
+ * @param {string} rest
124
+ * @returns {boolean}
125
+ */
126
+ function isOnlyTrailingComment(rest) {
127
+ const t = rest.trimStart();
128
+ return t === '' || t.startsWith('#');
129
+ }
130
+ /**
131
+ * @typedef {Object} CodexSparModelResolution
132
+ * @property {boolean} available — true iff a live top-level model resolved.
133
+ * @property {string|null} model — the resolved model, or null when unavailable.
134
+ * @property {string} source — the config source label (`~/.codex/config.toml`).
135
+ * @property {null|'config_missing'|'no_model_key'|'unparseable'} reason
136
+ */
137
+ /**
138
+ * Read `<home>/.codex/config.toml` LIVE and resolve the top-level model.
139
+ * Fail-closed (Decision C / ID-03): a missing file, a missing top-level `model`
140
+ * key, or an unparseable value returns `available: false` with a machine reason
141
+ * and `model: null`. It NEVER substitutes a default. There is no module-level
142
+ * cached value — the file is re-read on every call.
143
+ *
144
+ * `existsSync` / `readFileSync` are injected so tests stay hermetic (no real
145
+ * `$HOME` read).
146
+ *
147
+ * @param {{ home: string, existsSync: (p: string) => boolean, readFileSync: (p: string, enc: string) => string }} deps
148
+ * @returns {CodexSparModelResolution}
149
+ */
150
+ export function resolveCodexSparModel({ home, existsSync, readFileSync }) {
151
+ const source = CODEX_CONFIG_SOURCE;
152
+ const configPath = join(home, '.codex', 'config.toml');
153
+ if (!existsSync(configPath)) {
154
+ return { available: false, model: null, source, reason: 'config_missing' };
155
+ }
156
+ let text;
157
+ try {
158
+ text = readFileSync(configPath, 'utf-8');
159
+ }
160
+ catch {
161
+ return { available: false, model: null, source, reason: 'config_missing' };
162
+ }
163
+ const { model, reason } = parseTopLevelCodexModel(text);
164
+ if (model) {
165
+ return { available: true, model, source, reason: null };
166
+ }
167
+ return { available: false, model: null, source, reason: reason ?? 'unparseable' };
168
+ }
169
+ //# sourceMappingURL=codex-config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-config.mjs","sourceRoot":"","sources":["../../../src/cli/host/codex-config.mjs"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"legacy-paths.d.mts","sourceRoot":"","sources":["../../../src/cli/install/legacy-paths.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;;GAMG;AAEH,gDAAgD;AAChD,mCADW,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAsJ1C;;kBA5JY,MAAM;kBACN,MAAM;;;;;qBAEN,aAAa,CAAC,MAAM,CAAC"}
1
+ {"version":3,"file":"legacy-paths.d.mts","sourceRoot":"","sources":["../../../src/cli/install/legacy-paths.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;;GAMG;AAEH,gDAAgD;AAChD,mCADW,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAwJ1C;;kBA9JY,MAAM;kBACN,MAAM;;;;;qBAEN,aAAa,CAAC,MAAM,CAAC"}
@@ -106,6 +106,7 @@ export const LEGACY_INSTALL_PATHS = Object.freeze({
106
106
  'agents/apt-personas.md',
107
107
  'agents/apt-plan.md',
108
108
  'agents/apt-pr-review.md',
109
+ 'agents/apt-produce.md',
109
110
  'agents/apt-prototype.md',
110
111
  'agents/apt-quick.md',
111
112
  'agents/apt-release-notes.md',
@@ -151,6 +152,7 @@ export const LEGACY_INSTALL_PATHS = Object.freeze({
151
152
  'commands/apt-personas.md',
152
153
  'commands/apt-plan.md',
153
154
  'commands/apt-pr-review.md',
155
+ 'commands/apt-produce.md',
154
156
  'commands/apt-prototype.md',
155
157
  'commands/apt-quick.md',
156
158
  'commands/apt-release-notes.md',
@@ -1 +1 @@
1
- {"version":3,"file":"legacy-paths.mjs","sourceRoot":"","sources":["../../../src/cli/install/legacy-paths.mjs"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"legacy-paths.mjs","sourceRoot":"","sources":["../../../src/cli/install/legacy-paths.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /** The probes/<milestone>.json path for a run + milestone. */
2
+ export function probeSetPathFor(projectDir: any, runId: any, milestoneId: any): string;
3
+ /** Read + parse a frozen probe set. Returns null when absent or malformed. */
4
+ export function readProbeSet(projectDir: any, runId: any, milestoneId: any): any;
5
+ /**
6
+ * Freeze a blind-probe set for a milestone, idempotently. REFUSES fail-closed
7
+ * when the author family equals the implementer family (a held-out probe an
8
+ * implementer authored is not held out — ID-06) or when no implementer family
9
+ * is recorded (ID-M2-02). On a FRESH freeze appends `produce.probe.frozen`
10
+ * carrying ONLY the hash + author family (never the content). A second freeze
11
+ * returns the byte-identical stored set (`reused: true`) and never re-logs.
12
+ *
13
+ * @param {string} projectDir
14
+ * @param {string} runId
15
+ * @param {string} milestoneId
16
+ * @param {{ content: unknown, authorFamily: string, implementerFamily: string }} args
17
+ * @param {Date} [now]
18
+ * @returns {{ ok: true, reused: boolean, probe_set_hash: string, author_family: string }
19
+ * | { ok: false, reason: string }}
20
+ */
21
+ export function freezeProbeSet(projectDir: string, runId: string, milestoneId: string, { content, authorFamily, implementerFamily }: {
22
+ content: unknown;
23
+ authorFamily: string;
24
+ implementerFamily: string;
25
+ }, now?: Date): {
26
+ ok: true;
27
+ reused: boolean;
28
+ probe_set_hash: string;
29
+ author_family: string;
30
+ } | {
31
+ ok: false;
32
+ reason: string;
33
+ };
34
+ /**
35
+ * Record a blind-probe RUN result. REFUSES fail-closed when the probe family
36
+ * equals the implementer family (a probe run BY the implementer family is not
37
+ * cross-family — ID-08) or when no implementer family is recorded. On
38
+ * acceptance appends `produce.probe.run {run_id, milestone_id, result,
39
+ * probe_family, head_sha}` — result/family/head_sha only, never content.
40
+ *
41
+ * @param {string} projectDir
42
+ * @param {{ runId: string, milestoneId: string, result: string, probeFamily: string, headSha: string }} args
43
+ * @returns {{ ok: true, result: string, probe_family: string, head_sha: string }
44
+ * | { ok: false, reason: string }}
45
+ */
46
+ export function recordProbeRun(projectDir: string, { runId, milestoneId, result, probeFamily, headSha }: {
47
+ runId: string;
48
+ milestoneId: string;
49
+ result: string;
50
+ probeFamily: string;
51
+ headSha: string;
52
+ }): {
53
+ ok: true;
54
+ result: string;
55
+ probe_family: string;
56
+ head_sha: string;
57
+ } | {
58
+ ok: false;
59
+ reason: string;
60
+ };
61
+ /**
62
+ * Select a DETERMINISTIC rotating sample of already-`done` milestones for blind
63
+ * re-probing against HEAD (US-6). Rotates by fewest prior probe runs first,
64
+ * then oldest last-probe-run first (a never-probed done milestone sorts first),
65
+ * then first-seen roadmap order — so two folds of the same log select the same
66
+ * sample.
67
+ *
68
+ * @param {string} projectDir
69
+ * @param {string} runId
70
+ * @param {{ sample?: number }} [opts]
71
+ * @returns {{ run_id: string, sample_size: number, selected: Array<{ milestone_id: string, title: string, probe_run_count: number, last_probe_run_at: string | null }> }}
72
+ */
73
+ export function selectSweepSample(projectDir: string, runId: string, { sample }?: {
74
+ sample?: number;
75
+ }): {
76
+ run_id: string;
77
+ sample_size: number;
78
+ selected: Array<{
79
+ milestone_id: string;
80
+ title: string;
81
+ probe_run_count: number;
82
+ last_probe_run_at: string | null;
83
+ }>;
84
+ };
85
+ //# sourceMappingURL=blind-probe.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blind-probe.d.mts","sourceRoot":"","sources":["../../../src/cli/produce/blind-probe.mjs"],"names":[],"mappings":"AA4CA,8DAA8D;AAC9D,uFAEC;AAED,8EAA8E;AAC9E,iFAQC;AAkBD;;;;;;;;;;;;;;;GAeG;AACH,2CARW,MAAM,SACN,MAAM,eACN,MAAM,gDACN;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,QACrE,IAAI,GACF;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgEnC;AAED;;;;;;;;;;;GAWG;AACH,2CALW,MAAM,wDACN;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1F;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAqBnC;AAED;;;;;;;;;;;GAWG;AACH,8CALW,MAAM,SACN,MAAM,eACN;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAA;CAAE,CA6CxK"}