@really-knows-ai/foundry 2.3.2 → 3.0.1

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 (170) hide show
  1. package/README.md +180 -369
  2. package/dist/.opencode/plugins/foundry-tools/appraiser-tools.js +28 -0
  3. package/dist/.opencode/plugins/foundry-tools/artefact-tools.js +58 -0
  4. package/dist/.opencode/plugins/foundry-tools/assay-tools.js +92 -0
  5. package/dist/.opencode/plugins/foundry-tools/attestation-tools.js +191 -0
  6. package/dist/.opencode/plugins/foundry-tools/config-create-tools.js +128 -0
  7. package/dist/.opencode/plugins/foundry-tools/config-law-tools.js +380 -0
  8. package/dist/.opencode/plugins/foundry-tools/config-tools.js +43 -0
  9. package/dist/.opencode/plugins/foundry-tools/feedback-tools.js +234 -0
  10. package/dist/.opencode/plugins/foundry-tools/git-helpers.js +354 -0
  11. package/dist/.opencode/plugins/foundry-tools/git-tools.js +181 -0
  12. package/dist/.opencode/plugins/foundry-tools/helpers.js +340 -0
  13. package/dist/.opencode/plugins/foundry-tools/history-tools.js +20 -0
  14. package/dist/.opencode/plugins/foundry-tools/memory-admin-tools.js +296 -0
  15. package/dist/.opencode/plugins/foundry-tools/memory-helpers.js +104 -0
  16. package/dist/.opencode/plugins/foundry-tools/memory-tools.js +286 -0
  17. package/dist/.opencode/plugins/foundry-tools/orchestrate-tool.js +159 -0
  18. package/dist/.opencode/plugins/foundry-tools/snapshot-tools.js +104 -0
  19. package/dist/.opencode/plugins/foundry-tools/stage-tools.js +186 -0
  20. package/dist/.opencode/plugins/foundry-tools/validate-tools.js +263 -0
  21. package/dist/.opencode/plugins/foundry-tools/workfile-tools.js +102 -0
  22. package/dist/.opencode/plugins/foundry.js +105 -0
  23. package/dist/CHANGELOG.md +533 -0
  24. package/dist/LICENSE +21 -0
  25. package/dist/README.md +278 -0
  26. package/dist/docs/README.md +59 -0
  27. package/dist/docs/architecture.md +433 -0
  28. package/dist/docs/concepts.md +395 -0
  29. package/dist/docs/getting-started.md +344 -0
  30. package/dist/docs/memory-maintenance.md +176 -0
  31. package/dist/docs/tools.md +1411 -0
  32. package/dist/docs/work-spec.md +283 -0
  33. package/dist/scripts/lib/artefacts.js +151 -0
  34. package/dist/scripts/lib/assay/loader.js +151 -0
  35. package/dist/scripts/lib/assay/parse-jsonl.js +102 -0
  36. package/dist/scripts/lib/assay/permissions.js +52 -0
  37. package/dist/scripts/lib/assay/run.js +219 -0
  38. package/dist/scripts/lib/assay/spawn-with-timeout.js +138 -0
  39. package/dist/scripts/lib/attestation/attest.js +111 -0
  40. package/dist/scripts/lib/attestation/canonical-json.js +109 -0
  41. package/dist/scripts/lib/attestation/hash.js +17 -0
  42. package/dist/scripts/lib/attestation/parse.js +14 -0
  43. package/dist/scripts/lib/attestation/payload.js +106 -0
  44. package/dist/scripts/lib/attestation/render.js +16 -0
  45. package/dist/scripts/lib/attestation/verify.js +15 -0
  46. package/dist/scripts/lib/branch-guard.js +72 -0
  47. package/dist/scripts/lib/config-creators/appraiser.js +9 -0
  48. package/dist/scripts/lib/config-creators/artefact-type.js +9 -0
  49. package/dist/scripts/lib/config-creators/cycle.js +11 -0
  50. package/dist/scripts/lib/config-creators/factory.js +49 -0
  51. package/dist/scripts/lib/config-creators/flow.js +11 -0
  52. package/dist/scripts/lib/config-validators/appraiser.js +49 -0
  53. package/dist/scripts/lib/config-validators/artefact-type.js +38 -0
  54. package/dist/scripts/lib/config-validators/cycle.js +131 -0
  55. package/dist/scripts/lib/config-validators/flow.js +57 -0
  56. package/dist/scripts/lib/config-validators/helpers.js +96 -0
  57. package/dist/scripts/lib/config-validators/law.js +96 -0
  58. package/dist/scripts/lib/config.js +328 -0
  59. package/dist/scripts/lib/failed-flow.js +131 -0
  60. package/dist/scripts/lib/feedback-store.js +249 -0
  61. package/dist/scripts/lib/feedback-transitions.js +105 -0
  62. package/dist/scripts/lib/finalize.js +70 -0
  63. package/dist/scripts/lib/foundational-guards.js +13 -0
  64. package/dist/scripts/lib/git-bridge.js +77 -0
  65. package/dist/scripts/lib/git-finish/work-finish.js +233 -0
  66. package/dist/scripts/lib/git-policy.js +101 -0
  67. package/dist/scripts/lib/guards.js +125 -0
  68. package/dist/scripts/lib/history.js +132 -0
  69. package/dist/scripts/lib/memory/admin/create-edge-type.js +91 -0
  70. package/dist/scripts/lib/memory/admin/create-entity-type.js +43 -0
  71. package/dist/scripts/lib/memory/admin/create-extractor.js +67 -0
  72. package/dist/scripts/lib/memory/admin/drop-edge-type.js +40 -0
  73. package/dist/scripts/lib/memory/admin/drop-entity-type.js +172 -0
  74. package/dist/scripts/lib/memory/admin/dump.js +47 -0
  75. package/dist/scripts/lib/memory/admin/helpers.js +31 -0
  76. package/dist/scripts/lib/memory/admin/init.js +170 -0
  77. package/dist/scripts/lib/memory/admin/live-store.js +76 -0
  78. package/dist/scripts/lib/memory/admin/reembed.js +285 -0
  79. package/dist/scripts/lib/memory/admin/rename-edge-type.js +54 -0
  80. package/dist/scripts/lib/memory/admin/rename-entity-type.js +151 -0
  81. package/dist/scripts/lib/memory/admin/reset.js +24 -0
  82. package/dist/scripts/lib/memory/admin/vacuum.js +9 -0
  83. package/dist/scripts/lib/memory/admin/validate.js +19 -0
  84. package/dist/scripts/lib/memory/config.js +149 -0
  85. package/dist/scripts/lib/memory/cozo.js +136 -0
  86. package/dist/scripts/lib/memory/drift.js +71 -0
  87. package/dist/scripts/lib/memory/embeddings.js +128 -0
  88. package/dist/scripts/lib/memory/frontmatter.js +75 -0
  89. package/dist/scripts/lib/memory/ndjson.js +84 -0
  90. package/dist/scripts/lib/memory/paths.js +25 -0
  91. package/dist/scripts/lib/memory/permissions.js +41 -0
  92. package/dist/scripts/lib/memory/prompt.js +109 -0
  93. package/dist/scripts/lib/memory/query.js +56 -0
  94. package/dist/scripts/lib/memory/reads.js +109 -0
  95. package/dist/scripts/lib/memory/schema.js +64 -0
  96. package/dist/scripts/lib/memory/search.js +73 -0
  97. package/dist/scripts/lib/memory/singleton.js +49 -0
  98. package/dist/scripts/lib/memory/store.js +162 -0
  99. package/dist/scripts/lib/memory/types.js +93 -0
  100. package/dist/scripts/lib/memory/validate.js +58 -0
  101. package/dist/scripts/lib/memory/writes.js +40 -0
  102. package/{scripts → dist/scripts}/lib/pending.js +7 -2
  103. package/dist/scripts/lib/secret.js +59 -0
  104. package/{scripts → dist/scripts}/lib/slug.js +3 -2
  105. package/dist/scripts/lib/snapshot/finish.js +103 -0
  106. package/dist/scripts/lib/snapshot/inspect.js +253 -0
  107. package/dist/scripts/lib/snapshot/render.js +55 -0
  108. package/dist/scripts/lib/sort-fs-check.js +121 -0
  109. package/dist/scripts/lib/sort-routing.js +101 -0
  110. package/{scripts → dist/scripts}/lib/stage-guard.js +12 -6
  111. package/{scripts → dist/scripts}/lib/state.js +4 -0
  112. package/dist/scripts/lib/token.js +57 -0
  113. package/dist/scripts/lib/tracing.js +59 -0
  114. package/dist/scripts/lib/ulid.js +100 -0
  115. package/dist/scripts/lib/validator-jsonl.js +162 -0
  116. package/{scripts → dist/scripts}/lib/workfile.js +38 -20
  117. package/dist/scripts/orchestrate-cycle.js +215 -0
  118. package/dist/scripts/orchestrate-phases.js +314 -0
  119. package/dist/scripts/orchestrate.js +163 -0
  120. package/dist/scripts/sort.js +278 -0
  121. package/{skills → dist/skills}/add-appraiser/SKILL.md +39 -9
  122. package/{skills → dist/skills}/add-artefact-type/SKILL.md +62 -40
  123. package/{skills → dist/skills}/add-cycle/SKILL.md +57 -17
  124. package/dist/skills/add-extractor/SKILL.md +133 -0
  125. package/{skills → dist/skills}/add-flow/SKILL.md +36 -10
  126. package/dist/skills/add-law/SKILL.md +191 -0
  127. package/dist/skills/add-memory-edge-type/SKILL.md +52 -0
  128. package/dist/skills/add-memory-entity-type/SKILL.md +74 -0
  129. package/{skills → dist/skills}/appraise/SKILL.md +62 -13
  130. package/dist/skills/assay/SKILL.md +72 -0
  131. package/dist/skills/change-embedding-model/SKILL.md +58 -0
  132. package/dist/skills/drop-memory-edge-type/SKILL.md +54 -0
  133. package/dist/skills/drop-memory-entity-type/SKILL.md +57 -0
  134. package/dist/skills/dry-run/SKILL.md +116 -0
  135. package/{skills → dist/skills}/flow/SKILL.md +15 -2
  136. package/dist/skills/forge/SKILL.md +121 -0
  137. package/dist/skills/human-appraise/SKILL.md +153 -0
  138. package/{skills → dist/skills}/init-foundry/SKILL.md +23 -4
  139. package/dist/skills/init-memory/SKILL.md +92 -0
  140. package/{skills → dist/skills}/orchestrate/SKILL.md +30 -4
  141. package/dist/skills/quench/SKILL.md +99 -0
  142. package/{skills → dist/skills}/refresh-agents/SKILL.md +1 -1
  143. package/dist/skills/rename-memory-edge-type/SKILL.md +50 -0
  144. package/dist/skills/rename-memory-entity-type/SKILL.md +51 -0
  145. package/dist/skills/reset-memory/SKILL.md +54 -0
  146. package/dist/skills/upgrade-foundry/SKILL.md +191 -0
  147. package/package.json +34 -17
  148. package/.opencode/plugins/foundry.js +0 -761
  149. package/CHANGELOG.md +0 -100
  150. package/docs/concepts.md +0 -122
  151. package/docs/getting-started.md +0 -187
  152. package/docs/work-spec.md +0 -207
  153. package/scripts/lib/artefacts.js +0 -124
  154. package/scripts/lib/config.js +0 -175
  155. package/scripts/lib/feedback-transitions.js +0 -25
  156. package/scripts/lib/feedback.js +0 -440
  157. package/scripts/lib/finalize.js +0 -41
  158. package/scripts/lib/history.js +0 -59
  159. package/scripts/lib/secret.js +0 -23
  160. package/scripts/lib/tags.js +0 -108
  161. package/scripts/lib/token.js +0 -26
  162. package/scripts/orchestrate.js +0 -418
  163. package/scripts/sort.js +0 -370
  164. package/scripts/validate-tags.js +0 -54
  165. package/skills/add-law/SKILL.md +0 -111
  166. package/skills/forge/SKILL.md +0 -88
  167. package/skills/human-appraise/SKILL.md +0 -82
  168. package/skills/quench/SKILL.md +0 -62
  169. package/skills/upgrade-foundry/SKILL.md +0 -216
  170. /package/{skills → dist/skills}/list-agents/SKILL.md +0 -0
