geneseed 3.12.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +2 -2
  3. package/SHIPPED.md +1 -1
  4. package/adapters/bob/README.md +1 -1
  5. package/adapters/claude-code/README.md +1 -1
  6. package/adapters/openclaude/README.md +1 -1
  7. package/adapters/opencode/README.md +3 -3
  8. package/docs/README.md +41 -22
  9. package/docs/concepts/agents.md +3 -1
  10. package/docs/concepts/collaboration.md +3 -1
  11. package/docs/concepts/exclusions.md +4 -2
  12. package/docs/concepts/footprint.md +3 -1
  13. package/docs/concepts/foreman-mode.md +3 -1
  14. package/docs/concepts/hook-gates.md +61 -0
  15. package/docs/concepts/hooks.md +8 -56
  16. package/docs/concepts/host-matrix.md +38 -0
  17. package/docs/concepts/hosts.md +6 -32
  18. package/docs/concepts/loop-branch.md +66 -0
  19. package/docs/concepts/loop-bricks.md +48 -0
  20. package/docs/concepts/loop-contracts.md +33 -0
  21. package/docs/concepts/loop-gates.md +30 -0
  22. package/docs/concepts/loop-notes.md +43 -0
  23. package/docs/concepts/loop-risk.md +36 -0
  24. package/docs/concepts/loop-templates.md +50 -0
  25. package/docs/concepts/loops.md +24 -116
  26. package/docs/concepts/lsp.md +2 -0
  27. package/docs/concepts/memory.md +3 -1
  28. package/docs/concepts/notebook.md +3 -1
  29. package/docs/concepts/rules.md +4 -2
  30. package/docs/concepts/skills.md +3 -1
  31. package/docs/concepts/themes.md +3 -1
  32. package/docs/extending.md +23 -8
  33. package/docs/guides/autostart.md +3 -1
  34. package/docs/guides/choose-your-setup.md +5 -80
  35. package/docs/guides/headless.md +5 -3
  36. package/docs/guides/install-agent-md.md +37 -0
  37. package/docs/guides/install-bob.md +20 -0
  38. package/docs/guides/install-claude-code.md +22 -0
  39. package/docs/guides/install-clone.md +34 -0
  40. package/docs/guides/install-openclaude.md +25 -0
  41. package/docs/guides/install-opencode.md +35 -0
  42. package/docs/guides/install-scripted.md +21 -0
  43. package/docs/guides/install.md +9 -118
  44. package/docs/guides/loop-finish.md +54 -0
  45. package/docs/guides/loop-running.md +66 -0
  46. package/docs/guides/loop-which-template.md +35 -0
  47. package/docs/guides/mcp-filesystem.md +41 -0
  48. package/docs/guides/mcp-gitlab.md +66 -0
  49. package/docs/guides/mcp-markitdown.md +36 -0
  50. package/docs/guides/mcp.md +8 -137
  51. package/docs/guides/migrate.md +3 -1
  52. package/docs/guides/project-context.md +4 -2
  53. package/docs/guides/read-non-markdown.md +17 -0
  54. package/docs/guides/run-a-loop.md +64 -0
  55. package/docs/guides/run-anywhere.md +2 -0
  56. package/docs/guides/setup-doctrines.md +55 -0
  57. package/docs/guides/setup-footprint.md +48 -0
  58. package/docs/guides/uninstall.md +3 -1
  59. package/docs/guides/upgrade.md +3 -1
  60. package/docs/guides/verify.md +3 -1
  61. package/docs/guides/wiki.md +3 -1
  62. package/docs/guides/worktree.md +3 -1
  63. package/docs/reference/about.md +3 -1
  64. package/docs/reference/cli.md +2 -0
  65. package/docs/reference/env-context.md +40 -0
  66. package/docs/reference/environment.md +10 -59
  67. package/docs/reference/glossary.md +3 -1
  68. package/docs/reference/loop-actions.md +20 -0
  69. package/docs/reference/opencode-plugins.md +14 -118
  70. package/docs/reference/plugin-activity.md +20 -0
  71. package/docs/reference/plugin-context.md +27 -0
  72. package/docs/reference/plugin-guard.md +27 -0
  73. package/docs/reference/plugin-learn.md +27 -0
  74. package/docs/reference/plugin-notify.md +20 -0
  75. package/docs/reference/plugin-ponytail.md +19 -0
  76. package/docs/reference/plugin-workflow.md +25 -0
  77. package/docs/reference/troubleshoot-doctor.md +50 -0
  78. package/docs/reference/troubleshoot-hooks.md +99 -0
  79. package/docs/reference/troubleshoot-install.md +108 -0
  80. package/docs/reference/troubleshoot-tools.md +56 -0
  81. package/docs/reference/troubleshoot-update.md +23 -0
  82. package/docs/reference/troubleshoot-web.md +66 -0
  83. package/docs/reference/troubleshooting.md +13 -337
  84. package/docs/understand/a-day.md +3 -1
  85. package/docs/understand/enforced-vs-asked.md +3 -1
  86. package/docs/understand/harness.md +2 -0
  87. package/docs/understand/machine-bob.md +17 -0
  88. package/docs/understand/machine-claude.md +35 -0
  89. package/docs/understand/machine-opencode.md +36 -0
  90. package/docs/understand/on-your-machine.md +12 -55
  91. package/docs/understand/take-it-out.md +13 -0
  92. package/docs/web-ui.md +35 -15
  93. package/harness.config.json +1 -1
  94. package/js/README.md +11 -3
  95. package/js/cli-table.json +27 -1
  96. package/js/hosts/mcp.mjs +1 -1
  97. package/js/hosts/native.mjs +43 -5
  98. package/js/inspect/checks-build.mjs +28 -0
  99. package/js/loop/catalog.mjs +12 -1
  100. package/js/loop/cli.mjs +28 -6
  101. package/js/loop/graph.mjs +18 -0
  102. package/js/loop/registry.mjs +196 -0
  103. package/js/loop/score.mjs +45 -6
  104. package/js/loop/state.mjs +125 -11
  105. package/js/maintain/setup.mjs +1 -1
  106. package/js/web/actions.mjs +25 -0
  107. package/js/web/api.mjs +13 -0
  108. package/js/web/docs.mjs +64 -12
  109. package/js/web/routes.mjs +5 -1
  110. package/package.json +1 -1
  111. package/src/agents/explorer.md +2 -2
  112. package/src/agents/researcher.md +3 -3
  113. package/src/bricks/README.md +3 -1
  114. package/src/bricks/adr-challenge.md +20 -0
  115. package/src/bricks/adr-draft.md +15 -0
  116. package/src/bricks/characterize.md +17 -0
  117. package/src/bricks/ci-fix.md +2 -1
  118. package/src/bricks/ci-triage.md +20 -0
  119. package/src/bricks/compat-check.md +16 -0
  120. package/src/bricks/done-check.md +16 -0
  121. package/src/bricks/fitness-define.md +22 -0
  122. package/src/bricks/flake-check.md +17 -0
  123. package/src/bricks/flake-repro.md +18 -0
  124. package/src/bricks/identify.md +6 -3
  125. package/src/bricks/migration-plan.md +21 -0
  126. package/src/bricks/mutation-check.md +18 -0
  127. package/src/bricks/plan.md +6 -6
  128. package/src/bricks/red-test.md +16 -0
  129. package/src/bricks/review.md +5 -3
  130. package/src/bricks/spec.md +18 -0
  131. package/src/bricks/upgrade-scout.md +16 -0
  132. package/src/loops/api-endpoint.json +31 -0
  133. package/src/loops/architecture-decision.json +22 -0
  134. package/src/loops/bugfix.json +1 -0
  135. package/src/loops/ci-repair.json +19 -0
  136. package/src/loops/deps-upgrade.json +29 -0
  137. package/src/loops/enforce-architecture-rule.json +28 -0
  138. package/src/loops/feature.json +8 -5
  139. package/src/loops/fix-flaky-tests.json +30 -0
  140. package/src/loops/legacy-refactor.json +26 -0
  141. package/src/loops/legacy-tests.json +29 -0
  142. package/src/loops/refactor.json +5 -1
  143. package/src/loops/remove-dead-code.json +30 -0
  144. package/src/loops/spec-first-feature.json +29 -0
  145. package/src/loops/tdd.json +25 -0
  146. package/src/loops/update-contract.json +33 -0
  147. package/src/skills/brick-forge.md +3 -1
  148. package/src/skills/bruno-collection-generator.md +3 -3
  149. package/src/skills/bruno-test-writer.md +3 -3
  150. package/src/skills/ci-fix.md +3 -3
  151. package/src/skills/consolidate-memory.md +4 -4
  152. package/src/skills/council.md +1 -1
  153. package/src/skills/fresh-eyes.md +1 -1
  154. package/src/skills/git-archaeology.md +1 -1
  155. package/src/skills/git-rescue.md +4 -3
  156. package/src/skills/handoff.md +1 -1
  157. package/src/skills/herdr.md +1 -1
  158. package/src/skills/learn-mode.md +2 -2
  159. package/src/skills/loop.md +22 -10
  160. package/src/skills/opencode-theme.md +3 -3
  161. package/src/skills/ponytail.md +1 -1
  162. package/src/skills/profile.md +3 -4
  163. package/src/skills/prose.md +2 -3
  164. package/src/skills/quiz.md +1 -1
  165. package/src/skills/react-view-transitions/SKILL.md +1 -1
  166. package/src/skills/react-view-transitions/VENDOR.md +8 -3
  167. package/src/skills/research.md +3 -3
  168. package/src/skills/review-response.md +2 -2
  169. package/src/skills/rule.md +3 -3
  170. package/src/skills/security-audit.md +4 -4
  171. package/src/skills/teach.md +1 -1
  172. package/src/skills/wiki.md +3 -3
  173. package/src/skills/workflow.md +4 -4
  174. package/src/skills/worktree.md +2 -2
  175. package/web/dist/assets/Activity-Ca2Aruu7.js +1 -0
  176. package/web/dist/assets/ActivityDetail-Bo7v4Z_r.js +1 -0
  177. package/web/dist/assets/Dashboard-BuMq46aT.js +2 -0
  178. package/web/dist/assets/Docs-BzccCllG.js +5 -0
  179. package/web/dist/assets/FilterInput-CBcJBQPI.js +1 -0
  180. package/web/dist/assets/GreenhouseView-BCIKcnGG.js +2 -0
  181. package/web/dist/assets/Installs-DMFJvq7s.js +2 -0
  182. package/web/dist/assets/JournalView-o1rmd1_1.js +1 -0
  183. package/web/dist/assets/Laws-BANxq_I_.js +3 -0
  184. package/web/dist/assets/Library-DW4x0fbh.js +1 -0
  185. package/web/dist/assets/Loops-DEBibbBP.js +2 -0
  186. package/web/dist/assets/{Markdown-qjM2_ofS.js → Markdown-CdTX0kLe.js} +14 -14
  187. package/web/dist/assets/OperatorHudView-CLD0fYaA.js +2 -0
  188. package/web/dist/assets/Personal-6uMJvyBG.js +1 -0
  189. package/web/dist/assets/Tabs-BubnyZhF.js +1 -0
  190. package/web/dist/assets/activity-CObqyxkL.js +1 -0
  191. package/web/dist/assets/{api-CyMRbU2x.js → api-D_ixdyEY.js} +1 -1
  192. package/web/dist/assets/drawable-C_x5xncq.js +1 -0
  193. package/web/dist/assets/index-CMPgezFm.js +2 -0
  194. package/web/dist/assets/index-DMsT4Aa6.css +1 -0
  195. package/web/dist/assets/{react-B9Z_tXRV.js → react-Bbzhmq4v.js} +1 -1
  196. package/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  197. package/web/dist/assets/sections-Dg23Hel5.js +1 -0
  198. package/web/dist/assets/usePoll-BOqeunzF.js +1 -0
  199. package/web/dist/index.html +6 -5
  200. package/web/dist/assets/Activity-GaaZWXTY.js +0 -1
  201. package/web/dist/assets/ActivityDetail-4t7d45Du.js +0 -1
  202. package/web/dist/assets/Dashboard-CYn7Tp16.js +0 -2
  203. package/web/dist/assets/Docs-BeFKLg2T.js +0 -5
  204. package/web/dist/assets/FilterInput-CVyqmYWM.js +0 -1
  205. package/web/dist/assets/GreenhouseView-C6ibc8IE.js +0 -2
  206. package/web/dist/assets/Installs-DRYjYnxs.js +0 -2
  207. package/web/dist/assets/JournalView-1HbU1mfg.js +0 -1
  208. package/web/dist/assets/Laws-DFoG8JWB.js +0 -3
  209. package/web/dist/assets/Library-DDjgNwz_.js +0 -1
  210. package/web/dist/assets/Loops-D9VEoO0F.js +0 -1
  211. package/web/dist/assets/OperatorHudView-Bs7paWmh.js +0 -2
  212. package/web/dist/assets/Personal-BY5n4gTw.js +0 -1
  213. package/web/dist/assets/Tabs-ho-EYD8i.js +0 -1
  214. package/web/dist/assets/drawable-CLS9drMb.js +0 -1
  215. package/web/dist/assets/index-CX_hXMi5.css +0 -1
  216. package/web/dist/assets/index-Cjr7XCA3.js +0 -2
  217. package/web/dist/assets/sections-GalMS0Zv.js +0 -1
  218. package/web/dist/assets/usePoll-O0sJEw1Y.js +0 -1
