diff --git a/AGENTS.md b/AGENTS.md
index 002aeaf4..01ec04b6 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -44,7 +44,9 @@ For the full workflow narrative, conventions, and registry schemas, read
- **Registry** — root-level markdown files, each with one job: `active.md`
(in-flight tasks), `planned.md` (scoped, not started), `parked.md` (started
but not in flight), `condemned.md` (self-material staged for the Gut's
- transit-and-void lifecycle — see PyAutoGut), `queue.md` (ordered
+ transit-and-void lifecycle — see PyAutoGut), `epics.md` (long-running
+ multi-phase programmes and the ledger file that holds each one's state),
+ `queue.md` (ordered
input for `register_and_iterate --queue`), `ideas.md` (raw inbox swept by
`$intake`, `/intake` in Claude). Mutate these only via the skills in `skills/` so commit
messages stay consistent.
diff --git a/README.md b/README.md
index 451f0b4d..2deba3d2 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,8 @@ can follow every stage in this repository:
— the permanent ledger of everything the organism has shipped.
Alongside the lifecycle folders, the root holds the live registry:
-[`active.md`](active.md) (in flight), [`planned.md`](planned.md) (scoped, not
+[`active.md`](active.md) (in flight), [`epics.md`](epics.md) (long-running
+multi-phase programmes), [`planned.md`](planned.md) (scoped, not
started), [`parked.md`](parked.md) (paused), [`ideas.md`](ideas.md) (raw
inbox), and [`repos.yaml`](repos.yaml) — the body map naming every repository
the Mind can direct.
diff --git a/dashboard.html b/dashboard.html
index 872d7903..25be4feb 100644
--- a/dashboard.html
+++ b/dashboard.html
@@ -59,18 +59,23 @@
Quick wins (small enough, and safe enough to run unatte
Long-running multi-phase programmes — 📋 copies a prompt that works out where the epic stands from its ledger and continues it from the next logical point.
149 filed prompts, not started — sorted most-pickable first (priority, then size).
bug — 36
diff --git a/dashboard.md b/dashboard.md
index fc228e2e..80020b66 100644
--- a/dashboard.md
+++ b/dashboard.md
@@ -183,6 +183,34 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
+## Epics
+
+Long-running multi-phase programmes. Each 📋 prompt has Claude read the epic's ledger, work out where it stands, and continue from the next logical point — no hunting for the paired issue. Full record in [`epics.md`](epics.md).
+
+📋 JAX profiling — inference programme — ledger: `autolens_profiling/results/notes/inference/PROGRAMME.md`
+
+```
+Continue the 'JAX profiling — inference programme' epic. Its canonical state lives in autolens_profiling/results/notes/inference/PROGRAMME.md — read that ledger (and any DECISIONS/RESULTS files beside it) first. Cross-check this epic's entry in PyAutoMind/epics.md, any related rows in PyAutoMind/active.md, and the referenced repos' open issues and PRs, to work out the last completed phase and what is currently in flight. Then pick the next logical step and continue it through the normal workflow (/start_dev — filing the phase's prompt first if none exists), updating the ledger as the work advances. Note: DECISIONS.md (append-only gate log) and phase__*/RESULTS.md sit beside the ledger; slices ship as autolens_profiling issues/PRs, not Mind prompts.
+```
+
+
+
+📋 Cluster strong lensing — Source & Cluster arc — ledger: `draft/feature/autolens/source_cluster_arc.md`
+
+```
+Continue the 'Cluster strong lensing — Source & Cluster arc' epic. Its canonical state lives in draft/feature/autolens/source_cluster_arc.md — read that ledger (and any DECISIONS/RESULTS files beside it) first. Cross-check this epic's entry in PyAutoMind/epics.md, any related rows in PyAutoMind/active.md, and the referenced repos' open issues and PRs, to work out the last completed phase and what is currently in flight. Then pick the next logical step and continue it through the normal workflow (/start_dev — filing the phase's prompt first if none exists), updating the ledger as the work advances. Note: 12 phased prompts under draft/; issue phases ONE at a time as predecessors near shipping — no bulk issue queues.
+```
+
+
+
+📋 Expectation propagation (EP) campaign — ledger: `draft/research/graphical_ep/ep_campaign.md`
+
+```
+Continue the 'Expectation propagation (EP) campaign' epic. Its canonical state lives in draft/research/graphical_ep/ep_campaign.md — read that ledger (and any DECISIONS/RESULTS files beside it) first. Cross-check this epic's entry in PyAutoMind/epics.md, any related rows in PyAutoMind/active.md, and the referenced repos' open issues and PRs, to work out the last completed phase and what is currently in flight. Then pick the next logical step and continue it through the normal workflow (/start_dev — filing the phase's prompt first if none exists), updating the ledger as the work advances. Note: umbrella phase map — each phase's real content lives in its own prompt under draft/research/graphical_ep/; the campaign file itself is never issued.
+```
+
+
+
## Parked
Started or scoped, not currently in flight — resume by moving the row back to `active.md`. Full detail in [`parked.md`](parked.md).
diff --git a/epics.md b/epics.md
new file mode 100644
index 00000000..31983538
--- /dev/null
+++ b/epics.md
@@ -0,0 +1,28 @@
+# Epics
+
+Long-running multi-phase programmes — work that is bigger than any one task
+and outlives any single issue. Each entry names the epic's canonical
+**ledger**: the file that holds its phase/gate state, wherever it lives. The
+dashboard renders these under In flight with a one-tap resume prompt that
+works out where the epic stands from its ledger and continues it from the
+next logical point — nobody should have to hunt for the issue that pairs
+with an epic's current phase.
+
+Schema per entry: `## ` then `- title:` / `- ledger:` / `- notes:`
+(and optionally `- status:` for a coarse, durable state — never per-phase
+detail, which belongs in the ledger).
+
+## jax-inference-profiling
+- title: JAX profiling — inference programme
+- ledger: autolens_profiling/results/notes/inference/PROGRAMME.md
+- notes: DECISIONS.md (append-only gate log) and phase__*/RESULTS.md sit beside the ledger; slices ship as autolens_profiling issues/PRs, not Mind prompts.
+
+## cluster-strong-lensing
+- title: Cluster strong lensing — Source & Cluster arc
+- ledger: draft/feature/autolens/source_cluster_arc.md
+- notes: 12 phased prompts under draft/; issue phases ONE at a time as predecessors near shipping — no bulk issue queues.
+
+## graphical-ep
+- title: Expectation propagation (EP) campaign
+- ledger: draft/research/graphical_ep/ep_campaign.md
+- notes: umbrella phase map — each phase's real content lives in its own prompt under draft/research/graphical_ep/; the campaign file itself is never issued.
diff --git a/scripts/spawn.py b/scripts/spawn.py
index 7d404d9a..d992d584 100644
--- a/scripts/spawn.py
+++ b/scripts/spawn.py
@@ -79,7 +79,7 @@
# there, and the Mind's root stays the task ledger.
(".github/AI_POLICY.md", "KEEP_SUB"), (".github/CONTRIBUTING.md", "KEEP_SUB"),
("repos.yaml", "SPECIAL:body_map"),
- ("active.md", "EMPTY"), ("planned.md", "EMPTY"),
+ ("active.md", "EMPTY"), ("planned.md", "EMPTY"), ("epics.md", "EMPTY"),
("parked.md", "EMPTY"), ("condemned.md", "EMPTY"), ("ideas.md", "EMPTY"), ("queue.md", "EMPTY"),
("autonomy_log.md", "SPECIAL:autonomy_log"),
# Prompt-file lifecycle (issue #71): draft/ (not-started) -> active/
@@ -193,8 +193,9 @@
# SHARES a name (e.g. Memory's `bibliography/active.md`, caught by the broad
# `bibliography/*` EMPTY rule) does not silently inherit a root file's title.
EMPTY_TITLES = {
- "dashboard.md": "# PyAutoMind task dashboard",
+ "dashboard.md": "# PyAutoMind Dashboard",
"active.md": "# Active Tasks",
+ "epics.md": "# Epics",
"planned.md": "# Planned",
"parked.md": "# Parked tasks",
"condemned.md": "# Condemned material",