Overview
Bundles phase 1. The dashboard's auto-bundler (PyAutoBrain#309) groups on Target: — a mechanical key, so proposals read as "three things that live in autoarray" rather than "three things about MGE". This adds a Themes: keyword list to the prompt header and re-keys auto-bundling on the primary theme (cross-repo), with the remaining keywords as packing affinity. Follow-up to complete/2026/08/dashboard-bundles.md; phase 2 (nightly Claude theme-fill + proposed bundles) is filed separately and blocked on this.
Plan
- Add the optional
Themes: list header (same form as Repos:) with a small controlled vocabulary in PyAutoMind/REFERENCE.md; intake assigns it at formalisation.
- Re-key
auto_bundles(): first bullet = primary theme = grouping key (each prompt in ≤1 bundle); remaining bullets = Jaccard affinity for packing inside a pool; Target stays the fallback key for un-themed prompts. Card title = primary theme (+ shared secondaries); members show their repo. Unknown keywords warn ⚠️ like unknown epic/bundle slugs.
- One-off Opus backfill sweep writes
Themes: (1–3 keywords, primary first) on the ~132 draft/ prompts where clear — one reviewable diff, never overwriting an existing value.
- Tests: primary grouping, affinity packing, cross-repo members, fallback-to-Target, unknown-keyword warning, and the no-themes fixture rendering identically to today.
- Regenerate the dashboard; nightly needs no change.
Detailed implementation plan
Affected Repositories
- PyAutoBrain (primary)
- PyAutoMind
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./PyAutoBrain |
main |
clean |
| ./PyAutoMind |
main |
clean |
Suggested branch: feature/bundle-themes
Implementation Steps
PyAutoBrain/agents/conductors/intake/_intake.py
- Parse
Themes: as a list (reuse the Repos: list parsing); census records carry themes: list[str].
THEME_VOCAB loaded from PyAutoMind/REFERENCE.md (or a small themes.md/YAML — pick whichever the Mind conventions favour; the vocabulary must be human-editable without touching Brain). Unknown keyword → ⚠️ on the card and a hygiene count.
auto_bundles(): pool by primary theme when present, else by Target (fallback pools are labelled as today). Within a pool, greedy packing by affinity: seed with the highest-priority member, add the candidate with the highest Jaccard overlap of full theme lists (ties: priority, Target, path) until the existing cap (8 pts, ≤4 members, ≤1 large) is hit; min 2. All existing exclusions unchanged. Slug auto-<theme>-<n>; title <theme> + shared secondaries; members table gains a Repo column.
- Intake formalise step: prompt for / assign
Themes: (keep it optional — never block formalisation on it).
PyAutoMind/REFERENCE.md: Themes: in the header docs + the vocabulary table (seed: epic slugs + mge, point-source, jax-compile, jax-gradient, ci-smoke, dashboard, assistants, cti, interferometer, cluster, samplers, docs-hub, …).
- Backfill sweep (separate subagent, separate commit): read each
draft/**/*.md, insert Themes: after Repos: (or after Target:) only where absent and clear; leave unclear prompts untouched; report a table of path → keywords for review.
- Tests in
PyAutoBrain/tests/test_intake_dashboard.py.
- Regenerate
dashboard.md/html; --check clean.
Key Files
PyAutoBrain/agents/conductors/intake/_intake.py — parse_bundles, auto_bundles, bundle_cards, renderers
PyAutoBrain/tests/test_intake_dashboard.py
PyAutoMind/REFERENCE.md, PyAutoMind/draft/**
Original Prompt
Click to expand starting prompt
Bundles phase 1 — Themes: keyword list and theme-keyed (cross-repo) auto-bundling
Type: feature
Target: PyAutoMind
Repos:
- PyAutoMind
- PyAutoBrain
Difficulty: medium
Autonomy: supervised
Priority: high
Status: formalised
Filed: 2026-08-27
Original request (verbatim)
what is the premise of grouping?, they feel a bit random but I guess its hard
to know how to group really. it feels like they are grouped on the source code
library rather than the task and its scientific context, where the latter
would generally be more cross repo
i think we want 1 and 2?
could even be multiple key words in bullet points to help more?
Context
The Bundles section shipped 2026-08-27 (record
complete/2026/08/dashboard-bundles.md, PyAutoBrain#309). Its auto-bundler
groups on Target: only — a mechanical key (one worktree per repo), not a
topical one — so proposals read as "three things that live in autoarray", not
"three things about MGE". The useful grouping is scientific/topical and is
routinely cross-repo; the start_bundle contract already allows that (one
shared worktree per repo, parallel across repos).
Scope
-
Themes: header — optional light-header key in the same list form as
Repos::
Themes:
- mge
- jax-gradient
- interferometer
Small, controlled, human-editable vocabulary documented in REFERENCE.md
(seed from the epic slugs and the obvious clusters: mge, point-source,
jax-compile, jax-gradient, ci-smoke, dashboard, assistants,
cti, …). Unknown keywords render a ⚠️ like unknown epic/bundle slugs so
the list never rots into free-text tags. Intake assigns them at
formalisation going forward (_intake.py formalise step).
-
Renderer (PyAutoBrain/agents/conductors/intake/_intake.py
auto_bundles) — deterministic, keyed on themes, cross-repo allowed:
- first bullet = primary theme = the grouping key; every prompt lands in
at most one auto bundle (no duplicates across cards);
- remaining bullets = affinity: within a primary-theme pool, packing
prefers members with the highest keyword overlap (Jaccard over the whole
list), so a large pool splits by what the work is about rather than by
filename order; ties broken by priority, then Target, then path;
Target remains the fallback grouping key for prompts with no themes;
- keep every existing exclusion, the size cap, min 2, the top-8 display and
pinned/auto ordering. Card title = primary theme (+ the shared secondary
keywords, if any); members show their repo.
-
One-off backfill — an Opus sweep reads each of the ~132 draft/ prompts
and writes a Themes: list where clear (1–3 keywords, primary first; leave
absent when unclear); reviewable as a single diff, committed by the human.
Never overwrite an existing value.
-
Tests for primary-theme grouping, affinity-driven packing, cross-repo
members, fallback-to-Target, unknown-keyword warning, and that the existing
Target-only fixture still renders identically when no prompt carries themes.
Deferred to phase 2 (bundle_nightly_claude_pass.md): assigning theme lists to
new drafts automatically and Claude-proposed cross-theme bundles — the
affinity keywords are exactly the signal that pass uses.
Overview
Bundles phase 1. The dashboard's auto-bundler (PyAutoBrain#309) groups on
Target:— a mechanical key, so proposals read as "three things that live in autoarray" rather than "three things about MGE". This adds aThemes:keyword list to the prompt header and re-keys auto-bundling on the primary theme (cross-repo), with the remaining keywords as packing affinity. Follow-up tocomplete/2026/08/dashboard-bundles.md; phase 2 (nightly Claude theme-fill + proposed bundles) is filed separately and blocked on this.Plan
Themes:list header (same form asRepos:) with a small controlled vocabulary inPyAutoMind/REFERENCE.md; intake assigns it at formalisation.auto_bundles(): first bullet = primary theme = grouping key (each prompt in ≤1 bundle); remaining bullets = Jaccard affinity for packing inside a pool;Targetstays the fallback key for un-themed prompts. Card title = primary theme (+ shared secondaries); members show their repo. Unknown keywords warnThemes:(1–3 keywords, primary first) on the ~132draft/prompts where clear — one reviewable diff, never overwriting an existing value.Detailed implementation plan
Affected Repositories
Branch Survey
Suggested branch:
feature/bundle-themesImplementation Steps
PyAutoBrain/agents/conductors/intake/_intake.pyThemes:as a list (reuse theRepos:list parsing); census records carrythemes: list[str].THEME_VOCABloaded fromPyAutoMind/REFERENCE.md(or a smallthemes.md/YAML — pick whichever the Mind conventions favour; the vocabulary must be human-editable without touching Brain). Unknown keyword →auto_bundles(): pool by primary theme when present, else byTarget(fallback pools are labelled as today). Within a pool, greedy packing by affinity: seed with the highest-priority member, add the candidate with the highest Jaccard overlap of full theme lists (ties: priority, Target, path) until the existing cap (8 pts, ≤4 members, ≤1 large) is hit; min 2. All existing exclusions unchanged. Slugauto-<theme>-<n>; title<theme>+ shared secondaries; members table gains a Repo column.Themes:(keep it optional — never block formalisation on it).PyAutoMind/REFERENCE.md:Themes:in the header docs + the vocabulary table (seed: epic slugs +mge,point-source,jax-compile,jax-gradient,ci-smoke,dashboard,assistants,cti,interferometer,cluster,samplers,docs-hub, …).draft/**/*.md, insertThemes:afterRepos:(or afterTarget:) only where absent and clear; leave unclear prompts untouched; report a table of path → keywords for review.PyAutoBrain/tests/test_intake_dashboard.py.dashboard.md/html;--checkclean.Key Files
PyAutoBrain/agents/conductors/intake/_intake.py—parse_bundles,auto_bundles,bundle_cards, renderersPyAutoBrain/tests/test_intake_dashboard.pyPyAutoMind/REFERENCE.md,PyAutoMind/draft/**Original Prompt
Click to expand starting prompt
Bundles phase 1 —
Themes:keyword list and theme-keyed (cross-repo) auto-bundlingType: feature
Target: PyAutoMind
Repos:
Difficulty: medium
Autonomy: supervised
Priority: high
Status: formalised
Filed: 2026-08-27
Original request (verbatim)
Context
The Bundles section shipped 2026-08-27 (record
complete/2026/08/dashboard-bundles.md, PyAutoBrain#309). Its auto-bundlergroups on
Target:only — a mechanical key (one worktree per repo), not atopical one — so proposals read as "three things that live in autoarray", not
"three things about MGE". The useful grouping is scientific/topical and is
routinely cross-repo; the
start_bundlecontract already allows that (oneshared worktree per repo, parallel across repos).
Scope
Themes:header — optional light-header key in the same list form asRepos::Small, controlled, human-editable vocabulary documented in
⚠️ like unknown epic/bundle slugs so
REFERENCE.md(seed from the epic slugs and the obvious clusters:
mge,point-source,jax-compile,jax-gradient,ci-smoke,dashboard,assistants,cti, …). Unknown keywords render athe list never rots into free-text tags. Intake assigns them at
formalisation going forward (
_intake.pyformalise step).Renderer (
PyAutoBrain/agents/conductors/intake/_intake.pyauto_bundles) — deterministic, keyed on themes, cross-repo allowed:at most one auto bundle (no duplicates across cards);
prefers members with the highest keyword overlap (Jaccard over the whole
list), so a large pool splits by what the work is about rather than by
filename order; ties broken by priority, then
Target, then path;Targetremains the fallback grouping key for prompts with no themes;pinned/auto ordering. Card title = primary theme (+ the shared secondary
keywords, if any); members show their repo.
One-off backfill — an Opus sweep reads each of the ~132
draft/promptsand writes a
Themes:list where clear (1–3 keywords, primary first; leaveabsent when unclear); reviewable as a single diff, committed by the human.
Never overwrite an existing value.
Tests for primary-theme grouping, affinity-driven packing, cross-repo
members, fallback-to-Target, unknown-keyword warning, and that the existing
Target-only fixture still renders identically when no prompt carries themes.
Deferred to phase 2 (
bundle_nightly_claude_pass.md): assigning theme lists tonew drafts automatically and Claude-proposed cross-theme bundles — the
affinity keywords are exactly the signal that pass uses.