@@ -3,53 +3,27 @@ group: concepts
3
3
  order: 1
4
4
  title: "Hosts"
5
5
  kind: "concept"
6
+ section: "Harness"
7
+ description: "The AI coding tools Geneseed installs into, and what each one can enforce."
6
8
  ---
7
9
  A **host** is the AI coding tool Geneseed installs into — OpenCode, Claude Code, Bob or OpenClaude. Geneseed does not run the model; the host does. Geneseed writes the files the host reads (the instructions file, agents, skills) and, where the host allows it, wires small programs that run around the agent's actions. The *content* is the same on every host. What differs is how much of it the host lets Geneseed **automate** — check in code before an action — rather than only **ask** of the model in prose.
8
10
 
9
11
  > **You already know this:** one codebase, several CI providers. The pipeline does the same job everywhere, but each provider exposes different hooks, so some checks run natively on one and are a manual step on another.
10
12
 
11
- ### What is the same everywhere
13
+ ## What is the same everywhere
12
14
 
13
15
  One build renders the same text for every host: the constitution ([rules](rules.md)), the {N_AGENTS} [agents](agents.md), the {N_SKILLS} [skills](skills.md), the [memory](memory.md) and [notebook](notebook.md) conventions, and the theme's voice. No host drops an agent, a skill or the memory convention.
