@paradigma-inc/flywheel 0.1.16 → 0.1.25

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 (60) hide show
  1. package/README.md +8 -0
  2. package/package.json +1 -1
  3. package/skills/flywheel/SKILL.md +1 -0
  4. package/skills/flywheel/compute/managed-compute.md +111 -2
  5. package/skills/flywheel/references/experiment-design-protocol.md +1 -1
  6. package/skills/flywheel/references/flywheel-mcp-tool-map.md +130 -142
  7. package/skills/flywheel/setting-up-flywheel/updating-flywheel-mcp.md +8 -0
  8. package/skills/flywheel-auto/SKILL.md +14 -6
  9. package/skills/flywheel-auto/evals/evals.json +6 -0
  10. package/skills/flywheel-auto/references/ARTIFACTS.md +46 -216
  11. package/skills/flywheel-auto/references/INTERFACES.md +196 -195
  12. package/skills/flywheel-auto/references/experiment-design-protocol-autonomous.md +62 -0
  13. package/skills/flywheel-auto/references/experiment-design-protocol.md +1 -1
  14. package/skills/flywheel-auto/references/flywheel-mcp-tool-map.md +130 -142
  15. package/skills/flywheel-lookahead/SKILL.md +23 -15
  16. package/skills/flywheel-lookahead/agents/openai.yaml +3 -3
  17. package/skills/flywheel-lookahead/evals/evals.json +13 -1
  18. package/skills/flywheel-lookahead/references/ARTIFACTS.md +46 -216
  19. package/skills/flywheel-lookahead/references/INTERFACES.md +196 -195
  20. package/skills/flywheel-lookahead/references/flywheel-mcp-tool-map.md +130 -142
  21. package/skills/flywheel-prove/SKILL.md +163 -0
  22. package/skills/flywheel-prove/agents/interface.yaml +4 -0
  23. package/skills/flywheel-prove/assets/pipeline_template/bin/tproof +3 -0
  24. package/skills/flywheel-prove/assets/pipeline_template/bin/tproof.cmd +2 -0
  25. package/skills/flywheel-prove/assets/pipeline_template/logs/.gitkeep +1 -0
  26. package/skills/flywheel-prove/assets/pipeline_template/pyproject.toml +23 -0
  27. package/skills/flywheel-prove/assets/pipeline_template/scripts/smoke_test.cmd +2 -0
  28. package/skills/flywheel-prove/assets/pipeline_template/scripts/smoke_test.sh +3 -0
  29. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/__init__.py +1 -0
  30. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/cli.py +298 -0
  31. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/constants.py +10 -0
  32. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/layout.py +51 -0
  33. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/leanops.py +116 -0
  34. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/runstore.py +58 -0
  35. package/skills/flywheel-prove/assets/pipeline_template/src/tproof/tasking.py +94 -0
  36. package/skills/flywheel-prove/assets/pipeline_template/workspace/prompts/fill_sorries.txt +3 -0
  37. package/skills/flywheel-prove/references/workflow.md +193 -0
  38. package/skills/flywheel-prove/scripts/scaffold_pipeline.py +111 -0
  39. package/skills/flywheel-reproduce/SKILL.md +31 -23
  40. package/skills/flywheel-reproduce/evals/evals.json +7 -1
  41. package/skills/flywheel-reproduce/references/ARTIFACTS.md +46 -216
  42. package/skills/flywheel-reproduce/references/INTERFACES.md +196 -195
  43. package/skills/flywheel-reproduce/references/experiment-design-protocol.md +1 -1
  44. package/skills/flywheel-reproduce/references/flywheel-mcp-tool-map.md +130 -142
  45. package/skills/flywheel-reproduce/references/source-blog.md +35 -0
  46. package/skills/flywheel-reproduce/references/source-generic.md +30 -0
  47. package/skills/flywheel-reproduce/references/source-notes.md +35 -0
  48. package/skills/flywheel-reproduce/references/source-paper.md +89 -0
  49. package/skills/flywheel-reproduce/references/source-wiki.md +36 -0
  50. package/skills/flywheel-to-graph/SKILL.md +27 -21
  51. package/skills/flywheel-to-graph/evals/evals.json +7 -1
  52. package/skills/flywheel-to-graph/references/ARTIFACTS.md +46 -216
  53. package/skills/flywheel-to-graph/references/INTERFACES.md +196 -195
  54. package/skills/flywheel-to-graph/references/flywheel-mcp-tool-map.md +130 -142
  55. package/skills/flywheel-to-graph/references/source-blog.md +34 -0
  56. package/skills/flywheel-to-graph/references/source-generic.md +29 -0
  57. package/skills/flywheel-to-graph/references/source-notes.md +34 -0
  58. package/skills/flywheel-to-graph/references/source-paper.md +85 -0
  59. package/skills/flywheel-to-graph/references/source-wiki.md +35 -0
  60. package/src/cli.mjs +69 -3
package/README.md CHANGED
@@ -107,6 +107,14 @@ Reruns refresh every already-installed bundled skill in place and install any
107
107
  newly bundled skills from the updated package. They do not create side-by-side
108
108
  copies for the same scope and agent location.
109
109
 
110
+ If you choose to refresh via `skills experimental_sync` instead of rerunning
111
+ setup, install Flywheel locally in that project first:
112
+
113
+ ```bash
114
+ npm install --save-dev @paradigma-inc/flywheel@latest
115
+ npx skills experimental_sync --agent codex -y
116
+ ```
117
+
110
118
  ## Supported Hosts For Bundled Skill Install
111
119
 
112
120
  - Claude Code
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paradigma-inc/flywheel",
3
- "version": "0.1.16",
3
+ "version": "0.1.25",
4
4
  "description": "One-command setup for Flywheel MCP hosts",
5
5
  "type": "module",
