@aperant/framework 0.8.1 → 0.8.6

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 (308) hide show
  1. package/CHANGELOG.md +443 -1
  2. package/agents/apt-planner.md +39 -7
  3. package/dist/cli/commands/adr.mjs +1 -1
  4. package/dist/cli/commands/audit-branch-current.d.mts +25 -0
  5. package/dist/cli/commands/audit-branch-current.d.mts.map +1 -0
  6. package/dist/cli/commands/audit-branch-current.mjs +252 -0
  7. package/dist/cli/commands/audit-branch-current.mjs.map +1 -0
  8. package/dist/cli/commands/audit.d.mts.map +1 -1
  9. package/dist/cli/commands/audit.mjs +13 -2
  10. package/dist/cli/commands/audit.mjs.map +1 -1
  11. package/dist/cli/commands/check-version.d.mts.map +1 -1
  12. package/dist/cli/commands/check-version.mjs +19 -1
  13. package/dist/cli/commands/check-version.mjs.map +1 -1
  14. package/dist/cli/commands/context.mjs +3 -3
  15. package/dist/cli/commands/context.mjs.map +1 -1
  16. package/dist/cli/commands/coverage-check.d.mts.map +1 -1
  17. package/dist/cli/commands/coverage-check.mjs +74 -7
  18. package/dist/cli/commands/coverage-check.mjs.map +1 -1
  19. package/dist/cli/commands/detect-runtime.d.mts +6 -0
  20. package/dist/cli/commands/detect-runtime.d.mts.map +1 -0
  21. package/dist/cli/commands/detect-runtime.mjs +142 -0
  22. package/dist/cli/commands/detect-runtime.mjs.map +1 -0
  23. package/dist/cli/commands/driver-doctor.d.mts +29 -0
  24. package/dist/cli/commands/driver-doctor.d.mts.map +1 -0
  25. package/dist/cli/commands/driver-doctor.mjs +291 -0
  26. package/dist/cli/commands/driver-doctor.mjs.map +1 -0
  27. package/dist/cli/commands/gate.mjs +14 -0
  28. package/dist/cli/commands/gate.mjs.map +1 -1
  29. package/dist/cli/commands/init.d.mts.map +1 -1
  30. package/dist/cli/commands/init.mjs +9 -6
  31. package/dist/cli/commands/init.mjs.map +1 -1
  32. package/dist/cli/commands/install-from-source.d.mts +2 -0
  33. package/dist/cli/commands/install-from-source.d.mts.map +1 -0
  34. package/dist/cli/commands/install-from-source.mjs +2 -0
  35. package/dist/cli/commands/install-from-source.mjs.map +1 -0
  36. package/dist/cli/commands/modes.mjs +1 -1
  37. package/dist/cli/commands/route.d.mts.map +1 -1
  38. package/dist/cli/commands/route.mjs +38 -1
  39. package/dist/cli/commands/route.mjs.map +1 -1
  40. package/dist/cli/commands/triage.mjs +1 -1
  41. package/dist/cli/config/load.d.mts.map +1 -1
  42. package/dist/cli/config/load.mjs +9 -3
  43. package/dist/cli/config/load.mjs.map +1 -1
  44. package/dist/cli/coordination/auto-emit-artifact-ready.mjs +1 -1
  45. package/dist/cli/coordination/event-schema.d.mts.map +1 -1
  46. package/dist/cli/coordination/event-schema.mjs +18 -0
  47. package/dist/cli/coordination/event-schema.mjs.map +1 -1
  48. package/dist/cli/coverage-check/user-outcomes.d.mts +84 -0
  49. package/dist/cli/coverage-check/user-outcomes.d.mts.map +1 -0
  50. package/dist/cli/coverage-check/user-outcomes.mjs +265 -0
  51. package/dist/cli/coverage-check/user-outcomes.mjs.map +1 -0
  52. package/dist/cli/dispatch.d.mts.map +1 -1
  53. package/dist/cli/dispatch.mjs +18 -1
  54. package/dist/cli/dispatch.mjs.map +1 -1
  55. package/dist/cli/gate/context.d.mts +1 -0
  56. package/dist/cli/gate/context.d.mts.map +1 -1
  57. package/dist/cli/gate/context.mjs +14 -1
  58. package/dist/cli/gate/context.mjs.map +1 -1
  59. package/dist/cli/gate/gates/consistency-check.d.mts +1 -0
  60. package/dist/cli/gate/gates/consistency-check.d.mts.map +1 -1
  61. package/dist/cli/gate/gates/consistency-check.mjs +1 -0
  62. package/dist/cli/gate/gates/consistency-check.mjs.map +1 -1
  63. package/dist/cli/gate/gates/review-clean.d.mts +1 -0
  64. package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
  65. package/dist/cli/gate/gates/review-clean.mjs +1 -0
  66. package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
  67. package/dist/cli/gate/gates/verify-approved.d.mts +1 -0
  68. package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
  69. package/dist/cli/gate/gates/verify-approved.mjs +1 -0
  70. package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
  71. package/dist/cli/gate/registry.d.mts.map +1 -1
  72. package/dist/cli/gate/registry.mjs +9 -1
  73. package/dist/cli/gate/registry.mjs.map +1 -1
  74. package/dist/cli/host/detect.mjs +1 -1
  75. package/dist/cli/host/detect.mjs.map +1 -1
  76. package/dist/cli/install/find-workspace-framework-version.d.mts +16 -0
  77. package/dist/cli/install/find-workspace-framework-version.d.mts.map +1 -0
  78. package/dist/cli/install/find-workspace-framework-version.mjs +85 -0
  79. package/dist/cli/install/find-workspace-framework-version.mjs.map +1 -0
  80. package/dist/cli/install/install-from-source.d.mts +10 -0
  81. package/dist/cli/install/install-from-source.d.mts.map +1 -0
  82. package/dist/cli/install/install-from-source.mjs +271 -0
  83. package/dist/cli/install/install-from-source.mjs.map +1 -0
  84. package/dist/cli/install/install-kernel.d.mts.map +1 -1
  85. package/dist/cli/install/install-kernel.mjs +24 -0
  86. package/dist/cli/install/install-kernel.mjs.map +1 -1
  87. package/dist/cli/install/legacy-paths.d.mts +33 -11
  88. package/dist/cli/install/legacy-paths.d.mts.map +1 -1
  89. package/dist/cli/install/legacy-paths.mjs +163 -39
  90. package/dist/cli/install/legacy-paths.mjs.map +1 -1
  91. package/dist/cli/install/runtime-detect.mjs +1 -1
  92. package/dist/cli/install/runtime-detect.mjs.map +1 -1
  93. package/dist/cli/install/runtime-migrate.d.mts +34 -14
  94. package/dist/cli/install/runtime-migrate.d.mts.map +1 -1
  95. package/dist/cli/install/runtime-migrate.mjs +63 -30
  96. package/dist/cli/install/runtime-migrate.mjs.map +1 -1
  97. package/dist/cli/install/transforms/codex.d.mts.map +1 -1
  98. package/dist/cli/install/transforms/codex.mjs +28 -17
  99. package/dist/cli/install/transforms/codex.mjs.map +1 -1
  100. package/dist/cli/skill-author/contract.mjs +2 -2
  101. package/dist/cli/skill-author/contract.mjs.map +1 -1
  102. package/dist/cli/verify-proof/audit.d.mts +34 -0
  103. package/dist/cli/verify-proof/audit.d.mts.map +1 -0
  104. package/dist/cli/verify-proof/audit.mjs +53 -0
  105. package/dist/cli/verify-proof/audit.mjs.map +1 -0
  106. package/dist/cli/verify-proof/exec.d.mts +20 -0
  107. package/dist/cli/verify-proof/exec.d.mts.map +1 -0
  108. package/dist/cli/verify-proof/exec.mjs +74 -0
  109. package/dist/cli/verify-proof/exec.mjs.map +1 -0
  110. package/dist/cli/verify-proof/idl/index.d.mts +2 -0
  111. package/dist/cli/verify-proof/idl/index.d.mts.map +1 -0
  112. package/dist/cli/verify-proof/idl/index.mjs +13 -0
  113. package/dist/cli/verify-proof/idl/index.mjs.map +1 -0
  114. package/dist/cli/verify-proof/idl/types.d.ts +10 -0
  115. package/dist/cli/verify-proof/idl/types.d.ts.map +1 -0
  116. package/dist/cli/verify-proof/idl/types.js +10 -0
  117. package/dist/cli/verify-proof/idl/types.js.map +1 -0
  118. package/dist/cli/verify-proof/manifest-validator.d.mts +19 -0
  119. package/dist/cli/verify-proof/manifest-validator.d.mts.map +1 -0
  120. package/dist/cli/verify-proof/manifest-validator.mjs +182 -0
  121. package/dist/cli/verify-proof/manifest-validator.mjs.map +1 -0
  122. package/dist/cli/verify-proof/resolver.d.mts +105 -0
  123. package/dist/cli/verify-proof/resolver.d.mts.map +1 -0
  124. package/dist/cli/verify-proof/resolver.mjs +320 -0
  125. package/dist/cli/verify-proof/resolver.mjs.map +1 -0
  126. package/dist/cli/verify-proof/runtime-detect.d.mts +30 -0
  127. package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -0
  128. package/dist/cli/verify-proof/runtime-detect.mjs +209 -0
  129. package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -0
  130. package/dist/cli/verify-proof/trust.d.mts +70 -0
  131. package/dist/cli/verify-proof/trust.d.mts.map +1 -0
  132. package/dist/cli/verify-proof/trust.mjs +174 -0
  133. package/dist/cli/verify-proof/trust.mjs.map +1 -0
  134. package/dist/driver-sdk/conformance.d.ts +41 -0
  135. package/dist/driver-sdk/conformance.d.ts.map +1 -0
  136. package/dist/driver-sdk/conformance.js +123 -0
  137. package/dist/driver-sdk/conformance.js.map +1 -0
  138. package/dist/driver-sdk/errors.d.ts +75 -0
  139. package/dist/driver-sdk/errors.d.ts.map +1 -0
  140. package/dist/driver-sdk/errors.js +80 -0
  141. package/dist/driver-sdk/errors.js.map +1 -0
  142. package/dist/driver-sdk/idl.d.ts +221 -0
  143. package/dist/driver-sdk/idl.d.ts.map +1 -0
  144. package/dist/driver-sdk/idl.js +140 -0
  145. package/dist/driver-sdk/idl.js.map +1 -0
  146. package/dist/driver-sdk/index.d.ts +28 -0
  147. package/dist/driver-sdk/index.d.ts.map +1 -0
  148. package/dist/driver-sdk/index.js +28 -0
  149. package/dist/driver-sdk/index.js.map +1 -0
  150. package/dist/driver-sdk/manifest.d.ts +93 -0
  151. package/dist/driver-sdk/manifest.d.ts.map +1 -0
  152. package/dist/driver-sdk/manifest.js +12 -0
  153. package/dist/driver-sdk/manifest.js.map +1 -0
  154. package/dist/driver-sdk/retry.d.ts +33 -0
  155. package/dist/driver-sdk/retry.d.ts.map +1 -0
  156. package/dist/driver-sdk/retry.js +50 -0
  157. package/dist/driver-sdk/retry.js.map +1 -0
  158. package/dist/plugin/.claude-plugin/plugin.json +4 -1
  159. package/dist/plugin/agents/apt-planner.md +39 -7
  160. package/dist/plugin/skills/apt/SKILL.md +75 -6
  161. package/dist/plugin/skills/apt-caveman/SKILL.md +64 -0
  162. package/dist/plugin/skills/apt-debug/SKILL.md +36 -4
  163. package/dist/plugin/skills/apt-debug/appendices/diagnose-discipline.md +2 -11
  164. package/dist/plugin/skills/apt-discuss/SKILL.md +4 -4
  165. package/dist/plugin/skills/apt-discuss/appendices/grill-discipline.md +2 -11
  166. package/dist/plugin/skills/apt-discuss/appendices/zoom-out-helper.md +0 -8
  167. package/dist/plugin/skills/apt-execute/SKILL.md +27 -4
  168. package/dist/plugin/skills/apt-execute/appendices/tdd-mode.md +2 -10
  169. package/dist/plugin/skills/apt-fan-out/SKILL.md +36 -1
  170. package/dist/plugin/skills/apt-handoff/SKILL.md +228 -0
  171. package/dist/plugin/skills/apt-improve/DEEPENING.md +0 -8
  172. package/dist/plugin/skills/apt-improve/INTERFACE-DESIGN.md +0 -8
  173. package/dist/plugin/skills/apt-improve/LANGUAGE.md +0 -8
  174. package/dist/plugin/skills/apt-improve/SKILL.md +4 -4
  175. package/dist/plugin/skills/apt-plan/SKILL.md +73 -5
  176. package/dist/plugin/skills/apt-plan/adapters/conductor.md +1 -1
  177. package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -1
  178. package/dist/plugin/skills/apt-prototype/LOGIC.md +0 -8
  179. package/dist/plugin/skills/apt-prototype/SKILL.md +4 -4
  180. package/dist/plugin/skills/apt-prototype/UI.md +0 -8
  181. package/dist/plugin/skills/apt-quick/SKILL.md +31 -1
  182. package/dist/plugin/skills/apt-research/SKILL.md +526 -0
  183. package/dist/plugin/skills/apt-research/appendices/budget-loop.md +397 -0
  184. package/dist/plugin/skills/apt-research/appendices/claim-graph-schema.md +206 -0
  185. package/dist/plugin/skills/apt-research/appendices/domain-tools.md +236 -0
  186. package/dist/plugin/skills/apt-resume/SKILL.md +54 -31
  187. package/dist/plugin/skills/apt-run/SKILL.md +114 -16
  188. package/dist/plugin/skills/apt-setup/SKILL.md +97 -8
  189. package/dist/plugin/skills/apt-ship/SKILL.md +165 -9
  190. package/dist/plugin/skills/apt-spar/SKILL.md +84 -23
  191. package/dist/plugin/skills/apt-triage/AGENT-BRIEF.md +0 -8
  192. package/dist/plugin/skills/apt-triage/OUT-OF-SCOPE.md +0 -7
  193. package/dist/plugin/skills/apt-triage/SKILL.md +2 -2
  194. package/dist/plugin/skills/apt-update/SKILL.md +74 -17
  195. package/dist/plugin/skills/apt-verify-proof/SKILL.md +87 -1
  196. package/dist/plugin/skills/apt-zoom-out/SKILL.md +3 -3
  197. package/dist/schemas/quick-task.d.ts +17 -17
  198. package/dist/schemas/quick-task.d.ts.map +1 -1
  199. package/dist/schemas/quick-task.js +2 -2
  200. package/dist/schemas/quick-task.js.map +1 -1
  201. package/dist/types/config.d.ts +33 -0
  202. package/dist/types/config.d.ts.map +1 -1
  203. package/dist/types/state.d.ts +1 -1
  204. package/dist/types/state.d.ts.map +1 -1
  205. package/dist/types/task-record.d.ts +1 -1
  206. package/dist/types/task-record.d.ts.map +1 -1
  207. package/drivers/.gitkeep +0 -0
  208. package/drivers/api/README.md +40 -0
  209. package/drivers/api/driver.mjs +59 -0
  210. package/drivers/api/manifest.json +26 -0
  211. package/drivers/browser/README.md +105 -0
  212. package/drivers/browser/driver.mjs +134 -0
  213. package/drivers/browser/manifest.json +35 -0
  214. package/drivers/cli/README.md +44 -0
  215. package/drivers/cli/driver.mjs +62 -0
  216. package/drivers/cli/manifest.json +28 -0
  217. package/drivers/electron/README.md +64 -0
  218. package/drivers/electron/driver.mjs +87 -0
  219. package/drivers/electron/manifest.json +37 -0
  220. package/package.json +138 -133
  221. package/prompts/planner.md +1 -1
  222. package/prompts/spec_writer.md +1 -1
  223. package/skills/apt/SKILL.md +75 -6
  224. package/skills/apt-caveman/SKILL.md +64 -0
  225. package/skills/apt-debug/SKILL.md +36 -4
  226. package/skills/apt-debug/appendices/diagnose-discipline.md +2 -11
  227. package/skills/apt-discuss/SKILL.md +4 -4
  228. package/skills/apt-discuss/appendices/grill-discipline.md +2 -11
  229. package/skills/apt-discuss/appendices/zoom-out-helper.md +0 -8
  230. package/skills/apt-execute/SKILL.md +27 -4
  231. package/skills/apt-execute/appendices/tdd-mode.md +2 -10
  232. package/skills/apt-fan-out/SKILL.md +36 -1
  233. package/skills/apt-handoff/SKILL.md +228 -0
  234. package/skills/apt-improve/DEEPENING.md +0 -8
  235. package/skills/apt-improve/INTERFACE-DESIGN.md +0 -8
  236. package/skills/apt-improve/LANGUAGE.md +0 -8
  237. package/skills/apt-improve/SKILL.md +4 -4
  238. package/skills/apt-plan/SKILL.md +73 -5
  239. package/skills/apt-plan/adapters/conductor.md +1 -1
  240. package/skills/apt-planner.md +17 -1
  241. package/skills/apt-pr-review/SKILL.md +1 -1
  242. package/skills/apt-prototype/LOGIC.md +0 -8
  243. package/skills/apt-prototype/SKILL.md +4 -4
  244. package/skills/apt-prototype/UI.md +0 -8
  245. package/skills/apt-quick/SKILL.md +31 -1
  246. package/skills/apt-research/SKILL.md +526 -0
  247. package/skills/apt-research/appendices/budget-loop.md +397 -0
  248. package/skills/apt-research/appendices/claim-graph-schema.md +206 -0
  249. package/skills/apt-research/appendices/domain-tools.md +236 -0
  250. package/skills/apt-resume/SKILL.md +54 -31
  251. package/skills/apt-run/SKILL.md +114 -16
  252. package/skills/apt-setup/SKILL.md +97 -8
  253. package/skills/apt-ship/SKILL.md +165 -9
  254. package/skills/apt-spar/SKILL.md +84 -23
  255. package/skills/apt-triage/AGENT-BRIEF.md +0 -8
  256. package/skills/apt-triage/OUT-OF-SCOPE.md +0 -7
  257. package/skills/apt-triage/SKILL.md +2 -2
  258. package/skills/apt-update/SKILL.md +74 -17
  259. package/skills/apt-verify-proof/SKILL.md +87 -1
  260. package/skills/apt-zoom-out/SKILL.md +3 -3
  261. package/src/cli/commands/adr.mjs +1 -1
  262. package/src/cli/commands/audit-branch-current.mjs +250 -0
  263. package/src/cli/commands/audit.mjs +13 -2
  264. package/src/cli/commands/check-version.mjs +20 -1
  265. package/src/cli/commands/context.mjs +3 -3
  266. package/src/cli/commands/coverage-check.mjs +126 -44
  267. package/src/cli/commands/detect-runtime.mjs +143 -0
  268. package/src/cli/commands/driver-doctor.mjs +294 -0
  269. package/src/cli/commands/gate.mjs +15 -0
  270. package/src/cli/commands/init.mjs +9 -6
  271. package/src/cli/commands/install-from-source.mjs +1 -0
  272. package/src/cli/commands/modes.mjs +1 -1
  273. package/src/cli/commands/route.mjs +42 -1
  274. package/src/cli/commands/triage.mjs +1 -1
  275. package/src/cli/config/load.mjs +9 -3
  276. package/src/cli/coordination/auto-emit-artifact-ready.mjs +1 -1
  277. package/src/cli/coordination/event-schema.mjs +19 -0
  278. package/src/cli/coverage-check/user-outcomes.mjs +273 -0
  279. package/src/cli/dispatch.mjs +17 -1
  280. package/src/cli/gate/context.mjs +20 -1
  281. package/src/cli/gate/gates/consistency-check.mjs +1 -0
  282. package/src/cli/gate/gates/review-clean.mjs +1 -0
  283. package/src/cli/gate/gates/verify-approved.mjs +1 -0
  284. package/src/cli/gate/registry.mjs +11 -1
  285. package/src/cli/host/detect.mjs +1 -1
  286. package/src/cli/install/find-workspace-framework-version.mjs +88 -0
  287. package/src/cli/install/install-from-source.mjs +276 -0
  288. package/src/cli/install/install-kernel.mjs +24 -0
  289. package/src/cli/install/legacy-paths.mjs +164 -39
  290. package/src/cli/install/runtime-detect.mjs +1 -1
  291. package/src/cli/install/runtime-migrate.mjs +63 -30
  292. package/src/cli/install/transforms/codex.mjs +26 -17
  293. package/src/cli/skill-author/contract.mjs +2 -2
  294. package/src/cli/verify-proof/.gitkeep +0 -0
  295. package/src/cli/verify-proof/audit.mjs +55 -0
  296. package/src/cli/verify-proof/exec.mjs +74 -0
  297. package/src/cli/verify-proof/idl/index.mjs +23 -0
  298. package/src/cli/verify-proof/idl/types.ts +42 -0
  299. package/src/cli/verify-proof/manifest-schema.json +212 -0
  300. package/src/cli/verify-proof/manifest-validator.mjs +184 -0
  301. package/src/cli/verify-proof/resolver.mjs +330 -0
  302. package/src/cli/verify-proof/runtime-detect.mjs +211 -0
  303. package/src/cli/verify-proof/trust.mjs +187 -0
  304. package/templates/adr-format.md +0 -8
  305. package/templates/aperant-claude-md-appendix.md +1 -1
  306. package/templates/context-format.md +1 -9
  307. package/templates/proof-verification.md +51 -8
  308. package/workflows/verify-proof.md +130 -19