14
16
 
15
17
  Each host has a **global** install (in its config directory, active in every repo) and a **per-repo** install (inside one project). There is also a portable `files` bundle — a plain `Harness/` folder with an `AGENT.md` that any tool reading an instructions file can use, with no automation at all.
16
18
 
17
- ### Two engines
19
+ ## Two engines
18
20
 
19
21
  - **OpenCode** runs its own engine: Geneseed installs JavaScript **plugins** that OpenCode loads, plus permission entries in `opencode.json`. It also gets OpenCode-only extras: colour themes, [language servers](lsp.md), a workflow runner, a primary agent and `/`-commands.
20
22
  - **Claude Code**, **Bob** and **OpenClaude** share one Claude-shaped engine: Geneseed wires **hooks** into the host's `settings.json`, each calling `geneseed-hook <verb>`. See [Hooks](hooks.md).
21
23
 
22
- ### What each host automates
23
-
24
- | Capability | OpenCode | Claude Code | Bob | OpenClaude |
25
- | --- | :---: | :---: | :---: | :---: |
26
- | Instructions file | `AGENT.md` via `opencode.json` | `CLAUDE.md` | `AGENTS.md` + `rules/geneseed.md` | `CLAUDE.md` (`.openclaude/` per repo) |
27
- | Agents · Skills · Memory · Notebook | ✅ | ✅ | ✅ | ✅ |
28
- | Project context loaded at session start | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook² |
29
- | Memory written back at session end (learn) | ⚙️ plugin | 🪝 hook | 🪝 hook¹ | 🪝 hook² |
30
- | Destructive git (force-push, `reset --hard`…) | 🔒 permission ask | 🪝 ask | 🪝 block¹ | 🪝 ask² |
31
- | Secrets kept out of files | ⚙️ block⁴ | 🪝 ask | 🪝 block¹ | 🪝 ask² |
32
- | Consent before every commit and push | 🔒 permission ask | 🪝 ask | 🪝 warning¹ | 🪝 ask² |
33
- | Rule-or-memory write needs your call | ⚙️ speed bump³ | 🪝 ask | 🪝 warning¹ | 🪝 ask² |
34
- | Sovereign-repo exclusions | ⚙️ plugins stand down | ✅ `claudeMdExcludes` | ✅ rules shadow stub | ✅ `claudeMdExcludes` |
35
- | MCP server wiring | ✅ `mcp` | ✅ `mcpServers` | ✅ `mcp.json` | ✅ `mcpServers` |
36
- | Colour themes · LSP · workflow runner · primary agent · `/`-commands | ✅ | ➖ | ➖ | ➖ |
37
-
38
- ✅ native · ⚙️ OpenCode plugin · 🔒 `permission.bash` entry in `opencode.json` · 🪝 `settings.json` hook · ➖ no host mechanism (the rule still applies as prose).
39
-
40
- ¹ **Bob** has its own hook contract: Claude's event names, but it ignores a hook's output on `PreToolUse`, so the only way to refuse is exit code 2. Geneseed therefore blocks only the two always-on rules (secrets, destructive git) and turns the two consent checks into a logged warning. It has no `SubagentStop` or `PreCompact` event, so learn runs on `Stop` only. **Unverified live** — there is no Bob install on the authoring machine; the rules preamble still holds if a hook does not fire.
41
- ² **OpenClaude** is a Claude Code fork and gets Claude's hooks and verdicts verbatim, in `~/.openclaude/settings.json` (global) or `.openclaude/settings.local.json` (per repo). **Unverified live** for the same reason.
42
- ³ OpenCode's plugin hook can only allow or throw — there is no "ask the user" — so this check stops the first such write once rather than prompting.
43
- ⁴ The checks differ in shape: OpenCode's guard plugin blocks writes *to* private-key and credential files by path; the Claude-shaped hook looks at the *content* being written for credential-shaped strings (cloud keys, tokens, private-key blocks) and asks. A `.env` file is exempt on the hook side — that is where a secret is allowed to live.
44
-
45
- ### The one conditional row
46
-
47
- The **consent before commit and push** row depends on a choice you make at build time. It enforces the rule *Consent Before Push*, which belongs to the **process** doctrine pack ([Rules](rules.md)). Build without that pack, or exclude that one rule, and the commit/push question goes away — but the gate itself stays: on Claude Code and OpenClaude the `git-gate` hook is still wired (with `--no-consent`), so destructive git is still caught. Everything else in the table is always on.
48
-
49
- One OpenCode asymmetry: Geneseed shares `opencode.json` with you and cannot tell its own `git commit*` permission entry from one you typed, so a rebuild without the process pack leaves an existing entry in place and says so instead of deleting it.
50
-
51
- ### Where to go next
24
+ ## Where to go next
52
25
 
26
+ - Which checks each host runs in code, row by row: [What each host automates](host-matrix.md).
53
27
  - What exactly each host writes to disk: [What lands on your machine](../understand/on-your-machine.md).
54
28
  - Code-enforced versus asked-of-the-model, in plain terms: [Enforced vs. asked](../understand/enforced-vs-asked.md).
55
29
  - Per-host detail for maintainers: [OpenCode](../../adapters/opencode/README.md) · [Claude Code](../../adapters/claude-code/README.md) · [Bob](../../adapters/bob/README.md) · [OpenClaude](../../adapters/openclaude/README.md).