6
6
  "files": [
@@ -50,6 +50,7 @@ Choose one primary file first, then add at most one supporting file only if need
50
50
  - Prefer concrete steps and decision points over long narrative explanations.
51
51
  - Do not run broad document reads; load only what is required by the current request.
52
52
  - Do not start compute-heavy execution before design intent is clear.
53
+ - When another specialized Flywheel skill is explicitly invoked, this skill provides background guidance only and must not override that skill's workflow rules.
53
54
  - For managed compute cleanup in autonomous runs, default to releasing only
54
55
  known leases (leases acquired in the current run or explicitly selected by
55
56
  the user).
@@ -14,8 +14,9 @@ Flywheel can provision managed GPU instances for you from providers like Lambda
14
14
  ```
15
15
 
16
16
  2. **Approve a budget.** Flywheel opens an approval page in your browser where you set a spending cap for managed compute acquisition.
17
- 3. **The agent handles the rest.** It acquires a machine, waits for it to become ready, and gets SSH access automatically. Provisioning typically takes a few minutes — the agent polls for readiness in the background.
18
- 4. **Release when done.** When you're finished, the agent releases the lease. You can also release leases from the WebUI at any time.
17
+ 3. **Review and choose a GPU.** The agent lists current offers, recommends one option with rationale, presents alternatives, and waits for your explicit confirmation before acquiring.
18
+ 4. **The agent acquires and connects.** After explicit confirmation, the agent acquires a machine, waits for it to become ready, and gets SSH access automatically. Provisioning typically takes a few minutes the agent polls for readiness in the background.
19
+ 5. **Release when done.** When you're finished, the agent releases the lease. You can also release leases from the WebUI at any time.
19
20
 
20
21
  For autonomous runs, agents should default to releasing only known leases
21
22
  (leases acquired in the current run or explicitly selected by the user). If
@@ -42,6 +43,114 @@ Compute is billed against your Flywheel credits balance, which is separate from
42
43
 
43
44
  For a focused reference, see `compute/credits-and-billing.md`.
44
45
 
46
+ ## Recommendation procedure
47
+
48
+ ### Step 1 - Filter to allowed options
49
+
50
+ - Input: `options` from `flywheel_compute_list_options`.
51
+ - Keep only entries where `allowed == true`.
52
+ - If empty, return "empty option list" failure mode and stop.
53
+
54
+ ### Step 2 - Extract task signals from node text
55
+
56
+ - Read `node.content`, `node.hypothesis`, `node.summary`.
57
+ - Extract:
58
+ - `weight_class` in `{light, medium, heavy, unknown}`
59
+ - `expected_runtime_hours`
60
+ - `min_vram_gb`
61
+ - Defaults:
62
+ - `expected_runtime_hours`: `1` for light, `3` for medium, `8` for heavy, `unknown` when weight is unknown.
63
+ - `min_vram_gb`: `0` for light, `24` for medium, `40` for heavy.
64
+ - If any signal is `unknown`, ask exactly one clarifying question:
65
+ - "Roughly what size model and how long do you expect to run?"
66
+ - LLM judgment is allowed only in this step.
67
+
68
+ ### Step 3 - Apply affordability filter
69
+
70
+ - Compute `runway_hours = budget_remaining_cents / price_cents_per_hour` for each option.
71
+ - Drop options where `runway_hours < expected_runtime_hours * 1.25`.
72
+ - `1.25` is fixed in this issue; do not change it.
73
+ - If empty, return "all options over cap" failure mode and stop.
74
+
75
+ ### Step 4 - Apply minimum VRAM filter
76
+
77
+ - Drop options where `gpu_memory_gb < min_vram_gb`.
78
+ - If this would empty the set, keep the Step 3 set and mark `VRAM-constrained fallback`.
79
+ - Use the Step 4-qualified set for subsequent ranking, alternatives, and retries.
80
+ - Use the Step 3 survivors for those later decisions only when `VRAM-constrained fallback` is active.
81
+
82
+ ### Step 5 - Rank and pick recommendation
83
+
84
+ Evaluate buckets in this order and stop at the first non-empty bucket:
85
+
86
+ 1. Preferred + affordable + VRAM-met (`offer_id` in `preferred_offer_ids`)
87
+ 2. Affordable + VRAM-met
88
+ 3. Affordable fallback (when `VRAM-constrained fallback` is active)
89
+
90
+ Sorting rules:
91
+
92
+ - Buckets 1 and 2 primary sort: cheapest `price_cents_per_hour`.
93
+ - Bucket 3 primary sort: largest `gpu_memory_gb`, then cheapest on tie.
94
+
95
+ Tie-breakers (only when primary sort values are exactly equal):
96
+
97
+ 1. `availability_mode == live_capacity` before `allocation_time`
98
+ 2. `price_kind == provider_reported` before `estimate`
99
+ 3. more `regions` entries first
100
+ 4. lexicographic `offer_id`
101
+
102
+ ### Step 6 - Build recommendation rationale
103
+
104
+ Include:
105
+
106
+ - GPU identity: `{gpu_model} ({gpu_memory_gb}GB)`
107
+ - Hourly rate in dollars per hour
108
+ - Estimate suffix when `price_kind == estimate`
109
+ - Runway statement using `budget_remaining_cents`
110
+ - Weight-class match statement
111
+ - Availability note only when non-default
112
+ - Provenance tag for preferred-list pick or VRAM fallback
113
+
114
+ ### Step 7 - Select up to two alternatives
115
+
116
+ From the active candidate set (Step 4-qualified set by default; Step 3 survivors only when `VRAM-constrained fallback` is active), fill at most two slots in this order:
117
+
118
+ 1. Reliability alternative (only if recommendation is `allocation_time`): cheapest `live_capacity`
119
+ 2. Cheaper alternative: strictly cheaper than recommendation
120
+ 3. Headroom alternative: strictly higher `gpu_memory_gb` than recommendation
121
+
122
+ Display order:
123
+
124
+ 1. recommendation first
125
+ 2. filled alternatives in slot order
126
+
127
+ Never display more than three total options.
128
+
129
+ ### Step 8 - Require confirmation and handle acquire failure
130
+
131
+ - Wait for explicit user confirmation (or explicit user override offer id) before `flywheel_compute_acquire`.
132
+ - On acquire failure due to capacity:
133
+ 1. pick next-best candidate from the active candidate set (excluding failed offer),
134
+ 2. same provider -> retry immediately without re-confirmation,
135
+ 3. different provider -> ask user to re-confirm before retry,
136
+ 4. cap retries at 3 total acquire attempts per user confirmation,
137
+ 5. for `flywheel-auto` with `k > 1`, apply retry cap and confirmation boundary per worker.
138
+
139
+ Fixed numeric defaults for this flow:
140
+
141
+ - `1`, `3`, `8` runtime defaults
142
+ - affordability multiplier `1.25`
143
+ - acquire retry cap `3`
144
+
145
+ ## Presenting the options
146
+
147
+ - Always show the recommended offer first with rationale.
148
+ - Then show up to two alternatives.
149
+ - Always wait for explicit user confirmation before calling `flywheel_compute_acquire`.
150
+ - If the user provides an explicit offer-id override, Treat as first-class and proceed with that selected offer after confirmation.
151
+
152
+ For persistent preference, set `preferred_offer_ids` in the node compute policy.
153
+
45
154
  ## [](https://flywheel.paradigma.inc//#tips)Tips
46
155
 
47
156
  - Provisioning takes a few minutes — the agent polls automatically, so you don't need to babysit it.
@@ -141,7 +141,7 @@ Typical flow:
141
141
  1. `mcp__flywheel__flywheel_branch_node` or `mcp__flywheel__flywheel_stage_node_create`
142
142
  2. `mcp__flywheel__flywheel_stage_node_update` with the explicit run summary and the local question or hypothesis for that branch
143
143
  3. `mcp__flywheel__flywheel_request_compute_grant_approval` only after the user accepts the design
144
- 4. `mcp__flywheel__flywheel_list_compute_grants` or `mcp__flywheel__flywheel_list_approval_sessions` when you need to resolve the approved `compute_grant_id`
144
+ 4. `mcp__flywheel__flywheel_list_compute_grants(status=active, approval_session_id=<session_id>)` when you need to resolve the approved `compute_grant_id`
145
145
  5. `mcp__flywheel__flywheel_compute_acquire` and related compute tools only when execution is actually needed
146
146
  6. `mcp__flywheel__flywheel_prepare_artifact_uploads`, raw upload to the returned signed URLs, then `mcp__flywheel__flywheel_finalize_artifact_uploads`
147
147
  7. Do a brief epistemic check before commit: verify what the evidence actually shows, whether it matches the interpretation rule from the brief, and whether any gap between the data and the hoped-for story needs to be named explicitly in the node summary.
@@ -1,160 +1,148 @@
1
1
  # Flywheel MCP Tool Map
2
2
 
3
- This reference describes the Flywheel MCP tool families and the common runtime
4
- contract expected by the public Flywheel skill.
3
+ Contract-aligned routing guide for Flywheel MCP tool usage.
5
4
 
6
- Use it as a routing guide, not as a session snapshot. Always verify the exact
7
- tool surface exposed by your current MCP host before executing critical flows.
5
+ Flywheel is a graph-based system for tracking research work, decisions, and evidence over time. Flywheel MCP is the tool interface for reading and updating that graph. You can discover, create, and manage nodes. You can collaborate with other users and use managed compute.
8
6
 
9
7
  ## Core Contract Expectations
10
8
 
11
- - Node lifecycle and graph-mutation flows use optimistic locking
12
- (`expected_revision`).
13
- - Node commits require `kind`, `outcome`, and `summary`.
14
- - `kind` is typically `insight` or `empirical`.
15
- - `insight` commits require non-empty `insights`.
16
- - `empirical` commits require a non-empty `hypothesis`; completed empirical
17
- commits also require artifacts or a `no_artifacts_reason`.
18
- - Artifact publish is a two-step flow:
19
- prepare upload, upload raw bytes to returned signed URLs, then finalize
20
- the upload batch.
9
+ - Use `flywheel_get_contract` + `flywheel_get_contract_section` as canonical contract references.
10
+ - Node state is canonical durable state; avoid relying on ephemeral transcript state.
11
+ - Node kind (`untyped`, `empirical`, `insight`) is an explicit durable field.
12
+ - Node references include immutable `node_id` and optional immutable `slug_name`; prefer communicating both together for human clarity and disambiguation.
13
+ - Insight nodes should represent conceptual observations (theoretical insights, intuitions, motivations, decision-relevant framing); empirical nodes should represent experiments with explicit hypotheses and measured outcomes.
14
+ - Graph topology should encode logical/causal relations between concepts and experiments. Avoid defaulting to shallow root-only branching unless work items are truly independent.
15
+ - For empirical work, publish evidence with `flywheel_prepare_artifact_uploads`, upload raw file bytes, then `flywheel_finalize_artifact_uploads` before commit.
16
+ - Artifact metadata records expose a non-empty `title` suitable for display labels; title normalization must never derive from `storage_url`.
21
17
 
22
18
  ## Tool Families
23
19
 
24
- ### Session, Auth, and Contract
25
-
26
- - `mcp__flywheel__flywheel_auth_status`
27
- - `mcp__flywheel__flywheel_get_contract`
28
- - `mcp__flywheel__flywheel_get_contract_section`
29
- - `mcp__flywheel__flywheel_get_credits_balance`
30
-
31
- ### Node Discovery and Read
32
-
33
- - `mcp__flywheel__flywheel_list_nodes`
34
- - `mcp__flywheel__flywheel_get_node`
35
- - `mcp__flywheel__flywheel_get_node_tree`
36
- - `mcp__flywheel__flywheel_get_node_ancestry`
37
- - `mcp__flywheel__flywheel_summarize_node_tree`
38
- - `mcp__flywheel__flywheel_get_campaign_snapshot`
39
- - `mcp__flywheel__flywheel_list_audit`
40
-
41
- ### Node Mutation, Branching, and Commit
42
-
43
- - `mcp__flywheel__flywheel_stage_node_create`
44
- - `mcp__flywheel__flywheel_stage_node_update`
45
- - `mcp__flywheel__flywheel_commit_node`
46
- - `mcp__flywheel__flywheel_branch_node`
47
- - `mcp__flywheel__flywheel_merge_nodes`
48
- - `mcp__flywheel__flywheel_add_parent`
49
- - `mcp__flywheel__flywheel_remove_parent`
50
- - `mcp__flywheel__flywheel_delete_node`
51
- - `mcp__flywheel__flywheel_bulk_delete_nodes`
52
-
53
- ### Access Policy and Collaboration
54
-
55
- - `mcp__flywheel__flywheel_get_node_sharing`
56
- - `mcp__flywheel__flywheel_set_sharing_for_node`
57
- - `mcp__flywheel__flywheel_set_sharing_for_nodes`
58
-
59
- ### Tags and Graph Annotation
60
-
61
- - `mcp__flywheel__flywheel_create_node_tag`
62
- - `mcp__flywheel__flywheel_update_node_tag`
63
- - `mcp__flywheel__flywheel_delete_node_tag`
64
- - `mcp__flywheel__flywheel_set_node_tag_assignments`
20
+ ### Discovery and sharing
21
+
22
+ - `flywheel_auth_status` (read; scopes: `read`; HTTP: `GET /auth/status`; core surface): Return Flywheel auth status for the current access token.
23
+ - `flywheel_get_credits_balance` (read; scopes: `read`; HTTP: `GET /credits`; core surface): Return current user credits balance and lifetime counters.
24
+ - `flywheel_updates_list` (read; scopes: `read`; HTTP: `GET /mcp/updates`; core surface): List in-app updates/announcements for the signed-in user.
25
+ - `flywheel_updates_hide` (mutating; scopes: `write`; HTTP: `POST /mcp/updates/{announcement_id}/hide`; core surface): Mark one update as hidden for the current user (Don't show again).
26
+ - `flywheel_updates_hide_all_active` (mutating; scopes: `write`; HTTP: `POST /mcp/updates/hide-all-active`; core surface): Hide all active updates for the current user (Don't show all active again).
27
+ - `flywheel_updates_unhide` (mutating; scopes: `write`; HTTP: `DELETE /mcp/updates/{announcement_id}/hide`; core surface): Restore one hidden update for the current user.
28
+ - `flywheel_list_nodes` (read; scopes: `read`; HTTP: `GET /mcp/nodes`; full-surface only): List nodes with optional owners/writers/visibility filters and projection control (`core`, `topology`, `full`).
29
+ - `flywheel_resolve_node_slug` (read; scopes: `read`; HTTP: `GET /mcp/nodes/resolve-by-slug`; core surface): Resolve a node by slug_name with explicit conflict handling (`unique`, `context_resolved`, `ambiguous`, `not_found`).
30
+ - `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/sharing`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
31
+ - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `PUT /mcp/nodes/{node_id}/sharing`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
32
+ - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/sharing/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
33
+ - `flywheel_get_node` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}`; core surface): Get one node by node_id.
34
+ - `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node.
35
+ - `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /mcp/nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
36
+ - `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /mcp/nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
37
+ - `flywheel_set_node_tag_assignments` (mutating; scopes: `write`; HTTP: `PUT /mcp/nodes/{node_id}/tags`; full-surface only): Set graph tag assignments for one node.
38
+ - `flywheel_get_node_tree` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/tree`; full-surface only): Get a root-aware bounded tree/DAG projection for an anchor node.
39
+ - `flywheel_get_node_ancestry` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/ancestry`; full-surface only): Get ordered ancestry metadata from an anchor node to root boundaries.
40
+ - `flywheel_get_campaign_snapshot` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/campaign/snapshot`; core surface): Read the current campaign snapshot for a node's root campaign, including configured views and derived records.
41
+ - `flywheel_list_audit` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/audit`; full-surface only): List node MCP audit events.
42
+
43
+ ### Node stage and commit
44
+
45
+ - `flywheel_commit_new_node` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/commit-new`; full-surface only): Commit a locally staged new node into canonical storage and return the persisted node.
46
+ - `flywheel_acquire_stage_lease` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/stage/lease/acquire`; full-surface only): Acquire a session-scoped stage lease for an existing node before local staged edits.
47
+ - `flywheel_heartbeat_stage_lease` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/stage/lease/heartbeat`; full-surface only): Refresh the active stage lease for the current editing session.
48
+ - `flywheel_release_stage_lease` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/stage/lease/release`; full-surface only): Release the active stage lease for the current editing session.
49
+ - `flywheel_commit_node` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/commit`; core surface): Commit an existing node by publishing the caller's staged payload under an active stage lease.
50
+ - `flywheel_branch_node` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/branch`; full-surface only): Create a child branch node.
51
+ - `flywheel_merge_nodes` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/merge`; full-surface only): Merge nodes with caller-resolved node payload.
52
+ - `flywheel_add_parent` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/parents/add`; full-surface only): Attach an additional parent edge to an existing node (keeps node identity, validates against cycles).
53
+ - `flywheel_remove_parent` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/parents/remove`; full-surface only): Detach one parent edge from a node without deleting the node.
54
+ - `flywheel_delete_node` (mutating; scopes: `write`; HTTP: `DELETE /mcp/nodes/{node_id}`; full-surface only): Delete a node subtree.
55
+ - `flywheel_bulk_delete_nodes` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/bulk-delete`; full-surface only): Delete multiple node subtrees in one operation.
65
56
 
66
57
  ### Artifacts
67
58
 
68
- - `mcp__flywheel__flywheel_list_artifacts`
69
- - `mcp__flywheel__flywheel_get_artifact`
70
- - `mcp__flywheel__flywheel_get_artifact_preview`
71
- - `mcp__flywheel__flywheel_prepare_artifact_uploads`
72
- - `mcp__flywheel__flywheel_finalize_artifact_uploads`
73
- - `mcp__flywheel__flywheel_set_artifact_note`
74
- - `mcp__flywheel__flywheel_delete_artifact`
75
-
76
- Common artifact types include:
77
- `text`, `table`, `json`, `image`, `banner`, `html`, `plotly_html`, `vega`,
78
- `checkpoint`, and `diff_carousel`.
79
-
80
- ### Export and Import
81
-
82
- - `mcp__flywheel__flywheel_export_subgraph`
83
- - `mcp__flywheel__flywheel_import_subgraph`
84
- - `mcp__flywheel__flywheel_export_summary`
85
- - `mcp__flywheel__flywheel_export_summary_stream`
86
- - `mcp__flywheel__flywheel_export_summary_pdf`
87
- - `mcp__flywheel__flywheel_export_summary_render_pdf`
59
+ - `flywheel_prepare_artifact_uploads` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/artifacts/uploads/prepare`; core surface): Prepare one or more raw-file artifact uploads (returns batch token + signed upload URLs). Upload must send raw file bytes to the returned URLs (do not upload JSON metadata wrappers).
60
+ - `flywheel_finalize_artifact_uploads` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/artifacts/uploads/finalize`; core surface): Finalize a prepared artifact upload batch and append all staged artifacts to the node in one revision bump.
61
+ - `flywheel_list_artifacts` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/artifacts`; core surface): List node artifacts.
62
+ - `flywheel_get_artifact` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/artifacts/{artifact_id}`; core surface): Get one artifact by id.
63
+ - `flywheel_delete_artifact` (mutating; scopes: `write`; HTTP: `DELETE /mcp/nodes/{node_id}/artifacts/{artifact_id}`; core surface): Delete one artifact by id with optimistic locking.
64
+ - `flywheel_set_artifact_note` (mutating; scopes: `write`; HTTP: `PATCH /mcp/nodes/{node_id}/artifacts/{artifact_id}/note`; core surface): Set or clear one artifact note with optimistic locking.
88
65
 
89
66
  ### Executions
90
67
 
91
- - `mcp__flywheel__flywheel_launch_execution`
92
- - `mcp__flywheel__flywheel_list_executions`
93
- - `mcp__flywheel__flywheel_terminate_execution`
94
-
95
- ### Managed Compute
96
-
97
- - `mcp__flywheel__flywheel_approval_session_heartbeat`
98
- - `mcp__flywheel__flywheel_list_approval_sessions`
99
- - `mcp__flywheel__flywheel_expire_approval_session`
100
- - `mcp__flywheel__flywheel_request_compute_grant_approval`
101
- - `mcp__flywheel__flywheel_list_compute_grants`
102
- - `mcp__flywheel__flywheel_compute_list_options`
103
- - `mcp__flywheel__flywheel_compute_acquire`
104
- - `mcp__flywheel__flywheel_compute_status`
105
- - `mcp__flywheel__flywheel_compute_connection`
106
- - `mcp__flywheel__flywheel_compute_release`
107
- - `mcp__flywheel__flywheel_compute_release_all`
108
-
109
- ### Campaign Budgets (Organizer Flows)
110
-
111
- - `mcp__flywheel__flywheel_list_campaign_budgets`
112
- - `mcp__flywheel__flywheel_create_campaign_budget`
113
- - `mcp__flywheel__flywheel_update_campaign_budget`
114
- - `mcp__flywheel__flywheel_revoke_campaign_budget`
115
-
116
- ### Migration Helpers
117
-
118
- Some installations may expose migration-only helper tools with hashed names.
119
- Treat these as specialized one-off tools, not part of day-to-day research
120
- workflows.
68
+ - `flywheel_launch_execution` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/executions`; core surface): Launch node execution.
69
+ - `flywheel_list_executions` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/executions`; core surface): List node executions.
70
+ - `flywheel_terminate_execution` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/executions/{execution_id}/terminate`; core surface): Terminate a node execution.
71
+
72
+ ### Compute and budgets
73
+
74
+ - `flywheel_compute_list_options` (read; scopes: `compute`; HTTP: `GET /mcp/nodes/{node_id}/compute/options`; core surface): List managed compute options allowed for a node. When using grant-backed compute, pass the same compute_grant_id you will use for acquire.
75
+ - `flywheel_compute_status` (read; scopes: `compute`; HTTP: `GET /mcp/compute/status`; core surface): Read managed compute lease status for the current user and current lease_control_token scope. Lease rows include ownership flags so hosts can distinguish user-owned leases from sponsor-visible campaign leases. When checking a grant-backed lease, reuse the same compute_grant_id passed to acquire.
76
+ - `flywheel_compute_connection` (read; scopes: `compute`; HTTP: `GET /mcp/compute/connection`; core surface): Read SSH connection material for an active managed compute lease once flywheel_compute_status indicates the lease is usable. This tool is token-scoped to lease_control_token and only leases owned by the current user are connectable. Pass lease_id or node_id to disambiguate when needed.
77
+ - `flywheel_approval_session_heartbeat` (read; scopes: `compute`; HTTP: `POST /mcp/approval-sessions/heartbeat`; core surface): Create or refresh a compute-grant approval session for the current MCP host session.
78
+ - `flywheel_list_approval_sessions` (read; scopes: `compute`; HTTP: `GET /mcp/approval-sessions`; core surface): List approval sessions visible to the current user.
79
+ - `flywheel_expire_approval_session` (mutating; scopes: `compute`; HTTP: `POST /mcp/approval-sessions/expire`; core surface): Expire the current compute-grant approval session context without releasing active leases.
80
+ - `flywheel_request_compute_grant_approval` (mutating; scopes: `compute`; HTTP: `tool-mediated`; core surface): Request budget approval context before managed compute acquisition; branch on response status.
81
+ - `flywheel_list_compute_grants` (read; scopes: `compute`; HTTP: `GET /mcp/compute/grants`; core surface): List active/exhausted compute grants available to the current user.
82
+ - `flywheel_list_campaign_budgets` (read; scopes: `compute`; HTTP: `GET /mcp/nodes/{root_node_id}/campaign-budgets`; full-surface only): List campaign compute budgets for a campaign root. Organizer-only management view.
83
+ - `flywheel_create_campaign_budget` (mutating; scopes: `compute`; HTTP: `POST /mcp/nodes/{root_node_id}/campaign-budgets`; full-surface only): Create an organizer-funded campaign compute budget shared with participants.
84
+ - `flywheel_update_campaign_budget` (mutating; scopes: `compute`; HTTP: `PATCH /mcp/nodes/{root_node_id}/campaign-budgets/{compute_budget_id}`; full-surface only): Update hard caps or metadata for an organizer-funded campaign compute budget.
85
+ - `flywheel_revoke_campaign_budget` (mutating; scopes: `compute`; HTTP: `DELETE /mcp/nodes/{root_node_id}/campaign-budgets/{compute_budget_id}`; full-surface only): Revoke an organizer-funded campaign compute budget.
86
+ - `flywheel_compute_acquire` (mutating; scopes: `compute`; HTTP: `tool-mediated`; core surface): Acquire managed compute for a node with explicit SKU + region and required compute_grant_id (returns accepted/completed lease state only; poll flywheel_compute_status for readiness, not SSH key material). This tool forwards approval_session_id.
87
+ - `flywheel_compute_release` (mutating; scopes: `compute`; HTTP: `POST /mcp/compute/release`; core surface): Asynchronously release one managed compute lease by lease_id within the current lease_control_token scope.
88
+ - `flywheel_compute_release_all` (mutating; scopes: `compute`; HTTP: `POST /mcp/compute/release-all`; core surface): Asynchronously release active managed compute leases in the current lease_control_token scope; set force=true for explicit account-wide cleanup for the current user.
89
+
90
+ ### Contract, audit, and export
91
+
92
+ - `flywheel_get_contract` (read; scopes: `read`; HTTP: `GET /mcp/contract`; core surface): Return Flywheel MCP contract overview (scopes, write safety, operation catalog, and section index).
93
+ - `flywheel_get_contract_section` (read; scopes: `read`; HTTP: `GET /mcp/contract/sections/{section_id}`; core surface): Return one contract section by section_id (for example `graph` or `campaign/template_v1`).
94
+ - `flywheel_export_subgraph` (read; scopes: `read`; HTTP: `POST /mcp/export`; full-surface only): Export selected graph/subgraph nodes as JSON.
95
+ - `flywheel_import_subgraph` (mutating; scopes: `write`; HTTP: `POST /mcp/import`; full-surface only): Import graph/subgraph JSON payload into new node IDs. Set normalize_cycles=true to drop cycle/self-loop edges; default rejects cyclic payloads.
96
+ - `flywheel_summarize_node_tree` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/summary`; full-surface only): Summarize a node tree using node fields only.
97
+ - `flywheel_export_summary` (read; scopes: `read`; HTTP: `POST /mcp/export-summary`; full-surface only): Generate markdown summary for selected nodes.
98
+ - `flywheel_export_summary_stream` (read; scopes: `read`; HTTP: `POST /mcp/export-summary-stream`; full-surface only): Generate summary stream events for selected nodes.
99
+ - `flywheel_export_summary_pdf` (read; scopes: `read`; HTTP: `POST /mcp/export-summary-pdf`; full-surface only): Generate PDF summary for selected nodes.
100
+ - `flywheel_export_summary_render_pdf` (read; scopes: `read`; HTTP: `POST /mcp/export-summary-render-pdf`; full-surface only): Render provided markdown to PDF and embed export metadata.
121
101
 
122
102
  ## Practical Tool Sequences
123
103
 
124
- ### Insight Node Flow
125
-
126
- 1. `mcp__flywheel__flywheel_stage_node_create`
127
- 2. `mcp__flywheel__flywheel_stage_node_update`
128
- 3. `mcp__flywheel__flywheel_commit_node`
129
-
130
- ### Empirical Node With Artifacts
131
-
132
- 1. `mcp__flywheel__flywheel_stage_node_create`
133
- 2. `mcp__flywheel__flywheel_stage_node_update`
134
- 3. Run experiment or compute steps
135
- 4. `mcp__flywheel__flywheel_prepare_artifact_uploads`
136
- 5. Upload artifact bytes to signed URLs
137
- 6. `mcp__flywheel__flywheel_finalize_artifact_uploads`
138
- 7. `mcp__flywheel__flywheel_commit_node`
139
-
140
- ### Managed Compute Flow
141
-
142
- 1. `mcp__flywheel__flywheel_approval_session_heartbeat`
143
- 2. `mcp__flywheel__flywheel_request_compute_grant_approval`
144
- 3. `mcp__flywheel__flywheel_list_compute_grants` (if needed)
145
- 4. `mcp__flywheel__flywheel_compute_acquire`
146
- 5. `mcp__flywheel__flywheel_compute_status` until ready
147
- 6. `mcp__flywheel__flywheel_compute_connection`
148
- 7. `mcp__flywheel__flywheel_compute_release` (or `..._release_all`)
149
-
150
- ### Share a Graph With Collaborators
151
-
152
- 1. `mcp__flywheel__flywheel_get_node_sharing`
153
- 2. `mcp__flywheel__flywheel_set_sharing_for_node` (or `..._for_nodes`)
154
- 3. `mcp__flywheel__flywheel_export_summary` or `..._export_subgraph` for handoff
155
-
156
- ## Safety Notes
157
-
158
- - Prefer `get_contract` before implementing strict assumptions in automation.
159
- - Avoid call-order assumptions not mandated by contract.
160
- - Keep checks bounded: list/read first, then mutate only the intended nodes.
104
+ ### List Owned Nodes
105
+
106
+ 1. `flywheel_list_nodes` with `{'owners': ['me'], 'projection': 'core'}`.
107
+
108
+ ### Safe Node Update
109
+
110
+ 1. `flywheel_get_node`: Read latest node state before mutating fields.
111
+ 2. `flywheel_acquire_stage_lease`: Acquire a session-scoped stage lease before editing an existing node locally.
112
+ 3. `flywheel_commit_node`: Commit with `stage_session_id`, `base_committed_revision`, and full `staged_payload` once terminal and contract-complete.
113
+
114
+ ### Empirical Workflow
115
+
116
+ 1. `flywheel_commit_new_node`: Commit a local staged new node to canonical storage as the first persistence boundary.
117
+ 2. `flywheel_commit_node`: Commit staged empirical fields with `stage_session_id`, `base_committed_revision`, and a full `staged_payload` once the working state is ready to publish.
118
+ 3. `flywheel_request_compute_grant_approval`: If compute is needed, request budget approval context first. Branch on response status.
119
+ 4. Branch on `flywheel_request_compute_grant_approval.status`: Branch by response status (`already_approved`, `approval_required`, `insufficient_credits`).. if `already_approved` then `reuse_compute_grant_id`: Use returned `compute_grant_id` directly for flywheel_compute_acquire.. if `approval_required` then `present_approval_url_to_user`: Present `approval_url` to the user; the user opens it and confirms budget approval.; `flywheel_list_compute_grants`: After approval, list active grants for the current `approval_session_id` and use the returned `compute_grant_id` for acquire.. if `insufficient_credits` then `request_user_credit_top_up`: No `approval_url` is returned. Ask the user to add credits, then retry flywheel_request_compute_grant_approval.
120
+ 5. `flywheel_compute_acquire`: Acquire lease with `compute_grant_id`; include `approval_session_id` from approval response.
121
+ 6. `flywheel_compute_status`: Poll until the active lease is ready; follow `recommended_next_action`.
122
+ 7. `flywheel_launch_execution`: Launch execution once compute and inputs are ready.
123
+ 8. `flywheel_list_executions`: Poll until execution reaches terminal status.
124
+ 9. `flywheel_prepare_artifact_uploads`: Prepare signed upload URLs for empirical evidence.
125
+ 10. `raw_file_upload`: Upload raw bytes to each signed URL with required headers.
126
+ 11. `flywheel_finalize_artifact_uploads`: Finalize prepared uploads before commit, or set `no_artifacts_reason` when intentionally artifact-free.
127
+ 12. `flywheel_commit_node`: Commit terminal empirical node once contract requirements are satisfied.
128
+
129
+ ## Runtime Guidance
130
+
131
+ - `flywheel_resolve_node_slug`: resolve human-facing slug references. If response status is `ambiguous`, ask the user to confirm the intended node_id before mutating anything.
132
+ - `flywheel_get_node`: read the current node state before writes.
133
+ - `flywheel_acquire_stage_lease`, `flywheel_heartbeat_stage_lease`, `flywheel_release_stage_lease`: coordinate session-scoped local staged edits for an existing node before commit.
134
+ - `flywheel_get_campaign_snapshot`: read the current derived campaign state for this node's root campaign instead of inferring standings from freeform text.
135
+ - `flywheel_get_node_sharing`: after sharing writes, verify with flywheel_get_node_sharing before reporting private/shared/public state.
136
+ - `flywheel_compute_status`: check first when work may need managed compute (GPU), using the active lease_control_token from host context (or pass it explicitly).
137
+ - `flywheel_list_compute_grants`: list active compute grants (funded by user/root budgets) and select one `compute_grant_id` for acquisition.
138
+ - `flywheel_request_compute_grant_approval`: request/confirm budget before acquire and choose a budget source (`user` or `root`); branch on status (`already_approved`, `approval_required`, `insufficient_credits`).
139
+ - `flywheel_compute_connection`: read SSH connection material for the active user lease once status indicates the lease is usable, scoped by lease_control_token.
140
+ - `flywheel_compute_list_options`: use when a lease is needed and no suitable active lease exists, then select explicit provider-qualified `offer_id` (`provider::offer_id`) and `region`. Consider each option's `availability_mode`: `live_capacity` means provider-reported capacity, `allocation_time` means capacity is confirmed only when `flywheel_compute_acquire` attempts provisioning.
141
+ - `flywheel_compute_acquire`: provision compute once requirements are clear. This requires a valid `compute_grant_id` and returns lease/provisioning state only (not SSH key material). Capture `compute.lease_control_token` from the response for follow-up lease control tools.
142
+ - `flywheel_compute_release`: release compute when no longer needed, scoped by lease_control_token.
143
+ - `flywheel_launch_execution`, `flywheel_list_executions`, `flywheel_terminate_execution`: manage execution status transitions.
144
+ - `flywheel_prepare_artifact_uploads`: prepare one or more signed raw-file upload requests for concrete deliverables/evidence produced by the work.
145
+ - `flywheel_finalize_artifact_uploads`: finalize a staged artifact batch and append all uploaded artifacts in one revision bump.
146
+ - `flywheel_delete_artifact`: remove an accidental/obsolete node artifact.
147
+ - `flywheel_list_artifacts`, `flywheel_get_artifact`: inspect node artifact metadata (`title` is the display label) and consume `storage_url` for raw artifact bytes only.
148
+ - `flywheel_commit_new_node`, `flywheel_commit_node`: publish the caller's full staged payload for an existing node once terminal and contract-complete; requires an active stage lease and explicit `base_committed_revision`.
@@ -9,6 +9,14 @@ npx @paradigma-inc/flywheel uninstall
9
9
 
10
10
  `uninstall` removes Flywheel MCP entries from host config files.
11
11
 
12
+ If you choose to refresh via `skills experimental_sync` instead of rerunning
13
+ setup, install Flywheel locally in that project first:
14
+
15
+ ```bash
16
+ npm install --save-dev @paradigma-inc/flywheel@latest
17
+ npx skills experimental_sync --agent codex -y
18
+ ```
19
+
12
20
  ## FAQ: How Do I Migrate from the Previous OAuth-Based MCP Client Setup?
13
21
 
14
22
  If you installed Flywheel MCP before April 2026, migrate to the newer, more stable API key authentication setup with:
@@ -21,7 +21,8 @@ Before execution, recover or establish these inputs:
21
21
  - Ask only when a required execution input cannot be recovered from explicit user instructions, current conversational context, or recent graph state.
22
22
  - If start nodes cannot be recovered from explicit ids/slugs, named current context, or recent graph context, ask once.
23
23
  - If the objective is missing, ask once; if the user refuses, infer it from graph context and persist it before execution.
24
- - If budget ceiling, budget unit, or terminal condition is missing, ask once before execution. If the budget contract remains incomplete, keep planning but do not request compute approval or acquire compute.
24
+ - If budget ceiling or budget unit is missing, ask once before execution.
25
+ - If budget ceiling and budget unit are present but terminal condition is missing, set `terminal_condition: "budget ceiling reached"` and persist that derivation in the control node `content` before compute request or acquisition.
25
26
  - If the user gives a non-credit budget unit, persist that exact user-facing unit and derive the operational compute approval cap before acquisition.
26
27
 
27
28
  ## Working Terms
@@ -37,6 +38,7 @@ Before execution, recover or establish these inputs:
37
38
  - Use artifacts for supporting files and evidence, not as a substitute for the node's main narrative.
38
39
  - Only create graph edges for durable semantic relationships, because graphifying every wiki link floods the graph with noise that hides decision-relevant structure.
39
40
  - Treat the flywheel-auto skill as graph-local autonomous research: persist the run contract in the graph, keep the plan `n` hops ahead, and spend only within an explicit measured budget.
41
+ - When guidance from flywheel, flywheel-lookahead, flywheel-reproduce, or flywheel-to-graph conflicts during an active $flywheel-auto run, flywheel-auto rules take precedence for compute, questioning, and stop decisions.
40
42
  - Ask only the minimum clarification questions needed to establish a coherent control contract, and ask none when the required answers are already recoverable from user instructions, conversational context, or graph state.
41
43
  - Planned nodes that are expected to produce evidence or artifacts should be typed `empirical`; planned nodes that only encode synthesis, decomposition, or decision structure should be typed `insight`.
42
44
  - Keep the control node typed `insight` and keep its `insights` non-empty so the insight commit contract stays valid.
@@ -49,12 +51,12 @@ Before execution, recover or establish these inputs:
49
51
  2. Resolve the objective and budget contract.
50
52
  - Recover required execution inputs from the current conversation and graph first. Ask only for inputs that remain genuinely missing after that recovery pass.
51
53
  - The flywheel-auto skill requires a measurable objective and an explicit terminal condition. Ask once for missing prerequisites; if the user refuses to specify an objective, infer it from the available graph context and state it explicitly before continuing.
52
- - The budget contract must be explicit before execution starts. Ask once for any missing budget ceiling, budget unit, or terminal condition. If those inputs remain unavailable after one clarification round, keep planning but do not request compute approval or acquire compute.
54
+ - The budget contract must be explicit before execution starts. Ask once for missing budget ceiling or budget unit. When budget ceiling and budget unit are present but terminal condition is missing, derive `terminal_condition: "budget ceiling reached"` and persist that derivation into the control node `content` before any compute request or acquisition.
53
55
  - Managed compute spend is billed in Flywheel credits. If the user gives dollars, hours, or another measurable budget semantic, persist that user-facing cap explicitly and derive the operational compute approval cap before acquisition.
54
56
  - Persist the run contract in a dedicated `insight` control node for this frontier. Put the canonical contract in node `content`, keep a one-line synopsis in `summary`, and keep brief run rationale in `insights` so the commit contract stays valid.
55
57
  - The control contract must name: objective, decision criterion, start nodes, budget ceiling and unit, lookahead depth `n`, frontier width `k`, and an explicit terminal condition.
56
58
  - Later flywheel-auto replans must read the control node `content` first and continue from that persisted contract rather than from chat memory.
57
- - Run the design gate from [references/experiment-design-protocol.md](references/experiment-design-protocol.md) before the first compute request: confirm objective, decision criterion, evidence plan, and budget readiness, even though later continuation decisions become graph-local.
59
+ - Run the design gate from [references/experiment-design-protocol-autonomous.md](references/experiment-design-protocol-autonomous.md) before the first compute request: confirm objective, decision criterion, evidence plan, budget readiness, and stop-reason recording requirements, even though later continuation decisions become graph-local.
58
60
  3. Map each stable page, claim, or concept to a node.
59
61
  - For exact node-mutation shapes, load [references/flywheel-mcp-tool-map.md](references/flywheel-mcp-tool-map.md).
60
62
  - Create a new node with `flywheel_stage_node_create` when needed.
@@ -78,16 +80,20 @@ Before execution, recover or establish these inputs:
78
80
  - In the flywheel-auto skill, the same `k` also caps concurrent workers pursuing executable frontier nodes.
79
81
  - Keep unresolved plan nodes staged until the corresponding work is resolved.
80
82
  8. Execute and replan continuously.
81
- - For exact execution and compute request shapes, load [references/flywheel-mcp-tool-map.md](references/flywheel-mcp-tool-map.md) and [references/experiment-design-protocol.md](references/experiment-design-protocol.md).
83
+ - For exact execution and compute request shapes, load [references/flywheel-mcp-tool-map.md](references/flywheel-mcp-tool-map.md) and [references/experiment-design-protocol-autonomous.md](references/experiment-design-protocol-autonomous.md).
82
84
  - Use `flywheel_launch_execution` when the branch can run as a Flywheel node execution without a separate leased machine, and inspect terminal status before commit.
83
- - Use managed compute when the branch needs provider or SKU choice, SSH access, a custom runtime, or longer-lived hardware. In that case use `flywheel_request_compute_grant_approval`, resolve the approved `compute_grant_id` with `flywheel_list_compute_grants` or `flywheel_list_approval_sessions`, then `flywheel_compute_acquire`, poll `flywheel_compute_status`, and use `flywheel_compute_connection` when the lease is ready.
85
+ - Use managed compute when the branch needs provider or SKU choice, SSH access, a custom runtime, or longer-lived hardware. In that case use `flywheel_request_compute_grant_approval`, resolve the approved `compute_grant_id` with `flywheel_list_compute_grants(status=active, approval_session_id=<session_id>)`, call `flywheel_compute_list_options`, recommend one offer deterministically and present up to two alternatives, wait for explicit user confirmation (or explicit user override offer id), then `flywheel_compute_acquire`, poll `flywheel_compute_status`, and use `flywheel_compute_connection` when the lease is ready.
84
86
  - Spawn up to `k` workers for distinct executable frontier nodes.
87
+ - For `k > 1`, apply the list-options -> recommendation -> explicit confirmation boundary per worker before each worker-specific acquire call.
85
88
  - Route additional viable branches sequentially when there are more than `k` worthwhile directions.
86
89
  - After each resolved node, refresh the lookahead so the graph remains `n` hops ahead.
87
90
  - Release managed compute when a branch is done. Default to releasing only
88
91
  known leases. Use `flywheel_compute_release_all` only when the user
89
92
  explicitly requests account-wide cleanup.
90
93
  - Stop only when the graph-local terminal condition says to stop, such as: objective met, budget exhausted, or no non-redundant frontier branch is likely to produce enough decision-relevant information to justify the remaining budget and duplication risk.
94
+ - If stopping because no non-redundant frontier branch is worth pursuing, record a per-candidate rejection rationale in control node `content` before termination.
95
+ - Before every termination path, persist `stop_reason` in control node `content` as one of: `budget_exhausted`, `objective_met`, `no_viable_branch`, `user_cancelled`, `runtime_error`.
96
+
91
97
  9. Commit after the node snapshot is coherent with `flywheel_commit_node`.
92
98
  - Commit resolved insight nodes only when they have non-empty `insights`.
93
99
  - Commit resolved empirical nodes only when outcome and artifact rules are satisfied.
@@ -102,7 +108,8 @@ When the skill completes a pass, it should leave behind:
102
108
  - Zero or more committed resolved nodes, but only when their commit contracts are satisfied.
103
109
  - Uploaded artifacts for completed empirical work, or an explicit `no_artifacts_reason` when artifacts are absent by design.
104
110
  - Released managed compute if any lease was acquired during the pass.
105
- - An explicit stop reason, continuation rule, or next action recorded in node state so a later pass can resume graph-locally.
111
+ - An explicit `stop_reason` recorded in node state so a later pass can resume graph-locally.
112
+ - If the no-branch stop clause is used, a per-candidate rejection log recorded in control node `content`.
106
113
 
107
114
  ## Persisted Control Contract
108
115
 
@@ -140,6 +147,7 @@ Canonical contract shape:
140
147
  - Lookahead depth:
141
148
  - Frontier width:
142
149
  - Terminal condition:
150
+ - Stop reason:
143
151
  ```
144
152
 
145
153
  Use `Compute approval cap` for the operational cap that will govern managed
@@ -11,6 +11,12 @@
11
11
  "expected_output": "Persist the dollar-denominated budget ceiling and unit verbatim in the control node, derive an operational compute approval cap before acquisition, record both values before any compute request is made, and leave a coherent run contract behind for later continuation.",
12
12
  "files": []
13
13
  },
14
+ {
15
+ "id": "cold-start-budget-only-auto-exhaustion",
16
+ "prompt": "Use $flywheel-auto to continue autonomously under a budget ceiling when only the budget contract is explicit at cold start.",
17
+ "expected_output": "When terminal condition is missing but budget ceiling and budget unit are explicit, derive terminal condition as budget ceiling reached, continue autonomously without premature user handoff, and persist stop_reason in the committed control contract before termination.",
18
+ "files": []
19
+ },
14
20
  {
15
21
  "id": "cold-start-with-no-objective",
16
22
  "prompt": "Use $flywheel-auto to go autonomous on this Flywheel graph until you find something interesting. If I refuse to specify an objective, infer one from the graph context and make it explicit before you execute.",