@@ -0,0 +1,526 @@
1
+ ---
2
+ name: apt:research
3
+ description: "Multi-source research (UNDERSTAND/VERIFY/SOLVE/COMPARE) with --budget background loop. Claim-graph state, 4 agents per iteration (Builder/Skeptic/Retriever/Judge), domain-gated spar + first-principles, citation audit, converged-vs-stalled verdicts."
4
+ apt-skill-version: {{APT_VERSION}}
5
+ stage: plan
6
+ intent: investigate
7
+ when_to_use: "The user wants multi-source research with explicit confidence and contradiction surfacing — understand a topic, verify a belief, decompose a novel problem, or compare options. NOT for codebase-only questions (use /apt:zoom-out) and NOT for refactor discovery (use /apt:improve)."
8
+ user_invocable: true
9
+ internal: false
10
+ spawns_agent: true
11
+ agent_name: "apt-researcher"
12
+ task_context: create-new
13
+ default_track: STANDARD
14
+ default_execution_mode: step
15
+ execution_modes:
16
+ - auto
17
+ - step
18
+ - research
19
+ allowed-tools: "Bash, Read, Grep, Glob, Write, WebSearch, WebFetch, Task"
20
+ argument-hint: "apt:research [--understand|--verify|--solve|--compare] [--budget <duration>|--overnight|--weekend|--background|--no-budget] [--resume <task-id>] [topic]"
21
+ gates: []
22
+ triggers:
23
+ - /apt:research
24
+ - apt:research
25
+ produces:
26
+ - immutable research-spec.md (success-criterion oracle)
27
+ - claims.json + sources.json (claim graph with conditions, dependencies, tiers)
28
+ - RESEARCH.md synthesis with domain-gated output template
29
+ - progress.log (tail-able per-iteration heartbeat)
30
+ - dual-state verdict (converged | stalled) with calibration report
31
+ ---
32
+
33
+ <critical>
34
+ - The research spec is **immutable** after Step 3. It is the success-criterion oracle. You may not edit it to make findings pass.
35
+ - State is a **claim graph** (`claims.json` + `sources.json`), NOT a flat ledger. Every claim carries source tier, conditions, dependencies, evidence-for, evidence-against, and status. Flat-list rationalizations are rejected.
36
+ - Priority for the next attack is `impact × centrality × uncertainty`. NEVER "lowest confidence first" — high-confidence load-bearing claims get attacked early, not late.
37
+ - Per iteration, FOUR agents run with isolated contexts and distinct objectives: **Builder** (synthesize), **Skeptic** (falsify the most load-bearing claim), **Retriever** (new evidence only, no opinion), **Judge** (update statuses with evidence deltas). Single-agent shortcuts are rejected.
38
+ - First-principles derivation is **domain-gated**. Enabled for mechanistic domains (physics, distributed systems, algorithms). Disabled for empirical/social domains (medicine, market research, lore) — output from a first-principles agent in those domains is demoted to `hypothesis` rows that cannot reach `confidence: high`.
39
+ - Spar with a second LLM is **trigger-gated**, not clock-gated. Spar fires on: tier-1 conflict, high-impact claim unresolved for 2+ iterations, or vendor-only evidence. Each spar MUST produce a concrete claim status change with citation diff, NOT a debate summary.
40
+ - Citation-audit pass runs every N iterations (default 4). It re-fetches the source for top load-bearing claims and verifies the quoted text. Failures are quarantined to `suspect-citations.md`, never silently dropped.
41
+ - Stop has two terminal states: **converged** (critical claims above threshold, no unresolved tier-1 conflicts, no untapped evidence frontier) and **stalled** (retrieval frontier exhausted, claims still contested — outputs "I cannot resolve this without X"). The skill MUST distinguish them in the verdict.
42
+ - A budget is a **CAP, not a target**. CONVERGED at hour 3 of an 8h budget exits cleanly; the saved compute is reported, NOT spent on extra iterations "just in case."
43
+ - Domain-aware output gates apply at synthesis time. Medical forces `## Not medical advice` + `## What this CAN'T tell you`. Strategic forces conditional-tree recommendation. Code-SOLVE blocks `converged` if no falsification attempt was run. Physics/empirical forces `## Evidence gaps`.
44
+ </critical>
45
+
46
+ <objective>
47
+ You are the Aperant research facilitator. You take a topic, claim, problem, or option set
48
+ and produce evidence-backed findings as a **claim graph** with explicit confidence,
49
+ source tiers, conditions, dependencies, and surfaced contradictions.
50
+
51
+ You operate in one of four modes, chosen by reading the user's input — never by asking:
52
+
53
+ - **UNDERSTAND** (deep topic) — build a mental model from multiple perspectives.
54
+ - **VERIFY** (fact/belief) — triangulate a claim across independently-derived sources.
55
+ - **SOLVE** (novel problem) — decompose, generate candidates, search for prior failures.
56
+ - **COMPARE** (options/tools) — fixed evaluation dimensions, parallel per-dimension fan-out.
57
+
58
+ Orthogonal to mode, the `--budget <duration>` flag (with aliases `--overnight`,
59
+ `--weekend`, `--background`) enables a time-boxed multi-iteration loop in the background.
60
+ See `appendices/budget-loop.md` for the loop discipline. Without any budget set,
61
+ the skill runs a single session capped at 5 iterations of the
62
+ Builder/Skeptic/Retriever/Judge cycle.
63
+
64
+ Domain detection (mechanistic / empirical / strategic / general) gates first-principles
65
+ reasoning, tool surface (see `appendices/domain-tools.md`), and output template. The
66
+ domain is detected in Step 1d and persisted to `research-spec.md`.
67
+
68
+ The `apt-researcher` agent runs the 4 specialized roles per iteration. The skill body
69
+ owns mode-detection, domain-detection, budget-detection, spec-writing, role orchestration,
70
+ the claim graph, citation audits, stop-state decisioning, and synthesis.
71
+ </objective>
72
+
73
+ <your_environment>
74
+ - **Working directory:** The project root (where you were invoked)
75
+ - **apt-tools path:** `node packages/framework/bin/apt-tools.mjs` or the locally installed `apt-tools` binary
76
+ - **Constitution:** Read `AGENTS.md` in the project root if it exists
77
+ - **Config:** `.aperant/config.json` — autonomy level, source-credibility overrides, citation-audit cadence, default budget cap if any
78
+ - **State:** `.aperant/state.json` — current execution state (active task, track, phase)
79
+ - **Agent:** `apt-researcher` (defined at `packages/framework/skills/apt-researcher.md`) — spawned 4× per iteration with role-specialized prompts
80
+ - **Web tools:** `WebSearch` and `WebFetch` for retrieval; `mcp__plugin_context7_context7__*` for library-doc lookups
81
+ - **Bash tools:** `curl` (Crossref/PubMed citation verify), `gh` (GitHub releases + code search when present), `pdftotext` if installed (PDF source reads)
82
+ - **Wake primitive:** `ScheduleWakeup` for `--budget` loop continuation (same pattern as `/apt:watch-ci`)
83
+ - **Sparring:** `/apt:spar` (invoked via Skill) when trigger conditions fire
84
+ </your_environment>
85
+
86
+ <state_files>
87
+ ## State Files
88
+
89
+ **Reads:**
90
+ - `AGENTS.md` — project constitution
91
+ - `.aperant/state.json` — current execution state
92
+ - `.aperant/config.json` — autonomy, citation-audit cadence, default budget cap
93
+ - `.aperant/context/notes/*.md` — prior locked decisions (may inform UNDERSTAND/SOLVE)
94
+ - `.aperant/research/*/research-spec.md` — prior research artifacts (cross-task reuse)
95
+ - `.aperant/research/{task-id}/research-spec.md` — immutable spec when resuming
96
+
97
+ **Writes:**
98
+ - `.aperant/research/{task-id}/research-spec.md` — **immutable** after Step 3 (success-criterion oracle, including detected `domain` and `budget`)
99
+ - `.aperant/research/{task-id}/claims.json` — claim graph (see `appendices/claim-graph-schema.md` for schema)
100
+ - `.aperant/research/{task-id}/sources.json` — source registry with tiers, fetch timestamps, verification timestamps
101
+ - `.aperant/research/{task-id}/RESEARCH.md` — domain-gated synthesis with status header (`OPEN | INVESTIGATING | SYNTHESIZING | CONVERGED | STALLED`)
102
+ - `.aperant/research/{task-id}/iteration-log.md` — append-only per-iteration record (which claims attacked, what each role produced, what Judge ruled)
103
+ - `.aperant/research/{task-id}/progress.log` — one line per iteration, tail-able heartbeat (timestamp, iter, budget used/cap, next attack, status)
104
+ - `.aperant/research/{task-id}/suspect-citations.md` — quarantined citations that failed verification
105
+ - `.aperant/research/{task-id}/findings/{source-slug}.md` — per-source extracted quotes (citation-audit substrate)
106
+ - `.aperant/research/{task-id}/deferred-angles.md` — parking lot for angles not pursued (resumable)
107
+ - `.aperant/research/{task-id}/spar/{round-slug}.md` — written when a spar round fires
108
+ </state_files>
109
+
110
+ <rationalization>
111
+ Common shortcuts an agent will be tempted to take — and why each is wrong:
112
+
113
+ - "I'll just keep a flat list of findings — the graph is overkill." → Flat ledgers
114
+ hide claim dependencies. When the load-bearing claim turns out wrong at iter 12, a
115
+ flat list can't tell you what else collapses. The graph is the audit trail that
116
+ makes long-running research honest. See `appendices/claim-graph-schema.md`.
117
+ - "Lowest confidence first, that's standard." → Wrong heuristic. A high-confidence
118
+ load-bearing claim ("Milliken's load-transfer model applies to no-diff karts")
119
+ that turns out misapplied destroys everything built on it. Priority is
120
+ `impact × centrality × uncertainty`. Attack what matters, not what's weakest.
121
+ - "One agent per iteration is enough — Builder and Skeptic in one prompt." → A
122
+ single agent self-rationalizes. Specialization (4 isolated agents with distinct
123
+ objectives) forces honest disagreement. Skipping this is the most expensive
124
+ shortcut — it manufactures false consensus over many iterations.
125
+ - "First-principles is always rigorous, run it every iteration." → False. In
126
+ empirical domains (medicine, market behavior), first-principles produces
127
+ plausible-sounding nonsense that empirical evidence then can't dislodge.
128
+ Gated by domain — see Step 1d + `appendices/domain-tools.md`.
129
+ - "Spar every 4 iterations gives free signal." → Spar between LLMs trained on
130
+ overlapping corpora is mostly theater. Trigger-gated spar (tier-1 conflict /
131
+ unresolved high-impact / vendor-only evidence) earns its keep. Clock-gated spar
132
+ wastes tokens and creates fake "resolutions" of fake conflicts.
133
+ - "I have an 8h budget; I should fill the 8h." → No. A budget is a cap. CONVERGED
134
+ at hour 3 stops cleanly. Continuing wastes compute and risks polishing a wrong
135
+ answer into a confident-wrong one. The loop reports remaining budget, never
136
+ spends it.
137
+ - "Three blog posts confirm it — that's triangulation." → All three may cite the
138
+ same primary source. Independence is about derivation chain. Run the citation
139
+ trace; if they all link back to one source, you have **one** source. The
140
+ `sources.json` schema captures this in the `derivation_chain` field.
141
+ - "Three no-mutation iterations means we converged — stop." → No. That signal
142
+ catches stuckness, not convergence. The skill distinguishes `converged`
143
+ (critical claims above threshold + no unresolved tier-1 conflicts + frontier
144
+ exhausted) from `stalled` (frontier exhausted but claims still contested).
145
+ Conflating them ships confident-wrong answers.
146
+ - "Citations look real — no need to verify." → Medical scenario showed that
147
+ in a long-running loop, fabricated DOIs land in the ledger and look real.
148
+ Citation audit re-fetches and quote-checks every N iterations. Failures
149
+ quarantine to `suspect-citations.md`. Without this, long runtime manufactures
150
+ unearned credibility.
151
+ - "I'll just edit research-spec.md to lower coverage thresholds so my findings
152
+ pass." → The spec is immutable because it's the oracle. If you can't meet it,
153
+ emit `stalled` with a `## Cannot resolve without` section. Never edit the
154
+ oracle.
155
+ - "Vendor docs say X works — that's authoritative." → Vendor claims need
156
+ independent confirmation. For COMPARE mode, vendor-only evidence is itself a
157
+ spar trigger (see `appendices/budget-loop.md` § trigger conditions).
158
+ </rationalization>
159
+
160
+ <autonomy_interaction>
161
+ This skill is non-destructive: it only writes to `.aperant/research/{task-id}/` and never
162
+ modifies application code. Safe at every autonomy level.
163
+
164
+ - **Autonomy 0 (plan-only):** Run Steps 1-4 (init, mode/domain/budget detect, spec,
165
+ decompose). Stop before Step 5. Print the spec + decomposition + planned tool surface +
166
+ resolved budget. Ask the user to confirm before spawning agents (token cost matters).
167
+ - **Autonomy 1 (ask-before-destructive):** Run the full single-session pipeline.
168
+ For any `--budget` ≥ 1h (overnight/weekend/background or explicit), ask before
169
+ scheduling the first wake-loop continuation (the budget is a real compute commitment).
170
+ Default 4-role-per-iter runs without asking.
171
+ - **Autonomy 2 (full auto):** Run the full pipeline including any `--budget` if
172
+ requested. Stop on terminal state (converged/stalled) or budget exhaustion.
173
+
174
+ Resume semantics: `--resume <task-id>` restores from `.aperant/research/{task-id}/`.
175
+ Bare `--resume` picks the most recently modified research directory. Resuming re-reads
176
+ `research-spec.md` (still immutable, including the locked `domain` and original `budget`)
177
+ and the claim graph, then continues from the status field in `RESEARCH.md` with the
178
+ remaining budget computed as `original_budget − elapsed`.
179
+
180
+ The wake-loop is the only continuation primitive — same as `/apt:watch-ci`.
181
+ The skill body schedules its own next wake via `ScheduleWakeup` at the end of each
182
+ iteration; the host CLI delivers the wake event. No daemons, no cross-CLI re-exec.
183
+ </autonomy_interaction>
184
+
185
+ <process>
186
+
187
+ ## 1. Initialize or Resume Session
188
+
189
+ 1a. **Canonical task-id.** Derive from `$ARGUMENTS` topic phrase (lowercase, hyphens,
190
+ ≤40 chars) OR from `--resume <task-id>`. If `--resume` with no value, pick the
191
+ most recently modified `.aperant/research/*/` directory.
192
+
193
+ 1b. **Create or load the task directory.** `mkdir -p .aperant/research/{task-id}/`.
194
+ If `research-spec.md` already exists (resume), read it — DO NOT regenerate.
195
+
196
+ 1c. **Status field.** If creating, write `RESEARCH.md` with `## Status: OPEN`.
197
+ If resuming, read the status and skip ahead: `OPEN` → Step 2; `INVESTIGATING` →
198
+ Step 5; `SYNTHESIZING` → Step 8; `CONVERGED` or `STALLED` → Step 10 (report only).
199
+
200
+ 1d. **Detect domain.** Read the question. Classify into ONE of four domains using
201
+ these signals (recorded in `research-spec.md` under `## Domain`, immutable):
202
+
203
+ | Domain | Signals | Tool surface |
204
+ |---|---|---|
205
+ | **mechanistic** | physics, math, distributed systems, algorithms, deterministic engineering systems | first-principles ENABLED; arxiv + PDF read |
206
+ | **empirical** | medicine, biology, nutrition, psychology, public-health, social science | first-principles GATED to `hypothesis` rows only; PubMed/Crossref citation verify REQUIRED |
207
+ | **strategic** | tool comparison, market analysis, vendor selection, license/contract evaluation | first-principles DISABLED; GitHub releases + license fetch; vendor-only is spar trigger |
208
+ | **general** | catch-all when none of the above fit | first-principles soft-enabled with `hypothesis` demotion; standard tool surface |
209
+
210
+ See `appendices/domain-tools.md` for the per-domain tool surface, output gates,
211
+ and demotion rules.
212
+
213
+ ## 2. Detect Mode + Budget
214
+
215
+ ### 2a. Mode
216
+
217
+ Read the user's input. Pick exactly ONE mode using these signals — never ask:
218
+
219
+ | Mode | Signals |
220
+ |------|---------|
221
+ | **UNDERSTAND** | "explain X", "how does X work", "deep dive on", topic-shaped noun phrase |
222
+ | **VERIFY** | "is it true that", "fact-check", "I believe X — confirm", claim-shaped sentence |
223
+ | **SOLVE** | "novel problem", "no known solution", "how can we", task-shaped open question |
224
+ | **COMPARE** | "X vs Y", "which tool for", enumeration of 2+ options |
225
+
226
+ Explicit flag (`--understand|--verify|--solve|--compare`) overrides signal detection.
227
+ Ambiguous input → UNDERSTAND (lowest-commitment posture).
228
+
229
+ ### 2b. Budget
230
+
231
+ Resolve the budget value using this precedence (highest wins):
232
+
233
+ | Source | Value |
234
+ |---|---|
235
+ | `--no-budget` flag | Force single-session mode (no wake-loop) |
236
+ | `--budget <duration>` flag | Use the explicit duration (`30m`, `4h`, `10h`, `2d` — bounds `1m`–`72h`) |
237
+ | `--overnight` flag | `8h` |
238
+ | `--weekend` flag | `48h` |
239
+ | `--background` flag | `4h` |
240
+ | Prose signal in `$ARGUMENTS` | See table below |
241
+ | `.aperant/config.json: research.default_budget` | If set |
242
+ | (nothing) | single-session mode |
243
+
244
+ Prose signal table (read input, never ask):
245
+
246
+ | Signal in user prose | Inferred budget |
247
+ |---|---|
248
+ | "overnight", "while I sleep", "by morning" | 8h |
249
+ | "weekend", "over the weekend", "by Monday" | 48h |
250
+ | "for N hours/days/minutes" (any explicit duration) | N |
251
+ | "while I'm at work", "during the day" | 8h |
252
+ | "in the background" | 4h |
253
+ | "really thoroughly", "deep dive", "question my beliefs", "take your time" | 4h |
254
+ | Decomposition would produce ≥8 sub-questions OR ≥3 contested perspectives (assess during Step 4) | 4h |
255
+
256
+ If a budget is resolved (non-zero), load `appendices/budget-loop.md` into reasoning
257
+ context. This appendix carries the per-iteration loop discipline, priority formula,
258
+ spar triggers, stop-state criteria, progress checkpoints, and wake-loop continuation.
259
+ Do not re-state its rules here.
260
+
261
+ ### 2c. Announce
262
+
263
+ Open with a one-line declaration that surfaces the resolved budget AND the signal
264
+ that produced it (so the user can override knowingly):
265
+
266
+ ```
267
+ [apt:research] {Mode} / {Domain}{ — budget {value} from {signal-source}}.
268
+ {Pass --budget <duration> to override or --no-budget to disable.}
269
+ ```
270
+
271
+ Examples:
272
+ ```
273
+ [apt:research] UNDERSTAND / mechanistic — budget 8h from signal "overnight".
274
+ Pass --budget <duration> to override or --no-budget to disable.
275
+
276
+ [apt:research] COMPARE / strategic — single-session (no budget set).
277
+ Pass --budget 4h or --background to escalate to a background loop.
278
+
279
+ [apt:research] VERIFY / empirical — budget 10h from --budget flag.
280
+ ```
281
+
282
+ ## 3. Write Immutable Research Spec
283
+
284
+ Write `.aperant/research/{task-id}/research-spec.md`. **Once written, this file is locked
285
+ for the rest of the session.** It is the success-criterion oracle.
286
+
287
+ Mandatory sections, ALL modes:
288
+
289
+ - `## Question` — the question in exact, falsifiable form
290
+ - `## Mode` — UNDERSTAND | VERIFY | SOLVE | COMPARE
291
+ - `## Domain` — mechanistic | empirical | strategic | general (from Step 1d)
292
+ - `## Budget` — duration value (e.g. `8h`) AND source (e.g. `signal: "overnight"` /
293
+ `flag: --weekend` / `none — single-session`)
294
+ - `## Sub-questions` — the decomposed questions retrieval must answer (filled in Step 4)
295
+ - `## Source requirements` — required source tiers and minimum count, per domain rules
296
+ - `## Critical claims` — claims that, if wrong, invalidate the synthesis (load-bearing).
297
+ These get explicit `impact: high` weighting in the priority formula.
298
+ - `## Stop rule` — domain-gated; defaults in `appendices/budget-loop.md` §stop-states
299
+ - `## Anti-patterns` — failure modes specific to this question (e.g. "do NOT cite
300
+ single-author benchmarks for tool comparison")
301
+ - `## Output template` — domain-gated synthesis sections (see `appendices/domain-tools.md`
302
+ §output-gates)
303
+
304
+ Print the spec to stdout for the user to see the commitment.
305
+
306
+ ## 4. Decompose Query
307
+
308
+ Mode-specific decomposition. Output is the input to Step 5 fan-out and the basis for the
309
+ initial claim graph nodes.
310
+
311
+ - **UNDERSTAND**: enumerate 5-8 perspectives (skeptic, practitioner, theorist, historian,
312
+ …) and generate one sub-question per perspective.
313
+ - **VERIFY**: generate 3-5 independent probes from different angles (primary docs,
314
+ community reports, attempted refutation, edge cases, independent reproduction).
315
+ - **SOLVE**: state the problem decomposition, then generate 2-3 candidate approaches.
316
+ Per candidate, generate a prior-art query AND a failure-mode query (mandatory).
317
+ - **COMPARE**: declare 4-6 evaluation dimensions UP FRONT (do not invent dimensions
318
+ mid-research). Each dimension × each option is one cell.
319
+
320
+ Initialize the claim graph (`claims.json`): one claim node per sub-question with
321
+ `status: open`, `confidence: low`, `centrality: 0`, computed `impact` from the
322
+ `## Critical claims` spec section.
323
+
324
+ Write the decomposition into `research-spec.md` under `## Sub-questions`. This finalizes
325
+ the spec.
326
+
327
+ **Late budget upgrade.** If Step 2b resolved no budget AND this decomposition produces
328
+ ≥8 sub-questions OR ≥3 contested perspectives, the prose-signal threshold has been met
329
+ mid-process. Print a one-line escalation offer and proceed in single-session mode unless
330
+ the user opted out (autonomy 0 stops here for confirmation anyway):
331
+
332
+ ```
333
+ [apt:research] Decomposition produced N sub-questions — this is a strong --background
334
+ (4h) candidate. Continuing in single-session mode. Pass --background or --budget 4h on
335
+ resume to escalate.
336
+ ```
337
+
338
+ ## 5. Run One Iteration (4 specialized agents)
339
+
340
+ Set `RESEARCH.md` status to `INVESTIGATING`. Append a one-line heartbeat to
341
+ `progress.log` (format defined in `appendices/budget-loop.md` §progress-checkpoints).
342
+
343
+ Pick the next claim to attack using the priority formula from
344
+ `appendices/budget-loop.md` §priority-formula:
345
+
346
+ ```
347
+ priority(claim) = impact(claim) × centrality(claim) × uncertainty(claim)
348
+ ```
349
+
350
+ Spawn FOUR `apt-researcher` agents **in a single message** for parallel execution.
351
+ Each gets a role-specialized prompt and isolated context. Role prompts and the
352
+ domain-aware tool surface are defined in `appendices/budget-loop.md` §agent-roles
353
+ and `appendices/domain-tools.md` respectively.
354
+
355
+ | Role | Objective | Tool surface | Forbidden |
356
+ |---|---|---|---|
357
+ | **Builder** | Advance the synthesis using current claim graph | full read + WebSearch/WebFetch + domain tools | falsifying claims |
358
+ | **Skeptic** | Falsify the chosen high-priority claim; produce explicit counter-evidence | full read + WebSearch/WebFetch + domain tools | confirming or hedging |
359
+ | **Retriever** | Find NEW evidence only (sources not yet in `sources.json`) | WebSearch/WebFetch + domain-specific search | opinion, synthesis |
360
+ | **Judge** | Read what Builder/Skeptic/Retriever produced; update claim statuses with evidence deltas | read-only: claims.json, the three returns | proposing new claims |
361
+
362
+ For the gated cases:
363
+ - Domain ≠ mechanistic AND Builder/Skeptic uses first-principles reasoning → Judge
364
+ demotes that output to `status: hypothesis` (cannot reach `confidence: high`).
365
+ - Domain = strategic AND Builder ranks options → Judge ensures recommendation is
366
+ conditional-tree, not single-winner (see `appendices/domain-tools.md` §output-gates).
367
+ - Domain = empirical AND a citation is added without resolving through Crossref/PubMed
368
+ → Judge moves the source to `sources.json: pending-verify` (not promoted).
369
+
370
+ Append a structured `## Iteration N` block to `iteration-log.md` containing:
371
+ - Attacked claim ID + computed priority
372
+ - Builder output summary (1-3 lines)
373
+ - Skeptic output summary + falsification result
374
+ - Retriever output: new source IDs added
375
+ - Judge ruling: per-claim status delta + reasoning
376
+
377
+ ## 6. Update the Claim Graph
378
+
379
+ Merge the Judge's status deltas into `claims.json`. For each claim touched this
380
+ iteration:
381
+
382
+ - Append to `history[]` with `{iter, status, note, evidence_delta}`
383
+ - Recompute `centrality` (DAG out-degree on `depends_on` / `supports` / `contradicts`)
384
+ - Recompute `uncertainty` from evidence-for / evidence-against ratio + source tiers
385
+ - If Skeptic produced concrete counter-evidence accepted by Judge, downgrade
386
+ `confidence` and surface in synthesis
387
+
388
+ For each NEW source added by Retriever:
389
+ - Append to `sources.json` with `fetched_at`, `tier`, `derivation_chain` (what other
390
+ sources, if any, it derives from)
391
+ - For domain = empirical, mark `verified_at: null` until citation-audit Step 7 runs
392
+
393
+ For Skeptic output that introduces a new claim contradicting an existing one:
394
+ - Create a new claim node
395
+ - Add `contradicts` edge to existing claim
396
+ - If both are `confidence ≥ medium`, mark both `status: contested` and tag as a
397
+ tier-1 conflict (spar trigger candidate)
398
+
399
+ ## 7. Citation Audit (every N iterations, default N=4)
400
+
401
+ Pick the top-K load-bearing claims (highest `impact × centrality`). For each:
402
+
403
+ - Re-fetch the cited source URL via WebFetch (or `curl` + `pdftotext` if PDF)
404
+ - Verify the quoted text still appears in the source (case-insensitive, ≥80% match)
405
+ - For domain = empirical: resolve every cited DOI/PMID via Crossref or NCBI E-utilities
406
+ (`curl https://api.crossref.org/works/{doi}` / `curl https://eutils.ncbi.nlm.nih.gov/...`)
407
+
408
+ For each failure:
409
+ - Move the citation to `suspect-citations.md` with `{claim_id, source_id, failure_mode}`
410
+ - Downgrade the claim's confidence; if no other source supports it, set
411
+ `status: retracted`
412
+
413
+ Citation audit on a single-session run (no budget) fires once at the end of Step 5.
414
+
415
+ ## 8. Decide: Continue, Synthesize, or Spar
416
+
417
+ After Step 7, check four conditions in order. The FIRST terminal-state hit wins —
418
+ remaining budget is not consumed.
419
+
420
+ **8a. Spar trigger check.** Fire `/apt:spar` (via Skill) when ANY of:
421
+ - A tier-1 conflict exists in the graph (two contested claims with `confidence ≥ medium`)
422
+ - A `critical` claim (from spec `## Critical claims`) is unresolved for 2+ iterations
423
+ - A claim has only `tier: vendor-doc` evidence and no independent confirmation
424
+
425
+ Spar prompt MUST include: the current synthesis position, the specific claim under
426
+ challenge, and an explicit instruction to produce a concrete status delta with citation
427
+ diff. Reject spar returns that are debate summaries with no actionable delta.
428
+
429
+ **8b. Stop check (early-termination wins).** Apply the dual-state rule from
430
+ `appendices/budget-loop.md` §stop-states:
431
+
432
+ - **CONVERGED** if: all `critical` claims at `confidence ≥ high`, zero unresolved
433
+ tier-1 conflicts, and Retriever found no new sources for the last 2 iterations
434
+ (frontier exhausted with synthesis stable). Exits immediately even if budget
435
+ remains.
436
+ - **STALLED** if: Retriever frontier exhausted (no new sources for 2 iterations) but
437
+ critical claims remain `contested` or `confidence < high`. The skill outputs an
438
+ explicit `## Cannot resolve without` section listing what new evidence (real-world
439
+ experiments, paywalled paper access, vendor disclosure, etc.) would be required.
440
+ - **CONTINUE** otherwise. Increment iteration counter. If a budget is set, go to
441
+ Step 9 (wake-loop). If not, return to Step 5 — but cap at 5 iterations for
442
+ single-session runs; if cap hit without terminal state, force `STALLED` with
443
+ `## Cannot resolve in single-session mode — re-run with --budget 4h or higher`.
444
+
445
+ **8c. Budget-cap check (budget loops only).** If `elapsed ≥ budget`, force `STALLED`
446
+ with `## Stopped at budget cap` note. Honest, even if mid-attack.
447
+
448
+ **8d. Final progress.log entry.** When any terminal state fires, write the verdict
449
+ line to `progress.log` (see `appendices/budget-loop.md` §progress-checkpoints for the
450
+ format).
451
+
452
+ ## 9. Schedule Next Wake (budget loops only)
453
+
454
+ If a budget is set AND status = CONTINUE:
455
+
456
+ Compute `remaining = original_budget − elapsed_at_start_of_iter`. Call `ScheduleWakeup`:
457
+
458
+ - `delaySeconds`: 1200 (20 minutes — past cache TTL, lets retrieval breathe)
459
+ - `prompt`: `/apt:research --resume {task-id} --budget {remaining}`
460
+ - `reason`: `apt:research budget loop iter {N+1}, next attack: {claim_id}, budget remaining: {remaining}`
461
+
462
+ The `--budget {remaining}` arg keeps the cap monotonically decreasing across wakes
463
+ so a crash + manual restart preserves the original commitment.
464
+
465
+ Persist `## Next attack: {claim_id}, priority: {value}` and `## Budget remaining:
466
+ {remaining}` to `RESEARCH.md` so the wake-loop iteration knows where to resume
467
+ without recomputing.
468
+
469
+ Exit the current session. The wake event will fire Step 5 in a fresh context with
470
+ all state on disk.
471
+
472
+ ## 10. Synthesize (terminal state reached)
473
+
474
+ Flip status to `SYNTHESIZING`. Write `RESEARCH.md` using the domain-gated output
475
+ template from `appendices/domain-tools.md` §output-gates. Every domain produces:
476
+
477
+ - `## Headline` — one-paragraph synthesis
478
+ - `## Claim graph summary` — top 5 critical claims with `{statement, status, confidence,
479
+ source_tier, conditions}`
480
+ - `## Contradictions` — every unresolved tier-1 conflict, with both positions and the
481
+ evidence each rests on (NEVER silently averaged)
482
+ - `## Iteration log summary` — compact per-iteration trace pulled from `iteration-log.md`
483
+ - `## Self-Score` — `{sub_question_coverage: X/Y, critical_claim_coverage: X/Y,
484
+ stop_state: CONVERGED|STALLED, budget_used: X of Y, calibration_note: "..."}`
485
+
486
+ Domain-gated additions:
487
+ - **mechanistic** → `## First-principles derivations` with cross-check vs sources
488
+ - **empirical** → `## Not medical/financial/safety advice` + `## What this CAN'T tell
489
+ you` + `## Quality of evidence` (RCT/n/peer-review-status per cited study)
490
+ - **strategic** → `## Conditional-tree recommendation` (`if X then A, if Y then B`,
491
+ NEVER single-winner when evidence is vendor-only) + `## Vendor-claim conflicts`
492
+ - **general** → `## Outstanding gaps` + `## Recommended next reads`
493
+
494
+ Mode-gated additions:
495
+ - **UNDERSTAND** → mental model with mechanism + analogy
496
+ - **VERIFY** → verdict (`confirmed | partially confirmed | false | contested | unknown`)
497
+ - **SOLVE** → candidate approaches table + recommended path + `## Falsification status`
498
+ (Code-SOLVE blocks `CONVERGED` if no test/simulator/model-checker was run; force
499
+ `STALLED` with `## Cannot certify without falsification`)
500
+ - **COMPARE** → dimensions × options matrix + per-cell evidence pointers
501
+
502
+ ## 11. Report and What's Next
503
+
504
+ Print to stdout:
505
+
506
+ ```
507
+ [apt:research] {Mode} / {Domain} — {CONVERGED|STALLED}.
508
+ Task: .aperant/research/{task-id}/
509
+ RESEARCH.md — synthesis ({lines} lines)
510
+ research-spec.md — immutable spec
511
+ claims.json — {N} claims, {M} sources
512
+ iteration-log.md — {I} iterations
513
+ progress.log — {I} heartbeats (tail anytime)
514
+ suspect-citations.md — {Q} quarantined ({nonzero ? "REVIEW REQUIRED" : "clean"})
515
+ Self-score: critical-claim coverage {X}%, stop-state {CONVERGED|STALLED}
516
+ Budget: {used} of {cap} ({percent}% — {saved-time saved} if CONVERGED early)
517
+ {1-line headline finding OR 1-line "cannot resolve without" gap}
518
+
519
+ Next:
520
+ /apt:discuss to lock decisions from these findings
521
+ /apt:plan to turn SOLVE/COMPARE output into an implementation plan
522
+ /apt:research --resume {task-id} to extend (re-query gaps, add a mode)
523
+ /apt:research --resume {task-id} --budget <duration> to escalate to a longer loop
524
+ ```
525
+
526
+ </process>