@@ -0,0 +1,66 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 23
6
+ title: "LOOP.md, trailers and the loop branch"
7
+ description: "The loop's state file, the trailers on every commit, the loop/* branch exemption, and the console's view."
8
+ ---
9
+ ## `LOOP.md` and its trailers
10
+
11
+ `LOOP.md`, at the worktree root, is both the human-readable record (title, requirement, and the
12
+ rule that you may edit `preset` or `contracts` there) and the engine's own JSON state block. Every
13
+ closing commit carries a fixed set of trailers, read straight off that state — `Loop-Gates` only
14
+ when the unit passed at least one human gate:
15
+
16
+ ```
17
+ Loop-Iteration: <n>
18
+ Loop-Bricks: <every brick name visited this unit, deduplicated>
19
+ Loop-Risk-Declared: <score>
20
+ Loop-Risk-Actual: <score>
21
+ Loop-Threshold: <preset> <silent>/<soft>
22
+ Loop-Decision: silent | soft | blocking[ (amended)]
23
+ Loop-Tests: <what the loop was told about test state>
24
+ Loop-Gates: <every node whose gate passed this unit, deduplicated>
25
+ ```
26
+
27
+ ## The `loop/*` branch, and why merge always asks
28
+
29
+ A loop runs in its own worktree, on a branch named `loop/<slug>` — the `loop` skill creates both
30
+ with `git worktree add -b loop/<slug>` before `geneseed loop init` writes `LOOP.md` there.
31
+ While that branch is checked out and `LOOP.md` carries the engine's state marker, the git gate lets
32
+ exactly one commit/push form through without asking:
33
+
34
+ ```
35
+ git add -A && git commit -F <message_file> && git push [-u] <remote> HEAD:<loop branch>
36
+ ```
37
+
38
+ Nothing else is exempt — not `git commit -m`, not a quoted refspec, not a plain `git push` with no
39
+ explicit `HEAD:<ref>` — any other shape still asks. The exemption only ever covers a `loop/*`
40
+ branch, and never a shared one (`main`, `master`, `develop`, `development`, `release/*`,
41
+ `hotfix/*`). The **final** commit of a run — the one that removes `LOOP.md` on `$close` — is
42
+ outside the exemption too, because the loop is no longer running when it lands; that ask is your
43
+ consent to close it. **Merging a loop branch into anything else always asks, with no exception.**
44
+ The loop reports the branch to merge and the iterations that landed in "to review" — it never
45
+ merges for you.
46
+
47
+ ## Watching a loop
48
+
49
+ Every `geneseed loop init` upserts an identity row — root, branch, title, started — into a
50
+ **loop registry** at `$XDG_CONFIG_HOME/geneseed/loops.json` (default `~/.config/geneseed/loops.json`).
51
+ `LOOP.md` stays the only source of loop *state*; the registry just lets the console find a loop
52
+ without scanning every worktree on the machine. Only loops launched by this version or later are
53
+ registered, so a loop started before the registry existed won't appear until re-initialised.
54
+
55
+ The console's **Loops › Active** tab (`GET /api/loops/active`, polled every few seconds) reads that
56
+ registry and shows one card per loop: branch, status (`running`, `awaiting`, `done`, `stopped`,
57
+ `finished`, or `unreadable` if `LOOP.md` fails to parse), `iteration N / max`, and its current
58
+ node. A loop `awaiting` a decision is highlighted with what it's waiting on — the launch, the
59
+ declared score, the actual score, or a human gate (with its node) — but **the answer is given in the agent's session**, with
60
+ `geneseed loop decide`, never from the page. A finished loop (`LOOP.md` removed) is kept, muted,
61
+ for 7 days after first being seen finished, then dropped. Selecting a card draws its ring with the
62
+ current node filled, with the iteration history (declared, actual, decision, tests) underneath.
63
+
64
+ Each live card also carries a **preset picker** (`POST /api/loops/preset`) that rewrites
65
+ `LOOP.md`'s `preset` field — the same edit you could make by hand — applying from the next score
66
+ on, not retroactively. It's the tab's only write; there is no relaunch button.
@@ -0,0 +1,48 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 18
6
+ title: "Bricks and their origins"
7
+ description: "What a brick is, how templates wire bricks, and how project and global bricks override shipped ones."
8
+ ---
9
+ A **brick** is a markdown file: YAML-ish frontmatter (`name`, `description`, `effect` — `read` or
10
+ `mutate` — exactly one of `agent` or `skill`, and `outcomes`) plus a 4-10 line prose body. The
11
+ model never sees the file; `geneseed loop next` hands it the body as the prompt. A **loop
12
+ template** — a shipped template (see [Loop templates](loop-templates.md)) or one composed by hand — is the graph JSON
13
+ that wires bricks together.
14
+
15
+ Both are looked up across three origins, each able to override the one before it **by name**:
16
+
17
+ | origin | path | who writes it |
18
+ |---|---|---|
19
+ | shipped | `src/bricks/`, `src/loops/` | Geneseed itself — read by the CLI from its own source, never emitted into an install |
20
+ | global | `$XDG_CONFIG_HOME/geneseed/{bricks,loops}` (default `~/.config/geneseed/…`) | the user, for every project on this machine |
21
+ | project | `<repo>/.geneseed/{bricks,loops}` | a team, committed and shared |
22
+
23
+ Precedence is project > global > shipped. A project or global brick named `apply` replaces the
24
+ shipped `apply` everywhere a template references it, without the template changing.
25
+ `geneseed loop check` lists every override it finds, never silently.
26
+
27
+ A per-install skill exclusion is invisible to the CLI — it has no way to know which skills your
28
+ install carries. The `loop` skill covers the gap itself: when composing a graph it skips a brick
29
+ whose `skill` it doesn't have.
30
+
31
+ To add or adapt a brick, use the `brick-forge` skill — ask it, or see
32
+ [the bricks README](../../src/bricks/README.md) in
33
+ the repository.
34
+
35
+ ## Java notes for the newer bricks
36
+
37
+ - **`mutation-check`** (`legacy-tests`) prefers PIT on a Maven build: `mvn test-compile
38
+ org.pitest:pitest-maven:mutationCoverage -DtargetClasses=<fq.Class*>
39
+ -DreportsDirectory=<OS temp dir> -DtimestampedReports=false`, and needs `pitest-junit5-plugin`
40
+ on the classpath under JUnit 5; on Gradle, the `info.solidsoft.pitest` plugin's `pitest` task.
41
+ With neither configured it reports `unavailable` rather than adding the plugin itself or a
42
+ silent `pass`.
43
+ - **`fitness-define`** (`enforce-architecture-rule`) reaches for ArchUnit first on Java — a
44
+ `FreezingArchRule`, whose violation store doubles as the allowlist of today's violations —
45
+ before dependency-cruiser, import-linter, eslint-plugin-boundaries or size-limit elsewhere.
46
+ - **`migration-plan`** (`update-contract`) treats Pact or Spring Cloud Contract, where the repo
47
+ already records consumer contracts, as the check `compat-check` runs against each step rather
48
+ than only the consumers' own test suites.
@@ -0,0 +1,33 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 22
6
+ title: "Contracts and ignored deletions"
7
+ description: "The contract globs that always raise risk, the deletions a template ignores, and the glob dialect."
8
+ ---
9
+ A template may declare `contracts`: globs for the interface or schema files whose *shape* a
10
+ change can break, not just the implementation behind it — `update-contract` and
11
+ `api-endpoint` ship defaults (OpenAPI/Swagger/AsyncAPI specs, `.proto`, `.avsc`, GraphQL schemas,
12
+ Flyway/Liquibase migrations). They're copied into `LOOP.md`'s own `contracts` at `loop init`;
13
+ `loop init --contracts <globs>` appends more, and the list is editable by hand in `LOOP.md`
14
+ afterward, applying from the next score on. Touching a file any of these globs match raises the
15
+ *actual* score to at least the **api** weight (0.8) regardless of the declared card — a contract
16
+ edit is never silent.
17
+
18
+ A template may also declare `ignoreDeletions`: globs excluded from the ">20 deleted lines"
19
+ escalation rule only. `deps-upgrade` lists lockfiles this way (`**/package-lock.json`,
20
+ `**/yarn.lock`, `**/pnpm-lock.yaml`, `**/*.lock`, `**/gradle.lockfile`) because a lockfile
21
+ regenerating under a bump deletes and re-adds hundreds of lines with no risk in them;
22
+ `remove-dead-code` ignores generated output (`**/generated/**`, `**/generated-sources/**`,
23
+ `**/target/**`, `**/build/generated/**`) for the same reason. A file matched by `ignoreDeletions`
24
+ is still subject to the write-set check — it must still be declared or match a write-set glob, it
25
+ just doesn't count toward the deletion total.
26
+
27
+ Both lists, and the write set, share one hand-rolled glob dialect (no dependency — this module
28
+ imports only node builtins): `*` and `?` stay inside one path segment, `**` crosses segments and
29
+ `**/` may match zero directories (so `**/yarn.lock` also covers the root one); there is no brace
30
+ expansion (`{a,b}`). A write-set entry is matched as a glob too, but only when it has at least one
31
+ literal (non-`*`/`?`) path segment — a wildcard-only entry like `**` or `**/*.java` would
32
+ otherwise declare the whole repo as writable, so it's left to match nothing instead and the
33
+ check fails closed.
@@ -0,0 +1,30 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 21
6
+ title: "Human gates"
7
+ description: "Bricks that hold for a person whatever the score, and how ok, no and amend answer them."
8
+ ---
9
+ A brick can hold for a person regardless of preset or score, independent of the [risk machinery](loop-risk.md): its frontmatter carries `gate: human`, optionally narrowed with `gateOn: <outcomes>` (no
10
+ `gateOn` holds on every outcome the brick can report). `adr-challenge` (holds on `pass` — a
11
+ drafted ADR that survived its skeptic), `fitness-define`, `migration-plan` and `spec` all gate
12
+ this way: the loop reports `{awaiting}` with `kind: "gate"` before the edge that outcome would
13
+ normally follow is taken at all — **the gate holds the whole transition**, so nothing is scored,
14
+ committed or counted against a ring budget while it waits.
15
+
16
+ `geneseed loop decide --verdict ok|no|amend` answers it:
17
+
18
+ - **`ok`** follows the edge the brick's reported outcome actually points to. On a brick gated on
19
+ more than one outcome, a held `fail` still routes through its own edge on `ok` — which is
20
+ usually `$stop` — so `ok` on a held failure stops the loop, it doesn't wave it through.
21
+ - **`no`** stops the loop at that node.
22
+ - **`amend`** re-runs the same brick with your note appended to `LOOP.md`'s notes, so the next
23
+ run of that brick sees it; the node's re-entry (ring) budget restarts, since the amendment
24
+ changes what the unit does. A node can be amended at most 3 times per iteration — the 4th
25
+ amend stops the loop instead: three rounds that didn't converge are a conversation, not a loop.
26
+
27
+ Every closing commit that passed a gate names it under `Loop-Gates` (see [LOOP.md, trailers and the loop branch](loop-branch.md)). The console's
28
+ **Active** tab shows a gated loop as `Awaiting gate at <node>`, the same way it shows a score
29
+ `awaiting`. A gate passed in a read-only setup unit leaves its approval as a note in `LOOP.md`,
30
+ not a trailer — that unit closes without a commit.
@@ -0,0 +1,43 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 19
6
+ title: "Notes and rules"
7
+ description: "What survives an iteration in LOOP.md's notes, and the rules a template hands every brick."
8
+ ---
9
+ Two ways words travel through a loop: the notes a brick leaves in `LOOP.md`, and the rules a template hands every brick.
10
+
11
+ ## Notes: what survives an iteration
12
+
13
+ A `read` brick can find something worth keeping — a plan, a review finding, a mutation gap, a
14
+ classified CI failure — that the next brick needs but the outcome string alone can't carry.
15
+ `geneseed loop record --note "<text>"` (or `--note-file <path>` for anything multi-line or that
16
+ mentions `git commit`/`push`, which a shell argument can't carry safely) appends it to `LOOP.md`'s
17
+ notes, so it survives into the next node and the next iteration instead of evaporating with the
18
+ brick's own context. The brick never records a note itself — a brick only ever reports its
19
+ outcome, plus the path to a file it wrote; the loop skill records it with `--note-file` on the
20
+ brick's behalf. This applies to `plan` and `review` as much as to the newer bricks: any `read`
21
+ brick whose finding the next brick needs writes it to a file in the OS temp directory and reports
22
+ that file's path with the outcome.
23
+
24
+ ## `description` and `rules`: what a template is for, and what every brick must do
25
+
26
+ A template's JSON carries two prose fields, and they are never confused:
27
+
28
+ - **`description`** — the catalogue blurb: what the template is for and when to pick it. The
29
+ `loop` skill and the console read it to choose a template; no brick ever receives it.
30
+ - **`rules`** — optional, a list of one-line instructions every brick of this loop must follow
31
+ (`["Each card's intent cites the proof it is unused: …", "Generated sources do not count as
32
+ unused."]`). `geneseed loop check` refuses anything but a list of non-empty strings.
33
+
34
+ `geneseed loop next` hands the template's `rules` to every node — not only the iteration head that
35
+ reads `LOOP.md` — so a template-wide proviso (cite your deletion proof, a flaky test is never fixed
36
+ with a retry, contract edits stop for a human by design) is visible to whichever brick runs,
37
+ including `review`, which checks the diff against it. A graph with no `rules`, or an empty list,
38
+ omits the field; there is no fallback to `description`.
39
+
40
+ A template may also carry a **`category`** — one of `architecture`, `tests`, `development`,
41
+ `refactoring`, `day-to-day` — the shelf the console's Loops page files it under, in that order.
42
+ It is optional (a template without one is listed under *Other*); `geneseed loop check` refuses
43
+ any other value.
@@ -0,0 +1,36 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 20
6
+ title: "Risk, trust and validation levels"
7
+ description: "How a loop scores a change, the trust presets, and the silent, soft and blocking levels."
8
+ ---
9
+ Before a `mutate` brick runs, the loop scores the card the brick's setup declared: one risk weight
10
+ per action kind it named, and the score is the **max**, not a sum — one contract change outweighs
11
+ ten trivial renames, and ten trivial renames never add up to one. After the brick runs, the loop
12
+ re-scores against the real diff, and the diff can only raise the score, never lower it:
13
+
14
+ - a file touched outside the declared write set raises the score to at least **api** (`0.8`);
15
+ - more than 20 deleted lines raises it to at least the **delete** weight;
16
+ - touching a file listed in the loop's `contracts` raises it to at least the **api** weight.
17
+
18
+ `LOOP.md` itself is excluded from every score and every diff check — it's the engine's own
19
+ bookkeeping, rewritten on every action, never part of the work being judged.
20
+
21
+ The score is checked against a **trust preset** — `--preset` on `geneseed loop init`, editable
22
+ afterward in `LOOP.md`'s `preset` field, applying from the next score on:
23
+
24
+ | preset | silent ≤ | soft ≤ | above soft |
25
+ |---|---|---|---|
26
+ | prudent | 0.1 | 0.3 | blocking |
27
+ | balanced (default) | 0.2 | 0.6 | blocking |
28
+ | aggressive | 0.4 | 0.8 | blocking |
29
+
30
+ Three levels follow from where the score lands:
31
+
32
+ - **silent** — nothing more than the commit trailers (see [LOOP.md, trailers and the loop branch](loop-branch.md)).
33
+ - **soft** — listed under "to review" in the run's final summary; no notification during the run.
34
+ - **blocking** — the run ends. `LOOP.md` is written with `status: awaiting`, and a person has to
35
+ answer with `geneseed loop decide --verdict ok|no|amend`. Amending a verdict marks the decision
36
+ `blocking (amended)` in the trailers rather than silently rewriting it to something else.
@@ -0,0 +1,50 @@
1
+ ---
2
+ group: concepts
3
+ kind: "concept"
4
+ section: "Loops"
5
+ order: 17
6
+ title: "Loop templates"
7
+ description: "Every shipped loop template, what it is for, and the notes that matter when you pick one."
8
+ ---
9
+ The loop templates Geneseed ships. Each is a graph of [bricks](loop-bricks.md) wired for one kind of work; [Run a loop](../guides/run-a-loop.md) picks one by what you want to do.
10
+
11
+ | template | purpose | when to use |
12
+ |---|---|---|
13
+ | `bugfix` | reproduce, fix, test, review a defect | a reported bug with a reproduction step |
14
+ | `feature` | plan, then build and review in small iterations | new behaviour with no existing test pinning it |
15
+ | `refactor` | restructure behind the existing tests, no behaviour change | the tests already cover the code you're moving |
16
+ | `tdd` | plan, then write each failing test before the code that passes it | you want the test written first, every iteration |
17
+ | `legacy-tests` | pin undocumented behaviour with characterization tests, mutation-checked, production code untouched | code with no tests and no spec, before anyone risks changing it |
18
+ | `legacy-refactor` | pin current behaviour once with characterization tests, then refactor behind that net | the refactor target has no tests yet but will get changed |
19
+ | `deps-upgrade` | upgrade one package or group per iteration: read breaking changes, bump, adapt, audit | a dependency bump that needs to land as reviewable steps, not one big diff |
20
+ | `ci-repair` | triage failing CI checks for the current commit and fix one code failure per iteration | a red CI run on a `loop/*` branch that needs to go green |
21
+ | `architecture-decision` | draft one ADR per decision the requirement names, challenged by a skeptic brick, reviewed by the user | a design choice worth recording before (or instead of) any code changes |
22
+ | `enforce-architecture-rule` | encode an architecture rule as a test with an allowlist of today's violations, then fix one violation per iteration | a rule the codebase should hold everywhere but doesn't yet |
23
+ | `update-contract` | change an interface with live consumers as expand, migrate one consumer per iteration, contract | an API, schema or event change that can't break existing callers in one step |
24
+ | `spec-first-feature` | write the feature's spec (EARS criteria, ordered tasks) for review, then build one task per iteration | a feature whose acceptance criteria are worth pinning down before any code |
25
+ | `api-endpoint` | plan, build, test, write a Bruno request and security-review one endpoint change per iteration | an HTTP API feature where each endpoint needs its own exercised request and a security pass |
26
+ | `remove-dead-code` | confirm the suite is green, then delete one coherent group of unused code per iteration, test, review | code a tool (knip, ts-prune, vulture, PMD…) and a reference search say is unused |
27
+ | `fix-flaky-tests` | confirm flakiness by repeated runs, then fix one test's root cause per iteration — never a retry or a sleep | a test that fails only sometimes, not every run |
28
+
29
+ `feature` and `spec-first-feature` both end with an independent `done-check`: before `$close`, it
30
+ maps every acceptance criterion to a passing test (or a stated manual check) and reports `fail`
31
+ with what's missing rather than trusting the iterations that already ran.
32
+
33
+ `legacy-tests` and `legacy-refactor` both open on `baseline-green` — the suite must already be
34
+ green before either template pins anything, and `baseline-green` reporting `fail` stops the loop
35
+ rather than characterizing a change no one can tell from existing breakage.
36
+
37
+ `mutation-check`, inside `legacy-tests`, needs a mutation tool on the stack (Stryker, PIT, mutmut,
38
+ cargo-mutants) to prove the new characterization tests actually bite. With none configured it
39
+ reports `unavailable` rather than a silent `pass` — and still writes a note saying what it checked,
40
+ so the gap is visible in `LOOP.md` rather than just absent from it.
41
+
42
+ `ci-repair` needs CI to actually run on `loop/*` branches; `ci-triage` keys off the HEAD commit's
43
+ checks (`gh run list --commit`), and with no run for that commit it reports `done` with a note
44
+ rather than treating a branch CI never touched as green.
45
+
46
+ `deps-upgrade` lists lockfiles under `ignoreDeletions` (`**/package-lock.json`, `**/yarn.lock`,
47
+ `**/pnpm-lock.yaml`, `**/*.lock`, `**/gradle.lockfile`): a lockfile regenerating under a bump deletes
48
+ and re-adds hundreds of lines with no risk in them, so those lines stay out of the deleted-lines
49
+ count. Everything else keeps the default `delete` weight, and a lockfile outside the iteration's
50
+ write set still escalates like any other file.
@@ -1,10 +1,14 @@
1
1
  ---
2
2
  group: concepts
3
- order: 11
4
- title: "Loops"
5
3
  kind: "concept"
6
- link: {"hash": "#/docs/reference/cli", "label": "geneseed loop --help →"}
4
+ section: "Loops"
5
+ order: 16
6
+ title: "Loops"
7
+ link: {"hash":"#/docs/loop-actions","label":"The geneseed loop actions →"}
8
+ description: "What a loop is, the ring of bricks it runs, and how it differs from foreman mode."
7
9
  ---
10
+ To run one, see [Run a loop](../guides/run-a-loop.md).
11
+
8
12
  A **loop** is a requirement worked as small, validated, committed iterations instead of one long
9
13
  turn. `geneseed loop` is the state machine: it decides every transition, ceiling, score and stop,
10
14
  and hands the agent one node at a time to run. The `loop` [skill](skills.md) is the only thing
@@ -22,10 +26,11 @@ report. One cycle through the graph back to its head is an **iteration**; the gr
22
26
  array names every cycle that is allowed to exist, each with a `max` number of times a node inside
23
27
  it may be re-entered. Picture it as rings: the outer ring is the iteration itself (plan, apply,
24
28
  test, review, back to plan), and inner rings sit inside it for retries (apply failed its test, try
25
- `apply` again without going all the way back around). The three shipped templates —
26
- `bugfix`, `feature`, `refactor` — all nest a short `apply`↔`test` retry ring inside the iteration
27
- ring, and `bugfix` and `feature` nest a second, wider `apply`↔`test`↔`review` ring
28
- (`review-fix`) around that.
29
+ `apply` again without going all the way back around). The shipped templates that center on
30
+ `apply` — `bugfix`, `feature`, `refactor`, `tdd`, `legacy-refactor`, `deps-upgrade` — all nest a
31
+ short `apply`↔`test` retry ring inside the iteration ring, and most nest a second, wider
32
+ `review-fix` ring around that. `legacy-tests` and `ci-repair` have no `apply` at all: the first
33
+ only ever writes tests, the second repairs CI directly through `ci-fix`.
29
34
 
