@aperant/framework 0.8.4 → 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.
- package/CHANGELOG.md +156 -0
- package/agents/apt-planner.md +34 -3
- package/dist/cli/commands/coverage-check.d.mts.map +1 -1
- package/dist/cli/commands/coverage-check.mjs +74 -7
- package/dist/cli/commands/coverage-check.mjs.map +1 -1
- package/dist/cli/commands/detect-runtime.d.mts.map +1 -1
- package/dist/cli/commands/detect-runtime.mjs +18 -12
- package/dist/cli/commands/detect-runtime.mjs.map +1 -1
- package/dist/cli/coverage-check/user-outcomes.d.mts +84 -0
- package/dist/cli/coverage-check/user-outcomes.d.mts.map +1 -0
- package/dist/cli/coverage-check/user-outcomes.mjs +265 -0
- package/dist/cli/coverage-check/user-outcomes.mjs.map +1 -0
- package/dist/cli/host/detect.mjs +1 -1
- package/dist/cli/host/detect.mjs.map +1 -1
- package/dist/cli/install/install-from-source.mjs +3 -3
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +2 -0
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/verify-proof/idl/index.d.mts +1 -1
- package/dist/cli/verify-proof/idl/index.mjs +7 -8
- package/dist/cli/verify-proof/idl/index.mjs.map +1 -1
- package/dist/cli/verify-proof/idl/types.d.ts +5 -4
- package/dist/cli/verify-proof/idl/types.d.ts.map +1 -1
- package/dist/cli/verify-proof/idl/types.js +4 -3
- package/dist/cli/verify-proof/idl/types.js.map +1 -1
- package/dist/cli/verify-proof/resolver.d.mts +63 -1
- package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
- package/dist/cli/verify-proof/resolver.mjs +164 -4
- package/dist/cli/verify-proof/resolver.mjs.map +1 -1
- package/dist/cli/verify-proof/runtime-detect.d.mts +6 -3
- package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -1
- package/dist/cli/verify-proof/runtime-detect.mjs +104 -11
- package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -1
- package/dist/cli/verify-proof/trust.d.mts +1 -1
- package/dist/cli/verify-proof/trust.d.mts.map +1 -1
- package/dist/cli/verify-proof/trust.mjs +1 -1
- package/dist/driver-sdk/conformance.d.ts +41 -0
- package/dist/driver-sdk/conformance.d.ts.map +1 -0
- package/dist/driver-sdk/conformance.js +123 -0
- package/dist/driver-sdk/conformance.js.map +1 -0
- package/dist/driver-sdk/errors.d.ts +75 -0
- package/dist/driver-sdk/errors.d.ts.map +1 -0
- package/dist/driver-sdk/errors.js +80 -0
- package/dist/driver-sdk/errors.js.map +1 -0
- package/dist/driver-sdk/idl.d.ts +221 -0
- package/dist/driver-sdk/idl.d.ts.map +1 -0
- package/dist/driver-sdk/idl.js +140 -0
- package/dist/driver-sdk/idl.js.map +1 -0
- package/dist/driver-sdk/index.d.ts +28 -0
- package/dist/driver-sdk/index.d.ts.map +1 -0
- package/dist/driver-sdk/index.js +28 -0
- package/dist/driver-sdk/index.js.map +1 -0
- package/dist/driver-sdk/manifest.d.ts +93 -0
- package/dist/driver-sdk/manifest.d.ts.map +1 -0
- package/dist/driver-sdk/manifest.js +12 -0
- package/dist/driver-sdk/manifest.js.map +1 -0
- package/dist/driver-sdk/retry.d.ts +33 -0
- package/dist/driver-sdk/retry.d.ts.map +1 -0
- package/dist/driver-sdk/retry.js +50 -0
- package/dist/driver-sdk/retry.js.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +2 -1
- package/dist/plugin/agents/apt-planner.md +34 -3
- package/dist/plugin/skills/apt-plan/SKILL.md +50 -0
- package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -1
- package/dist/plugin/skills/apt-research/SKILL.md +526 -0
- package/dist/plugin/skills/apt-research/appendices/budget-loop.md +397 -0
- package/dist/plugin/skills/apt-research/appendices/claim-graph-schema.md +206 -0
- package/dist/plugin/skills/apt-research/appendices/domain-tools.md +236 -0
- package/dist/plugin/skills/apt-spar/SKILL.md +19 -7
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +41 -2
- package/dist/schemas/quick-task.d.ts +17 -17
- package/drivers/.gitkeep +0 -0
- package/drivers/api/README.md +40 -0
- package/drivers/api/driver.mjs +59 -0
- package/drivers/api/manifest.json +26 -0
- package/drivers/browser/README.md +105 -0
- package/drivers/browser/driver.mjs +134 -0
- package/drivers/browser/manifest.json +35 -0
- package/drivers/cli/README.md +44 -0
- package/drivers/cli/driver.mjs +62 -0
- package/drivers/cli/manifest.json +28 -0
- package/drivers/electron/README.md +64 -0
- package/drivers/electron/driver.mjs +87 -0
- package/drivers/electron/manifest.json +37 -0
- package/package.json +7 -3
- package/skills/apt-plan/SKILL.md +50 -0
- package/skills/apt-planner.md +16 -0
- package/skills/apt-pr-review/SKILL.md +1 -1
- package/skills/apt-research/SKILL.md +526 -0
- package/skills/apt-research/appendices/budget-loop.md +397 -0
- package/skills/apt-research/appendices/claim-graph-schema.md +206 -0
- package/skills/apt-research/appendices/domain-tools.md +236 -0
- package/skills/apt-spar/SKILL.md +19 -7
- package/skills/apt-verify-proof/SKILL.md +41 -2
- package/src/cli/commands/coverage-check.mjs +126 -44
- package/src/cli/commands/detect-runtime.mjs +23 -14
- package/src/cli/coverage-check/user-outcomes.mjs +273 -0
- package/src/cli/host/detect.mjs +1 -1
- package/src/cli/install/install-from-source.mjs +3 -3
- package/src/cli/install/legacy-paths.mjs +2 -0
- package/src/cli/verify-proof/idl/index.mjs +7 -8
- package/src/cli/verify-proof/idl/types.ts +5 -4
- package/src/cli/verify-proof/manifest-schema.json +2 -1
- package/src/cli/verify-proof/resolver.mjs +171 -4
- package/src/cli/verify-proof/runtime-detect.mjs +99 -10
- package/src/cli/verify-proof/trust.mjs +1 -1
- package/templates/proof-verification.md +32 -3
- package/workflows/verify-proof.md +78 -9
package/skills/apt-plan/SKILL.md
CHANGED
|
@@ -161,6 +161,14 @@ and is committable as a second-consumer document. Section ordering is
|
|
|
161
161
|
**load-bearing** — downstream tooling (`apt-tools coverage-check`,
|
|
162
162
|
`apt-tools consistency check`) reads sections by header.
|
|
163
163
|
|
|
164
|
+
**Three orthogonal user-facing sections — keep them distinct.** User
|
|
165
|
+
Stories carry product motivation, User Outcomes carry the
|
|
166
|
+
verify-proof input contract, and Acceptance Criteria carry code-level
|
|
167
|
+
invariants. The three do NOT subsume each other; a STANDARD/DEEP spec
|
|
168
|
+
carries all three. See the `## User Outcomes` block below for the
|
|
169
|
+
verify-proof unit shape (Epic line + atomic outcomes + surface tags
|
|
170
|
+
+ empty-with-note escape).
|
|
171
|
+
|
|
164
172
|
```markdown
|
|
165
173
|
# Spec: {task title}
|
|
166
174
|
|
|
@@ -184,6 +192,29 @@ ships: new files, modified files, new flags, new config, new skills.}
|
|
|
184
192
|
{persona}, when I {trigger}, I want {behavior} so I can {outcome}."
|
|
185
193
|
Stories map 1:1 onto subtasks in implementation_plan.json.}
|
|
186
194
|
|
|
195
|
+
## User Outcomes
|
|
196
|
+
|
|
197
|
+
{The verify-proof input contract. One bolded `**Epic:**` headline + N
|
|
198
|
+
atomic outcomes tagged by surface. Authors write the LITERAL string
|
|
199
|
+
`**ON**` — IDs are POSITIONAL and synthesized by the parser (the first
|
|
200
|
+
outcome row becomes `O1`, the second `O2`, etc.). Closed surface set:
|
|
201
|
+
`electron | web | cli | api | electron+web`. Optional cross-references
|
|
202
|
+
via `*(requires ON N)*` where `N` is the digit of a prior outcome's
|
|
203
|
+
position. For pure-refactor specs with no user-observable changes, the
|
|
204
|
+
body MAY be exactly `_No user-observable changes — pure refactor._`
|
|
205
|
+
(italic underscores required, exact em dash, period mandatory).
|
|
206
|
+
Coverage-check parses this section into a `user_outcomes` payload —
|
|
207
|
+
see the gate table below.}
|
|
208
|
+
|
|
209
|
+
**Epic:** {one-sentence user-facing capability headline}
|
|
210
|
+
|
|
211
|
+
- **ON** [surface]: {user does X; system shows/does Y}
|
|
212
|
+
- **ON** [surface]: {user does X; system shows/does Y} *(requires ON 1)*
|
|
213
|
+
- **ON** [electron+web]: {cross-surface outcome — runs twice, once per surface}
|
|
214
|
+
|
|
215
|
+
(Refactor-only escape:)
|
|
216
|
+
_No user-observable changes — pure refactor._
|
|
217
|
+
|
|
187
218
|
## Implementation Decisions
|
|
188
219
|
|
|
189
220
|
{Load-bearing principles carried forward into every subtask. Format:
|
|
@@ -215,6 +246,25 @@ ID. Subtasks reference these IDs via their per-subtask
|
|
|
215
246
|
plan-coverage-check input.}
|
|
216
247
|
```
|
|
217
248
|
|
|
249
|
+
**`## User Outcomes` is the verify-proof input contract (STANDARD/DEEP
|
|
250
|
+
only — QUICK is hard-exempt per ID-05 / Fast Path Guarantee).** The
|
|
251
|
+
section sits between `## User Stories` (product motivation prose) and
|
|
252
|
+
`## Implementation Decisions` (load-bearing engineering principles).
|
|
253
|
+
Coverage-check (`apt-tools coverage-check validate .`) parses the
|
|
254
|
+
section into a `user_outcomes` payload with this gate behavior:
|
|
255
|
+
|
|
256
|
+
| Header present? | Body shape | Gate result (v0.8.x) | v0.9.0 hard cutover |
|
|
257
|
+
|---|---|---|---|
|
|
258
|
+
| no | — | `warn` (migration deadline emitted) | `block` |
|
|
259
|
+
| yes | `outcomes` (≥1 `**ON**` row) | `pass` | `pass` |
|
|
260
|
+
| yes | exactly `_No user-observable changes — pure refactor._` | `pass` | `pass` |
|
|
261
|
+
| yes | empty (header but nothing under it) | `block` | `block` |
|
|
262
|
+
|
|
263
|
+
Closed surface set: `electron | web | cli | api | electron+web`. The
|
|
264
|
+
`electron+web` tag means the outcome runs on both surfaces during
|
|
265
|
+
verify-proof (split screenshot trees, two test entries in
|
|
266
|
+
`verification.json`).
|
|
267
|
+
|
|
218
268
|
**Constraint — do NOT interview the user.** The PRD is synthesized from
|
|
219
269
|
the task description + codebase investigation + AGENTS.md, not from a
|
|
220
270
|
clarifying interview. If a section truly cannot be filled, write
|
package/skills/apt-planner.md
CHANGED
|
@@ -100,6 +100,17 @@ Content format branches on track.
|
|
|
100
100
|
## User Stories
|
|
101
101
|
{**US-NN (persona).** stories, 1:1 onto subtasks.}
|
|
102
102
|
|
|
103
|
+
## User Outcomes
|
|
104
|
+
{Verify-proof input contract. **Epic:** headline + N atomic outcomes.
|
|
105
|
+
Authors write the LITERAL `**ON**` string (IDs are POSITIONAL — parser
|
|
106
|
+
synthesizes O1/O2/…). Closed surface set:
|
|
107
|
+
`electron | web | cli | api | electron+web`. Empty-with-note escape:
|
|
108
|
+
`_No user-observable changes — pure refactor._`}
|
|
109
|
+
|
|
110
|
+
**Epic:** {one-sentence user-facing capability}
|
|
111
|
+
|
|
112
|
+
- **ON** [surface]: {user does X; system shows/does Y}
|
|
113
|
+
|
|
103
114
|
## Implementation Decisions
|
|
104
115
|
{### ID-NN load-bearing principles.}
|
|
105
116
|
|
|
@@ -120,6 +131,11 @@ PRD section ordering is load-bearing — downstream tooling greps by header.
|
|
|
120
131
|
Do NOT interview the user; synthesize from task description + codebase +
|
|
121
132
|
AGENTS.md.
|
|
122
133
|
|
|
134
|
+
**`## User Outcomes` synthesis directive.** Outcomes are
|
|
135
|
+
user-observable; ACs are code-level. Do NOT collapse — they parse
|
|
136
|
+
through different gates. STANDARD/DEEP specs carry both. IDs are
|
|
137
|
+
POSITIONAL — never hand-author `**O1**`/`**O2**`.
|
|
138
|
+
|
|
123
139
|
## 5. Create Implementation Plan
|
|
124
140
|
|
|
125
141
|
Create `{task_dir}/implementation_plan.json`:
|
|
@@ -1081,7 +1081,7 @@ For every finding with `validation_status == "confirmed_valid"` AND `severity
|
|
|
1081
1081
|
- `{REVIEWER_EVIDENCE}` — the finding's `evidence` field verbatim.
|
|
1082
1082
|
3. Invoke codex using the shape configured at `.aperant/config.json:router.llm.providers.codex`:
|
|
1083
1083
|
```bash
|
|
1084
|
-
codex exec --
|
|
1084
|
+
codex exec --input-file /tmp/fp-gate-${FINDING_ID}.md
|
|
1085
1085
|
```
|
|
1086
1086
|
Parse the JSON response `{verdict, reasoning, evidence_quote, severity_assessment}`.
|
|
1087
1087
|
4. If `verdict == "falsify"`, set the finding's `validation_status = "dismissed_cross_model_falsification"` and copy the codex response into `fp_gate_result`. If `verdict == "confirm"`, pass through unchanged.
|
|
@@ -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>
|