Files
psf-memo/doc/plan-swarmforge-dir.md
T

98 lines
5.2 KiB
Markdown
Raw Normal View History

2026-08-26 09:10:39 -07:00
# Plan: Option B — `SWARMFORGE_DIR` (external machinery, per-project config)
> **Status**: pending implementation — working document to resume later.
> **Context**: came out of the trial run with `saas-prototype` (see the fork README).
> The goal is that projects do not carry SwarmForge code, only their configuration.
## 1. Goal
The project stops carrying SwarmForge **code** (scripts) and **shared rules**
(articles, default roles). It only keeps its **own configuration** (`swarmforge.conf` +
`project.prompt` + overrides). The fork (or any shared location via `SWARMFORGE_DIR`)
is the sole source of the machinery. With `SWARMFORGE_DIR` unset, **everything still works
as today** (full backward compatibility).
## 2. Design: where each thing lives
```
SWARMFORGE_DIR (base, e.g. ~/.local/share/swarmforge = fork clone)
├── swarm/ + swarmforge/scripts/ ← launcher, daemon, helpers, adapters
├── swarmforge/roles/*.prompt ← default roles
└── swarmforge/constitution/articles/ ← engineering, handoffs, workflow (shared)
PROJECT
└── swarmforge/ ← "thin": ONLY per-project material
├── swarmforge.conf ← project roles + models
└── constitution/articles/project.prompt (+ local-*.prompt, role overrides if any)
```
**Merge rule**: the project wins by name — if the project has
`roles/cleaner.prompt`, that takes precedence; otherwise the base one is used.
## 3. Code changes (file by file)
| File | Change | Why |
|---|---|---|
| `swarmforge.bb``context` | Add `:base-dir` = `(or (System/getenv "SWARMFORGE_DIR") (fs/path working-dir "swarmforge"))`; keep `:swarm-forge-dir` = `working-dir/swarmforge` (project config) | Shared base vs. per-project config |
| `swarmforge.bb``parse-config` | `roles-dir` = per-role lookup: `project/roles/<role>.prompt` if it exists, else `base/roles/<role>.prompt` | Role overrides |
| `swarmforge.bb` → new `sync-shared-config!` | For each worktree **and for master**: copy from `base` the shared articles and default roles into the destination `swarmforge/` **only if missing** (project ones win); scripts as today | The agent reads `swarmforge/constitution.prompt` relative to its cwd — after sync, the merged view is there |
| `swarmforge.bb``prepare-workspace!` / setup | When syncing on master (project root), add derived files (shared articles) to `.gitignore` so the project's git stays clean | Shared articles are generated at startup, not committed |
| `write-agent-instruction-file!` | **No changes** | Relative paths still work because sync merges the view into each worktree |
| `check-helper-scripts!` | **No changes** (validates `script-dir`, which points at the base) | — |
| `handoffd.bb`, helpers, adapters | **No changes** | Already resolve the project via git (`roles.tsv`) |
| `swarm` wrapper | Small install/docs tweak: when installed globally, it runs the base `swarmforge.sh`; the download block remains for first-time setup | Global install |
**Estimated total**: ~40-60 new/modified lines in `swarmforge.bb` + docs. Nothing else.
## 4. User setup (once)
```bash
# 1. Install the machinery once
git clone https://github.com/pablo-io/swarm-forge ~/.local/share/swarmforge
ln -s ~/.local/share/swarmforge/swarm ~/.local/bin/swarm
export SWARMFORGE_DIR=~/.local/share/swarmforge # (in your .bashrc)
# 2. In any project: create ONLY the config
mkdir -p swarmforge/constitution/articles
# swarmforge.conf + project.prompt (+ local-* / overrides if applicable)
# 3. Run
cd /my/project && swarm
```
## 5. Test plan
1. **`bb test`** — the existing suite (24 tests) must pass with no semantic changes.
2. **Mode B**: minimal project with only conf + `project.prompt` → launch with `SWARMFORGE_DIR`
→ verify: worktrees with the merged view (shared articles + roles + scripts),
functional master, clean startup.
3. **Handoff smoke**: a real end-to-end handoff (like the `saas-prototype` run)
under mode B.
4. **Backward compatibility**: `saas-prototype` (with full `swarmforge/`) without the env var →
must keep working the same.
5. **Sync**: change a script in the fork (e.g. a fix) → it is reflected without copying
anything into the project.
## 6. Optional migration of `saas-prototype` (after validating B)
- Thin its `swarmforge/`: delete `scripts/`, `roles/`, and shared articles; leave
`swarmforge.conf` + `project.prompt` (with the design rules).
- Re-copy updated prompts from the fork (`architect.prompt` with the written-report
rule) — now via the base, not manual copy.
## 7. Risks / open decisions
- **Shared articles synced onto master** will be gitignored (derived) — if someone wants
to version them explicitly, they can commit them (sync does not overwrite existing ones).
- **`roles.tsv` and state** stay under the project's `.swarmforge/` (gitignored) — unchanged.
- Agent instructions remain relative to the worktree — key to the design
(zero protocol changes).
## 8. Suggested implementation order
1. `context` + `parse-config` (base dir + role lookup)
2. `sync-shared-config!` + gitignore for derived files
3. `bb test`
4. Mode B trial with a minimal project
5. Doc in the fork README ("SWARMFORGE_DIR mode" section)