@@ -0,0 +1,1411 @@
1
+ # Foundry Public Tool Reference
2
+
3
+ Generated from the v3.0.x public plugin API. The authoritative tool set is
4
+ enforced by `tests/plugin/tool-registration.test.js` — if that snapshot
5
+ drifts, this doc must be updated. Total: **65 tools**.
6
+
7
+ All tools accept arguments as a JSON object and return JSON-stringified
8
+ results. Errors are returned as a stringified `{error: "..."}` object (not
9
+ thrown) unless noted otherwise. Some destructive tools require an explicit
10
+ `confirm: true` flag.
11
+
12
+ For a higher-level explanation of stages, cycles, WORK.md, and the feedback
13
+ state machine, see [`docs/concepts.md`](./concepts.md) and
14
+ [`docs/work-spec.md`](./work-spec.md).
15
+
16
+ ## Conventions
17
+
18
+ - **Active stage**: many tools require `foundry_stage_begin` to have been
19
+ called and not yet ended. The active stage is recorded in
20
+ `.foundry/active-stage.json`. Tools annotated "requires active stage"
21
+ return an error if called outside one. Tools annotated "requires no
22
+ active stage" do the opposite.
23
+ - **Stage base**: stage aliases have the form `<base>:<cycle>` (e.g.
24
+ `forge:create-haiku`). Some tools restrict to a particular base
25
+ (`forge`, `quench`, `appraise`, `human-appraise`, `assay`).
26
+ - **Failed flow**: when `WORK.md` frontmatter has `status: failed`:
27
+ - Mutating families refuse to run and return an error prefixed with the tool name. This covers work-branch FS writers, memory writers and mutating memory admin tools (`memory_put`, `memory_reset`, `memory_drop_*`, `memory_rename_*`, `memory_create_*`, `memory_init`, `memory_vacuum`, `memory_change_embedding_model`), the config-creator family (`foundry_config_create_artefact_type`, `foundry_config_create_appraiser`, `foundry_config_create_flow`, `foundry_config_create_cycle`), and the law mutators (`foundry_config_add_law`, `foundry_config_edit_law`).
28
+ - Read-only diagnostics remain callable: `foundry_workfile_get`; list tools such as `foundry_artefacts_list`, `foundry_feedback_list`, `foundry_history_list`, and `foundry_memory_list`; every `foundry_config_*` read tool; every `foundry_config_validate_*` schema validator; every memory read tool (`_get`, `_neighbours`, `_query`, `_search`, `_dump`, `_validate`); and every `foundry_snapshot_*` tool.
29
+ - `foundry_git_branch` and `foundry_git_finish` sit outside this guard so the caller can leave the failed branch. The escape hatch is `foundry_workfile_delete`.
30
+ - **Worktree context**: every tool reads `context.worktree` (the project
31
+ root) and operates on `foundry/`, `WORK.md`, `WORK.feedback.yaml`,
32
+ `WORK.history.yaml`, and `.foundry/` relative to it.
33
+ - **Memory permissions**: memory data tools consult the active cycle's
34
+ `memory.read` / `memory.write` frontmatter (via
35
+ `src/scripts/lib/memory/permissions.js`). Reads of disallowed types return
36
+ empty results; writes return an `error`. When no cycle is active the
37
+ call is unscoped (full access).
38
+ - **Branch requirements**: every mutating tool also enforces the branch-namespace split at call time (`src/scripts/lib/branch-guard.js`). The guard is applied per family, so per-tool blocks below do not repeat it:
39
+
40
+ | Namespace | Applies to | Notes |
41
+ |-----------|------------|-------|
42
+ | `config/<description>` | `foundry_config_create_*` (5), `foundry_memory_create_entity_type`, `foundry_memory_create_edge_type`, `foundry_memory_rename_*`, `foundry_memory_drop_*`, `foundry_memory_reset`, `foundry_memory_init`, `foundry_memory_change_embedding_model`, `foundry_extractor_create` | Config and schema mutation only. |
43
+ | `work/<flow>-<desc>` or `dry-run/<x>/<y>` | `foundry_orchestrate`, `foundry_stage_begin`, `foundry_stage_end`, `foundry_stage_retry`, `foundry_workfile_*`, `foundry_artefacts_*`, `foundry_feedback_*`, `foundry_assay_run`, `foundry_validate_run`, `foundry_memory_put`, `foundry_memory_relate`, `foundry_memory_unrelate` | Flow-data mutation only. |
44
+ | Any branch | `foundry_workfile_get`, `foundry_artefacts_list`, `foundry_feedback_list`, `foundry_history_list`, `foundry_config_*` read tools, `foundry_config_validate_*`, `foundry_appraisers_select`, `foundry_memory_get`, `foundry_memory_list`, `foundry_memory_neighbours`, `foundry_memory_query`, `foundry_memory_search`, `foundry_memory_dump`, `foundry_memory_validate`, `foundry_snapshot_*` | No branch guard and no failed-flow guard. |
45
+ | Self-classifying | `foundry_git_branch`, `foundry_git_finish` | Each tool checks its own branch rules. Leaving the failed branch is the recovery path. |
46
+
47
+ Off-namespace calls return a structured refusal envelope naming the required namespace and the current branch.
48
+
49
+ ## Tool index
50
+
51
+ **Lifecycle**
52
+ - [`foundry_stage_begin`](#foundry_stage_begin)
53
+ - [`foundry_stage_end`](#foundry_stage_end)
54
+ - [`foundry_stage_retry`](#foundry_stage_retry)
55
+ - [`foundry_orchestrate`](#foundry_orchestrate)
56
+ - [`foundry_workfile_create`](#foundry_workfile_create)
57
+ - [`foundry_workfile_get`](#foundry_workfile_get)
58
+ - [`foundry_workfile_delete`](#foundry_workfile_delete)
59
+
60
+ **Artefacts**
61
+ - [`foundry_artefacts_list`](#foundry_artefacts_list)
62
+ - [`foundry_artefacts_set_status`](#foundry_artefacts_set_status)
63
+
64
+ **Feedback**
65
+ - [`foundry_feedback_add`](#foundry_feedback_add)
66
+ - [`foundry_feedback_action`](#foundry_feedback_action)
67
+ - [`foundry_feedback_wontfix`](#foundry_feedback_wontfix)
68
+ - [`foundry_feedback_resolve`](#foundry_feedback_resolve)
69
+ - [`foundry_feedback_list`](#foundry_feedback_list)
70
+
71
+ **History**
72
+ - [`foundry_history_list`](#foundry_history_list)
73
+
74
+ **Config (read-only)**
75
+ - [`foundry_config_cycle`](#foundry_config_cycle)
76
+ - [`foundry_config_artefact_type`](#foundry_config_artefact_type)
77
+ - [`foundry_config_laws`](#foundry_config_laws)
78
+ - [`foundry_config_read_law`](#foundry_config_read_law)
79
+ - [`foundry_config_appraisers`](#foundry_config_appraisers)
80
+ - [`foundry_config_flow`](#foundry_config_flow)
81
+
82
+ **Config — Schema validation**
83
+ - [`foundry_config_validate_artefact_type`](#foundry_config_validate_artefact_type)
84
+ - [`foundry_config_validate_law`](#foundry_config_validate_law)
85
+ - [`foundry_config_validate_appraiser`](#foundry_config_validate_appraiser)
86
+ - [`foundry_config_validate_flow`](#foundry_config_validate_flow)
87
+ - [`foundry_config_validate_cycle`](#foundry_config_validate_cycle)
88
+
89
+ **Config — Schema mutation**
90
+ - [`foundry_config_create_artefact_type`](#foundry_config_create_artefact_type)
91
+ - [`foundry_config_add_law`](#foundry_config_add_law)
92
+ - [`foundry_config_edit_law`](#foundry_config_edit_law)
93
+ - [`foundry_config_create_appraiser`](#foundry_config_create_appraiser)
94
+ - [`foundry_config_create_flow`](#foundry_config_create_flow)
95
+ - [`foundry_config_create_cycle`](#foundry_config_create_cycle)
96
+
97
+ **Snapshots**
98
+ - [`foundry_snapshot_list`](#foundry_snapshot_list)
99
+ - [`foundry_snapshot_show`](#foundry_snapshot_show)
100
+ - [`foundry_snapshot_delete`](#foundry_snapshot_delete)
101
+ - [`foundry_snapshot_prune`](#foundry_snapshot_prune)
102
+
103
+ **Validation**
104
+ - [`foundry_validate_run`](#foundry_validate_run)
105
+
106
+ **Appraisers**
107
+ - [`foundry_appraisers_select`](#foundry_appraisers_select)
108
+
109
+ **Assay**
110
+ - [`foundry_assay_run`](#foundry_assay_run)
111
+
112
+ **Git**
113
+ - [`foundry_git_branch`](#foundry_git_branch)
114
+ - [`foundry_git_finish`](#foundry_git_finish)
115
+
116
+ **Attestation**
117
+ - [`foundry_attestation_show`](#foundry_attestation_show)
118
+ - [`foundry_attestation_verify`](#foundry_attestation_verify)
119
+ - [`foundry_attest`](#foundry_attest)
120
+
121
+ **Memory — Data**
122
+ - [`foundry_memory_put`](#foundry_memory_put)
123
+ - [`foundry_memory_relate`](#foundry_memory_relate)
124
+ - [`foundry_memory_unrelate`](#foundry_memory_unrelate)
125
+ - [`foundry_memory_get`](#foundry_memory_get)
126
+ - [`foundry_memory_list`](#foundry_memory_list)
127
+ - [`foundry_memory_neighbours`](#foundry_memory_neighbours)
128
+ - [`foundry_memory_query`](#foundry_memory_query)
129
+ - [`foundry_memory_search`](#foundry_memory_search)
130
+
131
+ **Memory — Admin**
132
+ - [`foundry_memory_init`](#foundry_memory_init)
133
+ - [`foundry_memory_validate`](#foundry_memory_validate)
134
+ - [`foundry_memory_dump`](#foundry_memory_dump)
135
+ - [`foundry_memory_vacuum`](#foundry_memory_vacuum)
136
+ - [`foundry_memory_reset`](#foundry_memory_reset)
137
+ - [`foundry_memory_change_embedding_model`](#foundry_memory_change_embedding_model)
138
+ - [`foundry_memory_create_entity_type`](#foundry_memory_create_entity_type)
139
+ - [`foundry_memory_create_edge_type`](#foundry_memory_create_edge_type)
140
+ - [`foundry_memory_rename_entity_type`](#foundry_memory_rename_entity_type)
141
+ - [`foundry_memory_rename_edge_type`](#foundry_memory_rename_edge_type)
142
+ - [`foundry_memory_drop_entity_type`](#foundry_memory_drop_entity_type)
143
+ - [`foundry_memory_drop_edge_type`](#foundry_memory_drop_edge_type)
144
+ - [`foundry_extractor_create`](#foundry_extractor_create)
145
+
146
+ ---
147
+
148
+ ## Lifecycle
149
+
150
+ ### `foundry_stage_begin`
151
+
152
+ > Open a subagent work stage; consumes a dispatch token from
153
+ > `foundry_orchestrate`.
154
+
155
+ **Args:**
156
+ - `stage` (string, required): Stage alias, e.g. `forge:create-haiku`.
157
+ - `cycle` (string, required): Cycle name.
158
+ - `token` (string, required): Token issued by `foundry_orchestrate` in its
159
+ `dispatch` action payload.
160
+
161
+ **Returns:** `{ ok: true, active: { cycle, stage, tokenHash, baseSha,
162
+ startedAt } }` on success.
163
+
164
+ **Stage requirements:** requires no active stage.
165
+
166
+ **Failure modes:**
167
+ - Flow is failed → `foundry_stage_begin: <reason>`.
168
+ - Active stage already exists → `... requires no active stage; current: <stage>`.
169
+ - Token signature/expiry invalid → `... token <reason>`.
170
+ - Token payload `route`/`cycle` does not match args → `... token payload mismatch (...)`.
171
+ - `git rev-parse HEAD` fails (no commits) → `... git rev-parse HEAD failed (no commits?)`.
172
+ - Token nonce already consumed or unknown → `... nonce not pending or already consumed`.
173
+
174
+ **Side effects:** writes `.foundry/active-stage.json`; consumes the
175
+ single-use nonce from the in-memory pending store.
176
+
177
+ ### `foundry_stage_end`
178
+
179
+ > Close the active subagent work stage; preserves `baseSha` for finalize.
180
+
181
+ **Args:**
182
+ - `summary` (string, required): Short summary of the work done.
183
+
184
+ **Returns:** `{ ok: true, summary }` on success. On post-stage memory sync
185
+ failure: `{ error, flow_failed: true }` and the workfile is marked
186
+ failed.
187
+
188
+ **Stage requirements:** requires active stage.
189
+
190
+ **Failure modes:**
191
+ - No active stage → `foundry_stage_end requires active stage; current: none`.
192
+ - End-of-stage memory sync to NDJSON fails → returns `flow_failed: true`
193
+ and marks `WORK.md` failed (data-loss guard).
194
+
195
+ **Side effects:** writes `.foundry/last-stage.json`, clears
196
+ `.foundry/active-stage.json`, flushes any pending memory writes to
197
+ `foundry-memory/relations/<name>.ndjson`. May mark `WORK.md` as
198
+ `status: failed` on sync failure.
199
+
200
+ ### `foundry_stage_retry`
201
+
202
+ > Retry a failed stage by discarding uncommitted memory changes and
203
+ > clearing the failed state. Requires clean git working tree.
204
+
205
+ **Args:** none.
206
+
207
+ **Returns:** `{ ok: true, message }` on success. `{ ok: false, error }`
208
+ otherwise.
209
+
210
+ **Stage requirements:** requires no active stage. Requires flow to be
211
+ in failed state.
212
+
213
+ **Preconditions:**
214
+ - Flow must have `status: failed`.
215
+ - No active stage exists.
216
+ - Git working tree must be clean (no uncommitted changes).
217
+
218
+ **Failure modes:**
219
+ - Flow not failed → `foundry_stage_retry requires failed flow; current status is not failed`.
220
+ - Active stage exists → `foundry_stage_retry requires no active stage; call foundry_stage_end first`.
221
+ - Dirty working tree → `foundry_stage_retry requires clean git working tree; commit or stash changes first`.
222
+ - Git status check fails → error with git failure message.
223
+
224
+ **Side effects:** invalidates the memory store singleton (discards
225
+ uncommitted changes, resets to on-disk NDJSON state), clears
226
+ `.foundry/last-stage.json`, clears the failed status from `WORK.md`
227
+ frontmatter.
228
+
229
+ ### `foundry_orchestrate`
230
+
231
+ > Run the next step of the current cycle. Call with no args on first
232
+ > invocation; call with `lastResult={ok, error?}` after a dispatch or
233
+ > human-appraise completes. Returns `{action, ...}` describing what the
234
+ > caller should do next.
235
+
236
+ **Args:**
237
+ - `lastResult` (object, optional): `{ ok: boolean, error?: string }` — output of the
238
+ prior action.
239
+ - `cycleDef` (string, optional): Test-mode override path to a cycle file.
240
+
241
+ **Returns:** one of:
242
+ - `{ action: "dispatch", stage, cycle, prompt, token, ... }` — caller
243
+ should dispatch a subagent. The `prompt` field is augmented with cycle
244
+ memory context (entity types, edge types, extractor briefs) when configured.
245
+ - `{ action: "human_appraise", ... }` — surface to the user.
246
+ - `{ action: "done", ... }` — cycle complete.
247
+ - `{ action: "blocked", ... }` — cycle stalled.
248
+ - `{ action: "violation", details, recoverable, affected_files }` —
249
+ policy violation; `recoverable:false` if `runOrchestrate` threw.
250
+
251
+ **Stage requirements:** none (drives the lifecycle itself). Refuses on
252
+ failed flow.
253
+
254
+ **Failure modes:**
255
+ - Flow is failed → `foundry_orchestrate: <reason>`.
256
+ - `runOrchestrate` throws → returns a `violation` action carrying the
257
+ message.
258
+
259
+ **Side effects:** mints/persists dispatch tokens (in-memory pending
260
+ store); commits via `commitWithPolicy` when finalising stages (refuses
261
+ on unexpected files); appends WORK.md artefact rows when finalising.
262
+
263
+ ### `foundry_workfile_create`
264
+
265
+ > Create `WORK.md` with frontmatter and goal.
266
+
267
+ **Args:**
268
+ - `flow` (string, required).
269
+ - `cycle` (string, required).
270
+ - `goal` (string, required): Goal text.
271
+ - `stages` (string[], optional): Ordered stage names; enriched with cycle
272
+ qualifiers.
273
+ - `maxIterations` (number, optional).
274
+ - `models` (string, optional): JSON-encoded per-stage model overrides,
275
+ e.g. `'{"forge":"openai/gpt-4o"}'`.
276
+
277
+ **Returns:** `{ ok: true }`.
278
+
279
+ **Stage requirements:** requires no active stage. Refuses on failed
280
+ flow.
281
+
282
+ **Failure modes:**
283
+ - `WORK.md` already exists → `... requires no WORK.md; current: exists`.
284
+
285
+ **Side effects:** writes `WORK.md`.
286
+
287
+ ### `foundry_workfile_get`
288
+
289
+ > Read `WORK.md` and return frontmatter + goal.
290
+
291
+ **Args:** none.
292
+
293
+ **Returns:** `{ ...frontmatter, goal }`. Returns `{ error: "WORK.md not
294
+ found" }` if missing. Note: frontmatter keys like `error` could collide with
295
+ the tool's own error reporting.
296
+
297
+ **Stage requirements:** none. **Always callable, even on a failed flow.**
298
+
299
+ **Side effects:** none.
300
+
301
+ ### `foundry_workfile_delete`
302
+
303
+ > Delete `WORK.md`, `WORK.history.yaml`, and `WORK.feedback.yaml`
304
+ > (requires `confirm:true`).
305
+
306
+ **Args:**
307
+ - `confirm` (boolean, required): Must be `true`.
308
+
309
+ **Returns:** `{ ok: true }`.
310
+
311
+ **Stage requirements:** requires no active stage. **Callable on a failed
312
+ flow** (escape hatch).
313
+
314
+ **Failure modes:**
315
+ - `confirm !== true` → `foundry_workfile_delete requires {confirm: true}`.
316
+ - Active stage exists → `... requires no active stage; current: <stage>`.
317
+
318
+ **Side effects:** deletes the three workfiles if present. **Destructive.**
319
+
320
+ ---
321
+
322
+ ## Artefacts
323
+
324
+ ### `foundry_artefacts_list`
325
+
326
+ > List artefacts from the WORK.md table. Optional `cycle` filter —
327
+ > callers should always pass the current cycle to avoid stale rows.
328
+
329
+ **Args:**
330
+ - `cycle` (string, optional).
331
+
332
+ **Returns:** array of `{file, type, cycle, status, ...}` rows. `{error:
333
+ "WORK.md not found"}` if missing.
334
+
335
+ **Stage requirements:** none.
336
+
337
+ **Side effects:** none.
338
+
339
+ ### `foundry_artefacts_set_status`
340
+
341
+ > Update the status of an artefact in `WORK.md` (`done` | `blocked`
342
+ > only).
343
+
344
+ **Args:**
345
+ - `file` (string, required): Artefact file path.
346
+ - `status` (string, required): New status (`done` | `blocked`).
347
+
348
+ **Returns:** `{ ok: true }`. On invalid input: `{ error: <message> }`.
349
+
350
+ **Stage requirements:** requires no active stage. Refuses on failed
351
+ flow.
352
+
353
+ **Failure modes:**
354
+ - Invalid status, unknown file, malformed table → error from
355
+ `setArtefactStatus`.
356
+
357
+ **Side effects:** rewrites `WORK.md`.
358
+
359
+ ---
360
+
361
+ ## Feedback
362
+
363
+ All feedback tools (except `foundry_feedback_list`) require an active
364
+ stage and refuse on failed flow. The state machine is described in
365
+ [`docs/work-spec.md`](./work-spec.md).
366
+
367
+ ### `foundry_feedback_add`
368
+
369
+ > Add a feedback item to `WORK.feedback.yaml`.
370
+
371
+ **Args:**
372
+ - `file` (string, required): Artefact file path.
373
+ - `text` (string, required): Feedback text.
374
+ - `tag` (string, required): Tag for the feedback item.
375
+
376
+ **Returns:** `{ ok: true, id, deduped }` (where `deduped` is true if an
377
+ existing equivalent item was returned). `{ error: ... }` otherwise.
378
+
379
+ **Stage requirements:** requires active stage. Tag is gated by stage
380
+ base:
381
+ - `forge` → forbidden (forge stages do not add feedback).
382
+ - `quench` → tag must be exactly `validation`.
383
+ - `appraise` → tag must start with `law:`.
384
+ - `human-appraise` → tag must be exactly `human`.
385
+ - `assay` → forbidden. Extractor failures mark the workfile failed and end
386
+ the cycle without filing feedback.
387
+
388
+ **Failure modes:** see above tag gates; `WORK.md` missing or no `cycle`
389
+ in frontmatter.
390
+
391
+ **Side effects:** writes `WORK.feedback.yaml`.
392
+
393
+ ### `foundry_feedback_action`
394
+
395
+ > Mark a feedback item as actioned (forge stages only).
396
+
397
+ **Args:** `id` (string, required) — feedback ULID.
398
+
399
+ **Returns:** `{ ok: true }` or `{ error: ... }`.
400
+
401
+ **Stage requirements:** requires active **forge** stage.
402
+
403
+ **Failure modes:** invalid transition for the item's current state.
404
+
405
+ **Side effects:** mutates `WORK.feedback.yaml`.
406
+
407
+ ### `foundry_feedback_wontfix`
408
+
409
+ > Mark a feedback item as wont-fix with reason (forge stages only).
410
+
411
+ **Args:**
412
+ - `id` (string, required).
413
+ - `reason` (string, required).
414
+
415
+ **Returns:** `{ ok: true }` or `{ error: ... }`.
416
+
417
+ **Stage requirements:** requires active **forge** stage.
418
+
419
+ **Side effects:** mutates `WORK.feedback.yaml`.
420
+
421
+ ### `foundry_feedback_resolve`
422
+
423
+ > Resolve a feedback item (`approved` or `rejected`).
424
+
425
+ **Args:**
426
+ - `id` (string, required).
427
+ - `resolution` (`"approved"` | `"rejected"`, required). The public
428
+ surface uses `approved`; internally this becomes the state machine's
429
+ `resolved`.
430
+ - `reason` (string, optional): Required when `rejected`, or for deadlock
431
+ override.
432
+
433
+ **Returns:** `{ ok: true }` or `{ error: ... }`.
434
+
435
+ **Stage requirements:** requires active **quench**, **appraise**, or
436
+ **human-appraise** stage.
437
+
438
+ **Side effects:** mutates `WORK.feedback.yaml`.
439
+
440
+ ### `foundry_feedback_list`
441
+
442
+ > List feedback items, optionally filtered by `file`.
443
+
444
+ **Args:** `file` (string, optional).
445
+
446
+ **Returns:** array of `{ id, file, tag, text, source, state, depth,
447
+ reason? }`. `{ error: "... WORK.md cycle not found" }` if `WORK.md` is
448
+ missing.
449
+
450
+ **Stage requirements:** none.
451
+
452
+ **Side effects:** none.
453
+
454
+ ---
455
+
456
+ ## History
457
+
458
+ ### `foundry_history_list`
459
+
460
+ > List history entries for a cycle.
461
+
462
+ **Args:** `cycle` (string, required).
463
+
464
+ **Returns:** array of history entries (per `loadHistory`).
465
+
466
+ **Stage requirements:** none.
467
+
468
+ **Side effects:** none.
469
+
470
+ ---
471
+
472
+ ## Config (read-only definition lookups)
473
+
474
+ These tools throw on missing/malformed definitions; the thrown error
475
+ propagates as a tool error without `{error: ...}` wrapping (no try/catch
476
+ in the registration).
477
+
478
+ ### `foundry_config_cycle`
479
+
480
+ > Get a cycle definition from foundry config.
481
+
482
+ **Args:** `cycleId` (string, required).
483
+
484
+ **Returns:** `{ frontmatter, body, ... }` — full parsed cycle definition.
485
+
486
+ ### `foundry_config_artefact_type`
487
+
488
+ > Get an artefact type definition.
489
+
490
+ **Args:** `typeId` (string, required).
491
+
492
+ **Returns:** parsed artefact-type document.
493
+
494
+ ### `foundry_config_laws`
495
+
496
+ > Get laws, optionally filtered by artefact type.
497
+
498
+ **Args:** `typeId` (string, optional).
499
+
500
+ **Returns:** array of law definitions. Without `typeId`, only global
501
+ laws under `foundry/laws/` are returned. With `typeId`, type-specific
502
+ laws from `foundry/artefacts/<typeId>/laws.md` are appended after the
503
+ global set.
504
+
505
+ ### `foundry_config_read_law`
506
+
507
+ > Read a single law by id, returning its full markdown including the
508
+ > validators block.
509
+
510
+ **Args:** `id` (string, required).
511
+
512
+ **Returns:** `{ ok: true, id, markdown, source }` where `source` is
513
+ `"global"` for laws under `foundry/laws/` or `"type:<typeId>"` for
514
+ laws under `foundry/artefacts/<typeId>/laws.md`. Returns
515
+ `{ ok: false, errors: ["Law \"<id>\" not found"] }` when no law of
516
+ that id is registered.
517
+
518
+ **Stage requirements:** none. Read-only; callable on any branch.
519
+
520
+ ### `foundry_config_appraisers`
521
+
522
+ > List all appraisers.
523
+
524
+ **Args:** none.
525
+
526
+ **Returns:** array of appraiser definitions.
527
+
528
+ ### `foundry_config_flow`
529
+
530
+ > Get a flow definition.
531
+
532
+ **Args:** `flowId` (string, required).
533
+
534
+ **Returns:** parsed flow document.
535
+
536
+ ---
537
+
538
+ ## Validation
539
+
540
+ ### `foundry_validate_run`
541
+
542
+ > Run all law-based validators for an artefact type and return their parsed
543
+ > feedback items.
544
+
545
+ **Args:**
546
+ - `typeId` (string, required).
547
+
548
+ **Returns:** `{ ok, validatorsRun, items, errors }`.
549
+
550
+ - `items`: array of `{ lawId, validatorId, file, text, location?, severity? }`.
551
+ Each entry is one parsed JSONL feedback item produced by a validator.
552
+ The quench skill emits one `foundry_feedback_add` call per item, tagged
553
+ `law:<lawId>:<validatorId>`.
554
+ - `errors`: array of `{ lawId, validatorId, type, message }`. `type` is
555
+ `parse` for malformed JSONL or missing required fields, and
556
+ `pattern-mismatch` for items whose `file` falls outside the artefact
557
+ type's `file-patterns`.
558
+ - `ok` is `true` when `errors` is empty. Items themselves do not flip
559
+ `ok` to `false` — they are the expected output of a failing validator.
560
+
561
+ `{ ok: false, error: "..." }` if the type is unknown or has no
562
+ `file-patterns`.
563
+
564
+ **Stage requirements:** none (callable outside any stage; intended to be
565
+ invoked by quench, but not enforced). Refused on a failed flow.
566
+
567
+ **Side effects:** spawns subprocesses via `execSync` in the worktree —
568
+ external commands may have arbitrary side effects, which is why the tool
569
+ is gated on failed flow.
570
+
571
+ ---
572
+
573
+ ## Appraisers
574
+
575
+ ### `foundry_appraisers_select`
576
+
577
+ > Select appraisers for an artefact type.
578
+
579
+ **Args:**
580
+ - `typeId` (string, required).
581
+ - `count` (number, optional).
582
+
583
+ **Returns:** array of selected appraiser objects.
584
+
585
+ **Stage requirements:** none. Callable on flow branches; refused on failed
586
+ flow.
587
+
588
+ **Side effects:** none. This tool is treated as a flow-tier mutation for
589
+ branch and failed-flow guards.
590
+
591
+ ---
592
+
593
+ ## Assay
594
+
595
+ ### `foundry_assay_run`
596
+
597
+ > Run extractors to populate flow memory. Only callable during an active
598
+ > assay stage. Aborts on the first extractor failure; on abort, marks
599
+ > the workfile failed.
600
+
601
+ **Args:**
602
+ - `cycle` (string, required).
603
+ - `extractors` (string[], required): Extractor names, executed in order.
604
+
605
+ **Returns:** the `runAssay` result object. On success: `{ ok: true, perExtractor: [{ name, rowsUpserted, durationMs }, ...] }`. On extractor failure: `{ error, flow_failed: true, aborted: true, failedExtractor, reason, stderr?, perExtractor }`. On post-run memory sync failure: `{ error, flow_failed: true }`.
606
+
607
+ **Stage requirements:** requires active **assay** stage matching
608
+ `cycle`. Refuses on failed flow.
609
+
610
+ **Failure modes:**
611
+ - Extractor exits non-zero, exceeds timeout, emits invalid JSONL → assay
612
+ result has `ok:false` and the workfile is marked failed.
613
+ - Post-run sync to NDJSON fails → workfile marked failed.
614
+
615
+ **Side effects:** spawns extractor subprocesses, mutates Cozo store and
616
+ NDJSON files, may mark `WORK.md` failed.
617
+
618
+ ---
619
+
620
+ ## Git
621
+
622
+ ### `foundry_git_branch`
623
+
624
+ > Create and checkout a branch in one of three namespaces.
625
+
626
+ **Args:**
627
+ - `kind` (string, required): one of `"config"`, `"work"`, `"dry-run"`.
628
+ - `description` (string, required for all kinds): branch description
629
+ suffix.
630
+ - `flowId` (string, required for `kind: "work"` and `kind: "dry-run"`;
631
+ invalid for `kind: "config"`).
632
+
633
+ **Per-kind dispatch:**
634
+
635
+ | `kind` | required args | required starting branch | resulting branch |
636
+ | ---------- | ------------------------------ | ------------------------------ | ----------------------------------------------- |
637
+ | `config` | `description` | not `config/*`, not `work/*` | `config/<desc-slug>` |
638
+ | `work` | `flowId`, `description` | not `config/*`, not `work/*` | `work/<flow-slug>-<desc-slug>` |
639
+ | `dry-run` | `flowId`, `description` | `config/<parent>` | `dry-run/<parent>/<flow-slug>-<desc-slug>` |
640
+
641
+ **Returns:** `{ ok: true, branch }`.
642
+
643
+ **Stage requirements:** requires no active stage. Not gated on failed
644
+ flow — callable while `WORK.md` has `status: failed` so the caller
645
+ can branch away to recover.
646
+
647
+ **Failure modes:**
648
+ - Missing/invalid `kind` → typed error.
649
+ - Wrong starting branch for the requested kind → typed error.
650
+ - `flowId` supplied with `kind: "config"`, or omitted with the other
651
+ kinds → typed error.
652
+ - Active stage exists → `... requires no active stage; current: <stage>`.
653
+ - `git checkout -b` failure (e.g. branch already exists, dirty state)
654
+ returns `{ error: "foundry_git_branch: failed to create branch '<branch>'. <git stderr>" }`.
655
+
656
+ **Side effects:** runs `git checkout -b` in the worktree. For
657
+ `kind: "dry-run"`, also truncates `.foundry/trace/<branch-slug>.jsonl`.
658
+
659
+ ### `foundry_git_finish`
660
+
661
+ > Three-mode dispatch keyed on the current branch prefix. Cleans up,
662
+ > integrates, or snapshots — depending on which namespace the branch
663
+ > belongs to (requires `confirm:true`).
664
+
665
+ **Args:**
666
+ - `message` (string, required): commit / snapshot message.
667
+ - `baseBranch` (string, optional): default `main`. Invalid for
668
+ `dry-run/*/*` (the parent is encoded in the branch name).
669
+ - `confirm` (boolean, optional): must be `true` to perform destructive
670
+ operations; otherwise returns a plan.
671
+
672
+ **Per-mode dispatch:**
673
+
674
+ | current branch | mode | what happens |
675
+ | -------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
676
+ | `work/<x>` | work | commits `WORK.*` cleanup on the work branch, preserves the branch as `archive/work/<x>-<hash>`, squash-merges to `baseBranch`, creates a signed commit whose message embeds the canonical Foundry attestation block. |
677
+ | `config/<x>` | config | squash-merges to `baseBranch`, force-deletes the config branch. No WORK cleanup. |
678
+ | `dry-run/<x>/<y>` | dry-run | writes `.snapshots/<run-id>/{README.md, work/WORK*, diff.patch, trace.jsonl}` on the parent `config/<x>` working tree; force-deletes the dry-run branch. No merge, no commit. |
679
+ | base branch (`main` by default) | noop | `{ ok: true, noop: true, ... }`. |
680
+ | anything else | refused | `{ ok: false, error: "... nothing to finish ..." }`. |
681
+
682
+ **Returns:**
683
+ - Plan (when `confirm` is not true):
684
+ - Work mode: `{ ok: false, error: "... requires {confirm: true}...",
685
+ planned: { workBranch, baseBranch, filesToDelete, action, commitMessage } }`
686
+ where `action` describes the archive-branch, cleanup, squash-merge, and
687
+ attested-commit sequence.
688
+ - Config mode: `{ ok: false, error: "... requires {confirm: true}...",
689
+ planned: { workBranch, baseBranch, filesToDelete, action, commitMessage } }`
690
+ where `action` describes checkout, squash-merge, commit, and branch deletion.
691
+ - Dry-run mode: `{ ok: false, error: "... requires {confirm: true}...",
692
+ planned: { branch, action, snapshotPath } }` where `action` is
693
+ `"snapshot + discard (dry-run finish)"`.
694
+ - Work success: `{ ok: true, hash, branch, archiveBranch,
695
+ archiveTipSha }` — `hash` is the final squash commit on the base
696
+ branch, `archiveBranch` is `archive/work/<x>-<short-hash>`,
697
+ `archiveTipSha` is the tip of the preserved work branch.
698
+ - Config success: `{ ok: true, hash, branch }`.
699
+ - Dry-run success: `{ ok: true, runId, snapshotPath, branch }`.
700
+ - Dirty worktree (work / config): `{ ok: false, error, dirty: [...] }`.
701
+ - Conflict (work / config): `{ ok: false, error: "... squash merge
702
+ failed ..." }`. Worktree reset and checked back out to the source
703
+ branch.
704
+ - Refused (not on expected branch): `{ ok: false, error: "... nothing
705
+ to finish ..." }`.
706
+
707
+ **Stage requirements:** requires no active stage. Not gated on failed
708
+ flow — callable while `WORK.md` has `status: failed`, including the
709
+ `work` mode whose cleanup deletes the failed `WORK.md` outright.
710
+
711
+ **Side effects (when confirmed):** see per-mode dispatch above.
712
+ **Destructive in all three modes.**
713
+
714
+ ---
715
+
716
+ ## Attestation
717
+
718
+ ### `foundry_attestation_show`
719
+
720
+ > Show the parsed Foundry attestation block for a git ref.
721
+
722
+ **Args:**
723
+ - `ref` (string, optional): Git ref, default `HEAD`.
724
+
725
+ **Returns:** `{ ok: true, human_summary, payload }` where `human_summary`
726
+ is the commit subject line and `payload` is the parsed JSON attestation
727
+ object. `{ error: ... }` when no attestation block is found.
728
+
729
+ **Stage requirements:** none. Callable on any branch.
730
+
731
+ **Failure modes:**
732
+ - Commit message has no attestation block → `{ error: "attestation
733
+ block not found" }`.
734
+ - Invalid JSON in attestation block → parse error.
735
+
736
+ **Side effects:** none (read-only).
737
+
738
+ ### `foundry_attestation_verify`
739
+
740
+ > Verify the signed Foundry attestation block on a git ref.
741
+
742
+ **Args:**
743
+ - `ref` (string, optional): Git ref, default `HEAD`.
744
+
745
+ **Returns:** `{ ok: true, status: "verified", schema, payload }` on
746
+ success. `{ error: ... }` when verification fails.
747
+
748
+ **Stage requirements:** none. Callable on any branch.
749
+
750
+ **Failure modes:**
751
+ - `git verify-commit` fails (commit not signed or signature invalid) →
752
+ returns git error.
753
+ - Commit message has no attestation block → `{ error: "attestation
754
+ block not found" }`.
755
+ - Invalid JSON in attestation block → parse error.
756
+
757
+ **Side effects:** none (read-only).
758
+
759
+ ### `foundry_attest`
760
+
761
+ > Verify the current work cycle is complete (all required stages ran, no unresolved feedback, no blocked artefacts) and commit a signed ATTEST.md to the work branch. foundry_git_finish will not merge without this commit at HEAD.
762
+
763
+ **Args:**
764
+ - `baseBranch` (string, optional): Branch to compute diff from (default: `main`).
765
+ - `message` (string, required): Goal text / human summary for the attestation.
766
+ - `confirm` (boolean, optional): Must be `true` to write and commit ATTEST.md.
767
+
768
+ **Returns:**
769
+ - Plan (when `confirm` is not true): `{ ok: false, error: "foundry_attest requires {confirm: true}. Re-invoke with confirm:true to write ATTEST.md.", planned: { action, branch, baseBranch } }`.
770
+ - Success: `{ ok: true, diffSha, commitSha }` where `diffSha` is the SHA-256 hash of the diff from base branch and `commitSha` is the short SHA of the attestation commit.
771
+ - Failure: `{ ok: false, error: ... }` describing the issue (cycle incomplete, validation errors, commit failure).
772
+
773
+ **Stage requirements:** requires no active stage. Must be on a `work/*` branch.
774
+
775
+ **Failure modes:**
776
+ - Active stage exists → `foundry_attest: requires no active stage; current: <stage>`.
777
+ - Not on a `work/*` branch → `foundry_attest: must be run on a work/* branch, current branch is '<branch>'`.
778
+ - Cycle verification fails (unresolved feedback, blocked artefacts, etc.) → `{ ok: false, error: ... }`.
779
+ - Git commit fails → `foundry_attest: commit failed. <stderr>`.
780
+
781
+ **Side effects (when confirmed):** writes `ATTEST.md` to the work branch, commits it with message `[<cycle>] attest: cycle complete`.
782
+
783
+ ---
784
+
785
+ ## Config — Schema mutation
786
+
787
+ These tools each write one named config artefact and produce a single
788
+ git commit on the current `config/*` branch. All of them refuse off
789
+ `config/*` and refuse on failed flow. The `_create_*` tools are paired
790
+ with read-only `_validate_*` forms (next section) that run the same
791
+ schema checks without writing. Laws use a different shape: `add_law`
792
+ creates a new entry, `edit_law` updates an existing one, and
793
+ `foundry_config_validate_law` covers schema validation for either.
794
+
795
+ Common args across the `_create_*` tools: `name` (string), `body`
796
+ (string, markdown). Common returns across the whole family:
797
+ `{ ok: true, path, sha }` on success; `{ ok: false, errors: [...] }`
798
+ on validation failure; `{ error, affected_files: [...] }` on
799
+ commit-policy refusal (the worktree was dirty with files outside
800
+ `foundry/**`). For the `_create_*` tools, updating an existing file is
801
+ not exposed as an MCP tool — operators edit by hand on the current
802
+ `config/*` branch. Laws are the exception: use `foundry_config_edit_law`
803
+ to update an existing law in place.
804
+
805
+ ### `foundry_config_create_artefact_type`
806
+
807
+ > Create a new artefact-type definition under
808
+ > `foundry/artefacts/<typeId>/`.
809
+
810
+ **Args:**
811
+ - `name` (string, required): typeId (kebab-case slug).
812
+ - `body` (string, required): markdown body with frontmatter
813
+ (`file-patterns`, optional `description`, etc.).
814
+
815
+ **Returns:** `{ ok: true, path, sha }` on success;
816
+ `{ ok: false, errors: [...] }` on schema failure;
817
+ `{ error, affected_files }` on commit-policy refusal.
818
+
819
+ **Stage requirements:** none (no active stage); requires a
820
+ `config/*` branch.
821
+
822
+ **Failure modes:**
823
+ - Off `config/*` branch → branch-guard refusal envelope.
824
+ - Failed flow → tool-name-prefixed error.
825
+ - Body fails artefact-type schema (missing `file-patterns`, glob
826
+ overlap with an existing type, …) → `{ ok: false, errors: [...] }`.
827
+ - Target file already exists → `{ ok: false, errors: ["… already
828
+ exists; this tool only creates new files — to update, edit by hand
829
+ on this config/* branch"] }`.
830
+ - Worktree has changes outside `foundry/**` →
831
+ `{ error, affected_files }`.
832
+
833
+ **Side effects:** writes the artefact-type file and commits it on the
834
+ current `config/*` branch.
835
+
836
+ ### `foundry_config_add_law`
837
+
838
+ > Add a new law markdown entry. Locator depends on `target.kind`.
839
+
840
+ **Args:**
841
+ - `name` (string, required): law id (kebab-case slug). Used in the
842
+ commit message.
843
+ - `body` (string, required): markdown body for the law, starting with
844
+ a `## <law-id>` heading.
845
+ - `target` (object, required):
846
+ - `{ kind: "global", file: "<name>.md" }` — appends or writes
847
+ `foundry/laws/<file>`.
848
+ - `{ kind: "type-specific", typeId: "<id>" }` — appends or writes
849
+ `foundry/artefacts/<typeId>/laws.md`.
850
+
851
+ **Returns / Stage requirements / Side effects:** as for
852
+ `foundry_config_create_artefact_type`.
853
+
854
+ **Failure modes:** as for `foundry_config_create_artefact_type`, plus
855
+ `target` shape errors:
856
+ - Missing or non-object `target` → `{ ok: false, errors: ["target
857
+ argument is required (object with kind + locator)"] }`.
858
+ - Unknown `target.kind` → `{ ok: false, errors: ["unknown
859
+ target.kind: <kind>"] }`.
860
+ - Missing `target.file` for `global` / missing `target.typeId` for
861
+ `type-specific` → `{ ok: false, errors: [...] }`.
862
+ - Target file already exists →
863
+ `{ ok: false, errors: ["… already exists; use foundry_config_edit_law
864
+ to update an existing law in place"] }`.
865
+
866
+ ### `foundry_config_edit_law`
867
+
868
+ > Replace the body of an existing law in place, preserving sibling
869
+ > laws in the same file. Locates the law by id across both global laws
870
+ > and per-type `laws.md` files.
871
+
872
+ **Args:**
873
+ - `id` (string, required): law id to edit.
874
+ - `body` (string, required): full new markdown body for the law,
875
+ starting with a `## <law-id>` heading.
876
+
877
+ **Returns:** `{ ok: true, id, path, source }` on success, where
878
+ `source` is `"global"` or `"type:<typeId>"`. Returns
879
+ `{ ok: false, errors: ["Law \"<id>\" not found"] }` when no law of
880
+ that id exists, or `{ ok: false, errors: [...] }` when the new body
881
+ fails law schema validation.
882
+
883
+ **Stage requirements:** none (no active stage); requires a `config/*`
884
+ branch and a non-failed flow.
885
+
886
+ **Side effects:** rewrites the containing laws file and commits it on
887
+ the current `config/*` branch with message `config: edit law <id>`.
888
+
889
+ ### `foundry_config_create_appraiser`
890
+
891
+ > Create a new appraiser personality at `foundry/appraisers/<id>.md`.
892
+
893
+ **Args:**
894
+ - `name` (string, required): appraiser id.
895
+ - `body` (string, required): markdown body with frontmatter
896
+ (`description`, optional `model`, …).
897
+
898
+ **Returns / Stage requirements / Side effects:** as for
899
+ `foundry_config_create_artefact_type`.
900
+
901
+ **Failure modes:** as for `foundry_config_create_artefact_type`,
902
+ applied to the appraiser schema (missing description, semantic overlap
903
+ with an existing appraiser, …).
904
+
905
+ ### `foundry_config_create_flow`
906
+
907
+ > Create a new flow definition under `foundry/flows/<flowId>/`.
908
+
909
+ **Args:**
910
+ - `name` (string, required): flowId (kebab-case slug).
911
+ - `body` (string, required): markdown body with frontmatter
912
+ (`description`, `cycles: [...]`).
913
+
914
+ **Returns / Stage requirements / Side effects:** as for
915
+ `foundry_config_create_artefact_type`.
916
+
917
+ **Failure modes:** as for `foundry_config_create_artefact_type`,
918
+ applied to the flow schema.
919
+
920
+ ### `foundry_config_create_cycle`
921
+
922
+ > Create a new cycle markdown file under `foundry/cycles/<cycleId>.md`.
923
+
924
+ **Args:**
925
+ - `name` (string, required): cycleId (kebab-case slug).
926
+ - `body` (string, required): markdown body with frontmatter
927
+ (`flowId`, `output`, optional `inputs`, `memory`, `models`, …).
928
+
929
+ **Returns / Stage requirements / Side effects:** as for
930
+ `foundry_config_create_artefact_type`.
931
+
932
+ **Failure modes:** as for `foundry_config_create_artefact_type`,
933
+ applied to the cycle schema (unknown `output` artefact-type, unknown
934
+ `memory.read` / `memory.write` types, unknown referenced appraisers,
935
+ …).
936
+
937
+ ---
938
+
939
+ ## Config — Schema validation
940
+
941
+ These five tools run the same schema checks as their `_create_*`
942
+ peers but write nothing and produce no commit. They have no branch
943
+ guard and do not refuse on failed flow — authors can iterate on a
944
+ draft body from any branch.
945
+
946
+ Common args: `name` (string), `body` (string).
947
+ `foundry_config_validate_law` does NOT require a `target` — schema
948
+ validation is target-agnostic.
949
+ Common returns: `{ ok: true }` on a valid body;
950
+ `{ ok: false, errors: [...] }` otherwise.
951
+
952
+ ### `foundry_config_validate_artefact_type`
953
+
954
+ > Validate a candidate artefact-type body. Writes nothing.
955
+
956
+ **Args:** `name`, `body`.
957
+
958
+ **Returns:** `{ ok: true }` or `{ ok: false, errors: [...] }`.
959
+
960
+ **Stage requirements:** none. Callable on any branch.
961
+
962
+ **Failure modes:** schema validation only; never raises.
963
+
964
+ ### `foundry_config_validate_law`
965
+
966
+ > Validate a candidate law body. Writes nothing.
967
+
968
+ **Args:** `name`, `body`. (No `target` — schema-only.)
969
+
970
+ **Returns / Stage requirements / Failure modes:** as for
971
+ `foundry_config_validate_artefact_type`.
972
+
973
+ ### `foundry_config_validate_appraiser`
974
+
975
+ > Validate a candidate appraiser body. Writes nothing.
976
+
977
+ **Args / Returns / Stage requirements / Failure modes:** as for
978
+ `foundry_config_validate_artefact_type`, applied to the appraiser
979
+ schema.
980
+
981
+ ### `foundry_config_validate_flow`
982
+
983
+ > Validate a candidate flow body. Writes nothing.
984
+
985
+ **Args / Returns / Stage requirements / Failure modes:** as for
986
+ `foundry_config_validate_artefact_type`, applied to the flow schema.
987
+
988
+ ### `foundry_config_validate_cycle`
989
+
990
+ > Validate a candidate cycle body. Writes nothing.
991
+
992
+ **Args / Returns / Stage requirements / Failure modes:** as for
993
+ `foundry_config_validate_artefact_type`, applied to the cycle schema
994
+ (memory permissions, target validity, appraiser references).
995
+
996
+ ---
997
+
998
+ ## Snapshots
999
+
1000
+ Forensic artefacts of dry-run finishes. Stored under `.snapshots/`
1001
+ (gitignored). All four tools are foundational and callable on every
1002
+ branch — they carry only `gitRepo` and `foundryRoot` guards.
1003
+
1004
+ ### `foundry_snapshot_list`
1005
+
1006
+ > List all snapshots under `.snapshots/`, sorted by `startedAt`
1007
+ > descending.
1008
+
1009
+ **Args:** none.
1010
+
1011
+ **Returns:** an array of metadata objects, one per snapshot:
1012
+ `[{ runId, branch, parent, flow, goal, startedAt, finishedAt,
1013
+ exitReason }]`. Incomplete snapshots include `error: "incomplete"`
1014
+ and a `missing: [...]` array. Returns `[]` if `.snapshots/` does not
1015
+ exist.
1016
+
1017
+ **Stage requirements:** none. Callable on any branch.
1018
+
1019
+ **Failure modes:** none under normal operation.
1020
+
1021
+ **Side effects:** none (read-only).
1022
+
1023
+ ### `foundry_snapshot_show`
1024
+
1025
+ > Read a structured summary of one snapshot: README metadata, diff
1026
+ > stats, trace stats.
1027
+
1028
+ **Args:**
1029
+ - `runId` (string, required): the snapshot's run id (typically a
1030
+ ULID; matches the directory name under `.snapshots/`).
1031
+
1032
+ **Returns:** `{ runId, readme, metadata, diff, trace, missing }` —
1033
+ - `readme`: raw README.md text (or `null` if missing).
1034
+ - `metadata`: `{ branch, parent, flow, goal, startedAt, finishedAt,
1035
+ exitReason }` parsed from the README frontmatter.
1036
+ - `diff`: `{ files, insertions, deletions }` summarising
1037
+ `diff.patch`.
1038
+ - `trace`: `{ lineCount, firstTs, lastTs }` summarising
1039
+ `trace.jsonl`.
1040
+ - `missing`: array of any of `["README.md", "work/WORK.md",
1041
+ "diff.patch", "trace.jsonl"]` that are absent.
1042
+
1043
+ When `runId` does not exist, returns
1044
+ `{ runId, error: "unknown_runId", missing: [...all four files] }`.
1045
+
1046
+ **Stage requirements:** none. Callable on any branch.
1047
+
1048
+ **Failure modes:** unknown runId returns the error envelope above.
1049
+
1050
+ **Side effects:** none (read-only).
1051
+
1052
+ ### `foundry_snapshot_delete`
1053
+
1054
+ > Delete one snapshot directory. Requires `confirm: true`.
1055
+
1056
+ **Args:**
1057
+ - `runId` (string, required).
1058
+ - `confirm` (boolean, optional): must be `true` to actually delete.
1059
+
1060
+ **Returns:**
1061
+ - Plan (when `confirm` is not true):
1062
+ `{ ok: false, error: "foundry_snapshot_delete requires {confirm:
1063
+ true}", planned: { runId, path } }`.
1064
+ - Success: `{ ok: true, runId, removed: ".snapshots/<runId>" }`.
1065
+ - Unknown runId: `{ ok: false, error: "unknown runId '<id>'" }`.
1066
+
1067
+ **Stage requirements:** none. Callable on any branch.
1068
+
1069
+ **Failure modes:** unknown runId returns the error envelope above.
1070
+
1071
+ **Side effects (when confirmed):** removes the
1072
+ `.snapshots/<runId>/` directory recursively.
1073
+
1074
+ ### `foundry_snapshot_prune`
1075
+
1076
+ > Bulk-delete snapshots whose runId ULID is older than
1077
+ > `olderThanDays`. Requires `confirm: true`.
1078
+
1079
+ **Args:**
1080
+ - `olderThanDays` (number, required): positive integer; days
1081
+ threshold.
1082
+ - `confirm` (boolean, optional): must be `true` to actually delete.
1083
+
1084
+ **Returns:**
1085
+ - Plan (when `confirm` is not true):
1086
+ `{ ok: false, error: "foundry_snapshot_prune requires {confirm:
1087
+ true}", candidates: [...runIds...], cutoff }`.
1088
+ - Success: `{ ok: true, removed: [...runIds...] }`.
1089
+ - Bad input: `{ ok: false, error: "olderThanDays must be a positive
1090
+ integer" }`.
1091
+
1092
+ **Stage requirements:** none. Callable on any branch.
1093
+
1094
+ **Failure modes:** non-integer or non-positive `olderThanDays` is
1095
+ rejected. Snapshots whose runId does not end in a valid 26-char ULID
1096
+ are silently skipped (treated as untouchable).
1097
+
1098
+ **Side effects (when confirmed):** removes each candidate
1099
+ `.snapshots/<runId>/` directory recursively.
1100
+
1101
+ ---
1102
+
1103
+ ## Memory — Data
1104
+
1105
+ All memory data tools share these traits unless noted:
1106
+ - Resolve permissions from the active cycle's frontmatter via
1107
+ `withStore`. Reads of disallowed entity/edge types return empty
1108
+ results; writes return an `error` string.
1109
+ - Refuse on failed flow (write tools only).
1110
+ - Writes that occur outside an active cycle stage are immediately synced
1111
+ to NDJSON; in-cycle writes are deferred until `foundry_stage_end`.
1112
+ - Embedding-aware tools (`put`, `search`) are no-ops or errors when
1113
+ embeddings are disabled in `foundry/memory/config.md`.
1114
+
1115
+ ### `foundry_memory_put`
1116
+
1117
+ > Upsert an entity into flow memory. Value must be ≤4KB.
1118
+
1119
+ **Args:**
1120
+ - `type` (string, required): Entity type (must be declared).
1121
+ - `name` (string, required): Entity name (unique within type).
1122
+ - `value` (string, required): Free-text intrinsic description (≤4KB).
1123
+
1124
+ **Returns:** `{ ok: true }` or `{ error: ... }`.
1125
+
1126
+ **Failure modes:** failed flow; cycle lacks write permission for the
1127
+ type; value too large; type not declared.
1128
+
1129
+ **Side effects:** mutates Cozo store; embeds the value if a write
1130
+ embedder is available; conditionally syncs NDJSON.
1131
+
1132
+ ### `foundry_memory_relate`
1133
+
1134
+ > Upsert an edge between two entities.
1135
+
1136
+ **Args:** `from_type`, `from_name`, `edge_type`, `to_type`, `to_name`
1137
+ (all string, required).
1138
+
1139
+ **Returns:** `{ ok: true }` or `{ error: ... }`.
1140
+
1141
+ **Failure modes:** failed flow; no write permission on `edge_type`; edge
1142
+ endpoints do not match the edge type's source/target rules.
1143
+
1144
+ **Side effects:** mutates Cozo store; conditionally syncs NDJSON.
1145
+
1146
+ ### `foundry_memory_unrelate`
1147
+
1148
+ > Delete an edge between two entities.
1149
+
1150
+ **Args:** same shape as `foundry_memory_relate`.
1151
+
1152
+ **Returns:** `{ ok: true }` or `{ error: ... }`.
1153
+
1154
+ **Failure modes:** failed flow; no write permission on `edge_type`.
1155
+
1156
+ **Side effects:** mutates Cozo store; conditionally syncs NDJSON.
1157
+
1158
+ ### `foundry_memory_get`
1159
+
1160
+ > Fetch a single entity by composite key (`type`, `name`).
1161
+
1162
+ **Args:** `type`, `name` (string, required).
1163
+
1164
+ **Returns:** the entity object, or `null` (also returned when the type
1165
+ is read-disallowed).
1166
+
1167
+ **Side effects:** none.
1168
+
1169
+ ### `foundry_memory_list`
1170
+
1171
+ > List all entities of a given type.
1172
+
1173
+ **Args:** `type` (string, required).
1174
+
1175
+ **Returns:** array of entities. Empty array if the type is
1176
+ read-disallowed.
1177
+
1178
+ **Side effects:** none.
1179
+
1180
+ ### `foundry_memory_neighbours`
1181
+
1182
+ > Bounded graph traversal from an entity. Returns entities and edges
1183
+ > within `depth` hops.
1184
+
1185
+ **Args:**
1186
+ - `type`, `name` (string, required).
1187
+ - `depth` (number, optional, default 1).
1188
+ - `edge_types` (string[], optional): Restrict traversal to named edges;
1189
+ defaults to all known edges.
1190
+
1191
+ **Returns:** `{ entities, edges }`. Both arrays are post-filtered against
1192
+ read permissions.
1193
+
1194
+ **Side effects:** none.
1195
+
1196
+ ### `foundry_memory_query`
1197
+
1198
+ > Arbitrary read-only Cozo Datalog query. Rejects `:put`, `:rm`,
1199
+ > `:create`, `::remove`. Returns `{headers, rows}`.
1200
+
1201
+ **Args:** `datalog` (string, required).
1202
+
1203
+ **Returns:** `{ headers, rows }` or `{ error: ... }`.
1204
+
1205
+ **Failure modes:** query references an `ent_*` or `edge_*` relation the
1206
+ cycle cannot read; query contains a forbidden keyword.
1207
+
1208
+ **Side effects:** none.
1209
+
1210
+ ### `foundry_memory_search`
1211
+
1212
+ > Semantic nearest-neighbour search over entity values. Requires
1213
+ > embeddings enabled.
1214
+
1215
+ **Args:**
1216
+ - `query_text` (string, required).
1217
+ - `k` (number, optional, default 5).
1218
+ - `type_filter` (string[], optional): default = all readable entity
1219
+ types.
1220
+
1221
+ **Returns:** array of search results (entity + similarity score). Errors
1222
+ with `embeddings are disabled in memory config` if no embedder.
1223
+
1224
+ **Side effects:** issues an embedding API call.
1225
+
1226
+ ---
1227
+
1228
+ ## Memory — Admin
1229
+
1230
+ These tools manage the memory schema, on-disk layout, and bulk
1231
+ operations. They use the worktree-scoped memory IO and (where
1232
+ applicable) the singleton store. None of them check active-stage
1233
+ state; they are intended to run as project-level admin actions.
1234
+
1235
+ ### `foundry_memory_init`
1236
+
1237
+ > Scaffold `foundry/memory/` plus top-level `foundry-memory/relations/`:
1238
+ > creates `entities/` and `edges/` dirs under `foundry/memory/`, creates
1239
+ > `relations/` under top-level `foundry-memory/`, writes `config.md` and
1240
+ > `schema.json`, appends `.gitignore` entries, and optionally probes the
1241
+ > embedding provider. Fails if `foundry/memory/` or `foundry-memory/`
1242
+ > already exists.
1243
+
1244
+ **Args:**
1245
+ - `embeddings_enabled` (boolean, optional, default `true`).
1246
+ - `probe` (boolean, optional, default `true`).
1247
+
1248
+ **Returns:** init report from `admInitMemory` or `{ error: ... }`.
1249
+
1250
+ **Side effects:** creates files and directories under `foundry/memory/`
1251
+ and `foundry-memory/`; mutates `.gitignore`.
1252
+
1253
+ ### `foundry_memory_validate`
1254
+
1255
+ > Run load-time and drift checks; returns a report.
1256
+
1257
+ **Args:** none.
1258
+
1259
+ **Returns:** validation report.
1260
+
1261
+ **Side effects:** none.
1262
+
1263
+ ### `foundry_memory_dump`
1264
+
1265
+ > Human-readable snapshot of memory. Optional `type` + `name`.
1266
+
1267
+ **Args:** `type` (optional), `name` (optional), `depth` (optional).
1268
+
1269
+ **Returns:** JSON `{ dump }` where `dump` is the rendered human-readable
1270
+ report string. On error, JSON `{error}`.
1271
+
1272
+ **Side effects:** none.
1273
+
1274
+ ### `foundry_memory_vacuum`
1275
+
1276
+ > Compact the Cozo database.
1277
+
1278
+ **Args:** none.
1279
+
1280
+ **Returns:** vacuum report.
1281
+
1282
+ **Side effects:** rewrites the underlying Cozo storage.
1283
+
1284
+ ### `foundry_memory_reset`
1285
+
1286
+ > Destructive. Purge all memory data (keeps type definitions). Requires
1287
+ > `confirm: true`.
1288
+
1289
+ **Args:** `confirm` (boolean, required).
1290
+
1291
+ **Returns:** reset report or `{ error: ... }`.
1292
+
1293
+ **Side effects:** wipes all entity/edge rows from Cozo and NDJSON files.
1294
+ **Destructive.**
1295
+
1296
+ ### `foundry_memory_change_embedding_model`
1297
+
1298
+ > Swap the embedding model and re-embed all existing entities.
1299
+
1300
+ **Args:**
1301
+ - `model` (string, required).
1302
+ - `dimensions` (number, required).
1303
+ - `baseURL` (string, optional).
1304
+ - `apiKey` (string, optional).
1305
+
1306
+ **Returns:** reembed report or `{ error: ... }`.
1307
+
1308
+ **Failure modes:** probe fails; provider returns vectors whose
1309
+ dimensionality mismatches `dimensions`.
1310
+
1311
+ **Side effects:** re-embeds every entity (issues many embedding API
1312
+ calls); rewrites `foundry/memory/config.md`; updates schema.
1313
+
1314
+ ### `foundry_memory_create_entity_type`
1315
+
1316
+ > Create a new entity type with a prose body brief.
1317
+
1318
+ **Args:** `name` (string, required), `body` (string, required).
1319
+
1320
+ **Returns:** create report or `{ error: ... }`.
1321
+
1322
+ **Side effects:** writes a new entity-type file and updates schema.
1323
+
1324
+ ### `foundry_memory_create_edge_type`
1325
+
1326
+ > Create a new edge type.
1327
+
1328
+ **Args:**
1329
+ - `name` (string, required).
1330
+ - `sources` (`"any"` | string[], required).
1331
+ - `targets` (`"any"` | string[], required).
1332
+ - `body` (string, required).
1333
+
1334
+ **Returns:** create report or `{ error: ... }`.
1335
+
1336
+ **Side effects:** writes a new edge-type file and updates schema.
1337
+
1338
+ ### `foundry_memory_rename_entity_type`
1339
+
1340
+ > Rename an entity type and cascade updates to edges and rows.
1341
+
1342
+ **Args:** `from`, `to` (string, required).
1343
+
1344
+ **Returns:** rename report or `{ error: ... }`.
1345
+
1346
+ **Side effects:** rewrites schema, NDJSON, edge-type references.
1347
+
1348
+ ### `foundry_memory_rename_edge_type`
1349
+
1350
+ > Rename an edge type. (Does not touch row data.)
1351
+
1352
+ **Args:** `from`, `to` (string, required).
1353
+
1354
+ **Returns:** rename report or `{ error: ... }`.
1355
+
1356
+ **Side effects:** rewrites schema and edge metadata only.
1357
+
1358
+ ### `foundry_memory_drop_entity_type`
1359
+
1360
+ > Destructive. Delete an entity type and cascade to affected edges.
1361
+ > Without `confirm`, returns a preview of what would be deleted.
1362
+
1363
+ **Args:**
1364
+ - `name` (string, required).
1365
+ - `confirm` (boolean, optional). Must be `true` to actually drop.
1366
+
1367
+ **Returns:** preview report or drop report; `{ error: ... }` on
1368
+ failure.
1369
+
1370
+ **Side effects (confirm:true only):** removes the entity-type file,
1371
+ purges rows, drops dependent edges. **Destructive.**
1372
+
1373
+ ### `foundry_memory_drop_edge_type`
1374
+
1375
+ > Destructive. Delete an edge type. Without `confirm`, returns a row
1376
+ > count preview.
1377
+
1378
+ **Args:**
1379
+ - `name` (string, required).
1380
+ - `confirm` (boolean, optional).
1381
+
1382
+ **Returns:** preview or drop report; `{ error: ... }` on failure.
1383
+
1384
+ **Side effects (confirm:true only):** removes the edge-type file and
1385
+ its rows. **Destructive.**
1386
+
1387
+ ### `foundry_extractor_create`
1388
+
1389
+ > Create a new extractor definition under
1390
+ > `foundry/memory/extractors/`.
1391
+
1392
+ **Args:**
1393
+ - `name` (string, required).
1394
+ - `command` (string, required): The CLI to execute.
1395
+ - `memoryWrite` (string[], required): Entity types the extractor is allowed to write. Edge rows are permitted when either endpoint entity type is in this list.
1396
+ - `body` (string, required): Prose brief for the LLM.
1397
+ - `timeout` (string, optional).
1398
+
1399
+ **Returns:** create report or `{ error: ... }`.
1400
+
1401
+ **Side effects:** writes a new extractor markdown file under
1402
+ `foundry/memory/extractors/`.
1403
+
1404
+ ---
1405
+
1406
+ ## Design exceptions
1407
+
1408
+ 1. **`foundry_orchestrate` returns `violation` instead of `{error}`
1409
+ when `runOrchestrate` throws.** Intentional: the `violation`
1410
+ action signals an unrecoverable orchestrator state to the caller's
1411
+ loop. Every other tool uses `{error}` for failure envelopes.