30
35
  Work closes into a commit whenever the graph re-enters the iteration loop's head — so any setup
31
36
  work before the loop starts (reproducing a bug, say) is its own unit, numbered iteration 0, kept
@@ -42,120 +47,23 @@ all gets exactly 1 — no re-entry — which is also why **every cycle inside an
42
47
  named inner loop** in the graph JSON: `geneseed loop check` (and `loop init`, which runs the same
43
48
  check) refuses a graph with an undeclared cycle inside an iteration, before a single node runs.
44
49
 
45
- ## Bricks, templates, and the three origins
46
-
47
- A **brick** is a markdown file: YAML-ish frontmatter (`name`, `description`, `effect` — `read` or
48
- `mutate` — exactly one of `agent` or `skill`, and `outcomes`) plus a 4-10 line prose body. The
49
- model never sees the file; `geneseed loop next` hands it the body as the prompt. A **loop
50
- template** (`bugfix`, `feature`, `refactor`, or one composed by hand) is the graph JSON that wires
51
- bricks together.
52
-
53
- Both are looked up across three origins, each able to override the one before it **by name**:
54
-
55
- | origin | path | who writes it |
56
- |---|---|---|
57
- | shipped | `src/bricks/`, `src/loops/` | Geneseed itself — read by the CLI from its own source, never emitted into an install |
58
- | global | `$XDG_CONFIG_HOME/geneseed/{bricks,loops}` (default `~/.config/geneseed/…`) | the user, for every project on this machine |
59
- | project | `<repo>/.geneseed/{bricks,loops}` | a team, committed and shared |
60
-
61
- Precedence is project > global > shipped. A project or global brick named `apply` replaces the
62
- shipped `apply` everywhere a template references it, without the template changing.
63
- `geneseed loop check` lists every override it finds, never silently.
64
-
65
- A per-install skill exclusion is invisible to the CLI — it has no way to know which skills your
66
- install carries. The `loop` skill covers the gap itself: when composing a graph it skips a brick
67
- whose `skill` it doesn't have.
68
-
69
- To add or adapt a brick, use the `brick-forge` skill — ask it, or see
70
- [the bricks README](https://github.com/geneseed-dev/geneseed/blob/main/src/bricks/README.md) in
71
- the repository.
72
-
73
- ## Risk, trust, and the three validation levels
74
-
75
- Before a `mutate` brick runs, the loop scores the card the brick's setup declared: one risk weight
76
- per action kind it named, and the score is the **max**, not a sum — one contract change outweighs
77
- ten trivial renames, and ten trivial renames never add up to one. After the brick runs, the loop
78
- re-scores against the real diff, and the diff can only raise the score, never lower it:
79
-
80
- - a file touched outside the declared write set raises the score to at least **api** (`0.8`);
81
- - more than 20 deleted lines raises it to at least the **delete** weight;
82
- - touching a file listed in the loop's `contracts` raises it to at least the **api** weight.
83
-
84
- `LOOP.md` itself is excluded from every score and every diff check — it's the engine's own
85
- bookkeeping, rewritten on every action, never part of the work being judged.
86
-
87
- The score is checked against a **trust preset** — `--preset` on `geneseed loop init`, editable
88
- afterward in `LOOP.md`'s `preset` field, applying from the next score on:
89
-
90
- | preset | silent ≤ | soft ≤ | above soft |
91
- |---|---|---|---|
92
- | prudent | 0.1 | 0.3 | blocking |
93
- | balanced (default) | 0.2 | 0.6 | blocking |
94
- | aggressive | 0.4 | 0.8 | blocking |
95
-
96
- Three levels follow from where the score lands:
97
-
98
- - **silent** — nothing more than the commit trailers below.
99
- - **soft** — listed under "to review" in the run's final summary; no notification during the run.
100
- - **blocking** — the run ends. `LOOP.md` is written with `status: awaiting`, and a person has to
101
- answer with `geneseed loop decide --verdict ok|no|amend`. Amending a verdict marks the decision
102
- `blocking (amended)` in the trailers rather than silently rewriting it to something else.
103
-
104
- ## `LOOP.md` and its trailers
105
-
106
- `LOOP.md`, at the worktree root, is both the human-readable record (title, requirement, and the
107
- rule that you may edit `preset` or `contracts` there) and the engine's own JSON state block. Every
108
- closing commit carries seven trailers, read straight off that state:
109
-
110
- ```
111
- Loop-Iteration: <n>
112
- Loop-Bricks: <every brick name visited this unit, deduplicated>
113
- Loop-Risk-Declared: <score>
114
- Loop-Risk-Actual: <score>
115
- Loop-Threshold: <preset> <silent>/<soft>
116
- Loop-Decision: silent | soft | blocking[ (amended)]
117
- Loop-Tests: <what the loop was told about test state>
118
- ```
119
-
120
- ## The `loop/*` branch, and why merge always asks
121
-
122
- A loop runs in its own worktree, on a branch named `loop/<slug>` — the `loop` skill creates both
123
- with `git worktree add -b loop/<slug>` before `geneseed loop init` writes `LOOP.md` there.
124
- While that branch is checked out and `LOOP.md` carries the engine's state marker, the git gate lets
125
- exactly one commit/push form through without asking:
126
-
127
- ```
128
- git add -A && git commit -F <message_file> && git push [-u] <remote> HEAD:<loop branch>
129
- ```
130
-
131
- Nothing else is exempt — not `git commit -m`, not a quoted refspec, not a plain `git push` with no
132
- explicit `HEAD:<ref>` — any other shape still asks. The exemption only ever covers a `loop/*`
133
- branch, and never a shared one (`main`, `master`, `develop`, `development`, `release/*`,
134
- `hotfix/*`). The **final** commit of a run — the one that removes `LOOP.md` on `$close` — is
135
- outside the exemption too, because the loop is no longer running when it lands; that ask is your
136
- consent to close it. **Merging a loop branch into anything else always asks, with no exception.**
137
- The loop reports the branch to merge and the iterations that landed in "to review" — it never
138
- merges for you.
139
-
140
- ## `geneseed loop` actions
141
-
142
- | action | what it does |
143
- |---|---|
144
- | `check` | lists templates and every brick (available, unavailable, overridden); validates one graph file (`--graph`) or one brick file (`--brick`) |
145
- | `init` | writes a fresh `LOOP.md` from a template or graph file, under a title, requirement and trust preset |
146
- | `next` | the only driver of the cycle — returns the next thing to do: run a node, score a card, answer an `awaiting`, or a terminal |
147
- | `score` | scores a declared card (`--declared`) before a mutate node runs, or the real diff (`--diff`, numstat piped on stdin) before a commit |
148
- | `record` | records a brick's reported outcome and advances the graph |
149
- | `decide` | answers an `awaiting` validation with a verdict and a note |
150
-
151
- Run `geneseed loop --help` for the full flag list.
152
-
153
50
  ## Limits
154
51
 
155
52
  - **No parallel nodes.** The graph runs one node at a time; there is no fan-out.
156
- - **A per-install skill exclusion is invisible to the CLI** (see above) — the `loop` skill is
53
+ - **A per-install skill exclusion is invisible to the CLI** (see [Bricks and their origins](loop-bricks.md)) — the `loop` skill is
157
54
  responsible for skipping bricks it can't run, not the engine.
158
55
 
56
+ ## Read on
57
+
58
+ - [Loop templates](loop-templates.md): the shipped graphs, and when to use each.
59
+ - [Bricks and their origins](loop-bricks.md): what a brick is, and where your own override the shipped ones.
60
+ - [Notes and rules](loop-notes.md): what survives an iteration, and what every brick must follow.
61
+ - [Risk, trust and validation levels](loop-risk.md): how a change is scored, and when it stops for you.
62
+ - [Human gates](loop-gates.md): the bricks that always wait for a person.
63
+ - [Contracts and ignored deletions](loop-contracts.md): the globs that raise or ignore risk.
64
+ - [LOOP.md, trailers and the loop branch](loop-branch.md): the state file, the commit trailers, and why merging always asks.
65
+ - [Loop actions](../reference/loop-actions.md): the `geneseed loop` commands.
66
+
159
67
  ## Not foreman mode
160
68
 
161
69
  A loop and a [foreman-mode](foreman-mode.md) pipeline are both "hand work off and keep going," but
@@ -3,6 +3,8 @@ group: concepts
3
3
  order: 13
4
4
  title: "Code intelligence (LSP, OpenCode)"
5
5
  kind: "concept"
6
+ section: "Configuration"
7
+ description: "Language servers on OpenCode, so the agent sees real diagnostics."
6
8
  ---
7
9
  OpenCode can run **language servers** — the same Language Server Protocol servers your editor uses — so the agent sees real diagnostics, type errors and definitions, not just text. Geneseed turns this on for every language OpenCode ships a server for.
8
10
 
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  group: concepts
3
- order: 6
3
+ order: 8
4
4
  title: "Memory"
5
5
  kind: "markdown"
6
+ section: "Memory"
7
+ description: "How durable facts are stored, indexed and loaded."
6
8
  source: "src/memory/README.md"
7
9
  ---
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  group: concepts
3
- order: 7
3
+ order: 9
4
4
  title: "Notebook"
5
5
  kind: "markdown"
6
+ section: "Memory"
7
+ description: "The agent's own working space: plans, notes and the gate log."
6
8
  source: "src/notebook/README.md"
7
9
  ---
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  group: concepts
3
- order: 2
3
+ order: 3
4
4
  title: "Rules (the constitution)"
5
5
  kind: "concept"
6
+ section: "Harness"
7
+ description: "The constitution: the standing rules every session carries, in laws and doctrine packs."
6
8
  link: {"hash": "#/laws", "label": "Browse the constitution →"}
7
9
  ---
8
10
  The **constitution** is the set of standing rules the agent carries into every session. It is authored in `src/`, rendered into the instructions file your host reads (`AGENT.md`, `CLAUDE.md` or `AGENTS.md`), and comes in layers that differ in one thing: whether you can turn them off.
@@ -37,7 +39,7 @@ When two instructions disagree, the higher one wins.
37
39
  | **process** | how a session runs — planning, context economy, docs first, bounded loops, consent before every commit and push |
38
40
  | **comms** | how answers are presented — stable reference codes on tracked items, a diagram or table only where it earns its place |
39
41
 
40
- All of them are on by default. This install built in {N_PACKS_ACTIVE}, carrying {N_DOCTRINE_RULES} rules between them. You choose packs at build time with `--doctrines`, or drop single rules with `--exclude-rules`; the how-to is in [Choose your setup](../guides/choose-your-setup.md).
42
+ All of them are on by default. This install built in {N_PACKS_ACTIVE}, carrying {N_DOCTRINE_RULES} rules between them. You choose packs at build time with `--doctrines`, or drop single rules with `--exclude-rules`; the how-to is in [Doctrine packs and single rules](../guides/setup-doctrines.md).
41
43
 
42
44
  A pack you leave out **still ships**: every pack file lands under `doctrines/` beside the instructions file whether or not it was built in. A rule that cites an inactive pack still resolves on disk, and you can read the alternatives before turning one on. An inactive pack loses its binding force, not its availability.
43
45
 
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  group: concepts
3
- order: 4
3
+ order: 5
4
4
  title: "Skills"
5
5
  kind: "concept"
6
+ section: "Harness"
7
+ description: "Written playbooks the agent follows for a repeatable task."
6
8
  link: {"hash": "#/section/skills", "label": "Browse the catalog →"}
7
9
  ---
8
10
  A **skill** is a repeatable workflow written as a markdown playbook: when it applies, the steps, and what "done" looks like. The agent reads the playbook before acting, so a task it has a skill for is done the same careful way every time instead of improvised.
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  group: concepts
3
- order: 12
3
+ order: 11
4
4
  title: "Themes"
5
5
  kind: "concept"
6
+ section: "Configuration"
7
+ description: "The agent's voice and the words the harness uses, never its structure."
6
8
  ---
7
9
  A **theme** changes the agent's *voice* and the words the harness uses for its own parts. It never changes structure: the same rules, in the same order, with the same files, folders and links, whatever theme you pick.
8
10