Merge pull request 'fix: docs: update BOOTSTRAP.md with multi-project setup lessons (#47)' (#64) from fix/issue-47 into main

This commit is contained in:
johba 2026-03-17 17:19:36 +01:00
commit 66e6095468

View file

@ -95,6 +95,12 @@ On Codeberg, set up branch protection for your primary branch:
This ensures dev-agent can't merge its own PRs — it must wait for review-agent (running as the bot account) to approve. This ensures dev-agent can't merge its own PRs — it must wait for review-agent (running as the bot account) to approve.
> **Common pitfall:** Approvals alone are not enough. You must also:
> 1. Add `review_bot` as a **write** collaborator on the repo (Settings → Collaborators)
> 2. Set both `approvals_whitelist_username` **and** `merge_whitelist_usernames` to include `review_bot` in the branch protection rule
>
> Without write access, the bot's approval is counted but the merge API returns HTTP 405.
### Required: Seed the `AGENTS.md` tree ### Required: Seed the `AGENTS.md` tree
The planner-agent maintains an `AGENTS.md` tree — architecture docs with The planner-agent maintains an `AGENTS.md` tree — architecture docs with
@ -149,6 +155,8 @@ Dev-agent checks that all referenced issues are closed (= merged) before startin
crontab -e crontab -e
``` ```
### Single project
Add (adjust paths): Add (adjust paths):
```cron ```cron
@ -158,10 +166,10 @@ FACTORY_ROOT=/home/you/disinto
0,10,20,30,40,50 * * * * $FACTORY_ROOT/supervisor/supervisor-poll.sh 0,10,20,30,40,50 * * * * $FACTORY_ROOT/supervisor/supervisor-poll.sh
# Review agent — find unreviewed PRs (every 10 min, offset +3) # Review agent — find unreviewed PRs (every 10 min, offset +3)
3,13,23,33,43,53 * * * * $FACTORY_ROOT/review/review-poll.sh 3,13,23,33,43,53 * * * * $FACTORY_ROOT/review/review-poll.sh $FACTORY_ROOT/projects/myproject.toml
# Dev agent — find ready issues, implement (every 10 min, offset +6) # Dev agent — find ready issues, implement (every 10 min, offset +6)
6,16,26,36,46,56 * * * * $FACTORY_ROOT/dev/dev-poll.sh 6,16,26,36,46,56 * * * * $FACTORY_ROOT/dev/dev-poll.sh $FACTORY_ROOT/projects/myproject.toml
# Gardener — backlog grooming (daily) # Gardener — backlog grooming (daily)
15 8 * * * $FACTORY_ROOT/gardener/gardener-poll.sh 15 8 * * * $FACTORY_ROOT/gardener/gardener-poll.sh
@ -170,7 +178,35 @@ FACTORY_ROOT=/home/you/disinto
0 9 * * 1 $FACTORY_ROOT/planner/planner-poll.sh 0 9 * * 1 $FACTORY_ROOT/planner/planner-poll.sh
``` ```
The 3-minute offsets prevent agents from competing for resources. `review-poll.sh`, `dev-poll.sh`, and `gardener-poll.sh` all take a project TOML file as their first argument.
### Multiple projects
Stagger each project's polls so they don't overlap. With the example below, cross-project gaps are 2 minutes:
```cron
FACTORY_ROOT=/home/you/disinto
# Supervisor (shared)
0,10,20,30,40,50 * * * * $FACTORY_ROOT/supervisor/supervisor-poll.sh
# Project A — review +3, dev +6
3,13,23,33,43,53 * * * * $FACTORY_ROOT/review/review-poll.sh $FACTORY_ROOT/projects/project-a.toml
6,16,26,36,46,56 * * * * $FACTORY_ROOT/dev/dev-poll.sh $FACTORY_ROOT/projects/project-a.toml
# Project B — review +8, dev +1 (2-min gap from project A)
8,18,28,38,48,58 * * * * $FACTORY_ROOT/review/review-poll.sh $FACTORY_ROOT/projects/project-b.toml
1,11,21,31,41,51 * * * * $FACTORY_ROOT/dev/dev-poll.sh $FACTORY_ROOT/projects/project-b.toml
# Gardener — per-project backlog grooming (daily)
15 8 * * * $FACTORY_ROOT/gardener/gardener-poll.sh $FACTORY_ROOT/projects/project-a.toml
45 8 * * * $FACTORY_ROOT/gardener/gardener-poll.sh $FACTORY_ROOT/projects/project-b.toml
# Planner — AGENTS.md maintenance + gap analysis (weekly)
0 9 * * 1 $FACTORY_ROOT/planner/planner-poll.sh
```
The staggered offsets prevent agents from competing for resources. Each project gets its own lock file (`/tmp/dev-agent-{name}.lock`) derived from the `name` field in its TOML, so concurrent runs across projects are safe.
## 5. Verify ## 5. Verify
@ -205,6 +241,26 @@ If you want real-time notifications and human-in-the-loop escalation:
``` ```
3. The supervisor and gardener will post status updates and escalation threads to the configured room. Reply in-thread to answer escalations. 3. The supervisor and gardener will post status updates and escalation threads to the configured room. Reply in-thread to answer escalations.
### Per-project Matrix setup
Each project can post to its own Matrix room. For each project:
1. **Create a Matrix room** and note its room ID (e.g. `!abc123:matrix.example.org`)
2. **Create a bot user** (or reuse one) and join it to the room
3. **Add the token** to `.env` using a project-prefixed name:
```bash
PROJECTNAME_MATRIX_TOKEN=syt_xxxxx
```
4. **Configure the TOML** with a `[matrix]` section:
```toml
[matrix]
room_id = "!abc123:matrix.example.org"
bot_user = "@projectname-bot:matrix.example.org"
token_env = "PROJECTNAME_MATRIX_TOKEN"
```
The `token_env` field points to the environment variable name, not the token value itself, so you can have multiple bots with separate credentials in a single `.env`.
## Lifecycle ## Lifecycle
Once running, the system operates autonomously: Once running, the system operates autonomously:
@ -234,3 +290,13 @@ Meanwhile:
| Claude not found | `which claude` — must be in PATH. Check `lib/env.sh` adds `~/.local/bin`. | | Claude not found | `which claude` — must be in PATH. Check `lib/env.sh` adds `~/.local/bin`. |
| Merge fails | Branch protection misconfigured? Review bot needs write access to the repo. | | Merge fails | Branch protection misconfigured? Review bot needs write access to the repo. |
| Memory issues | Supervisor auto-heals at <500 MB free. Check `supervisor/supervisor.log` for P0 alerts. | | Memory issues | Supervisor auto-heals at <500 MB free. Check `supervisor/supervisor.log` for P0 alerts. |
### Multi-project common blockers
| Symptom | Cause | Fix |
|---------|-------|-----|
| Dev-agent for project B never starts | Shared lock file path | Each TOML `name` field must be unique — lock is `/tmp/dev-agent-{name}.lock` |
| Review-poll skips all PRs | CI gate with no CI configured | Set `woodpecker_repo_id = 0` in the TOML `[ci]` section to bypass the CI check |
| Approved PRs never merge (HTTP 405) | `review_bot` not in merge/approvals whitelist | Add as write collaborator; set both `approvals_whitelist_username` and `merge_whitelist_usernames` in branch protection |
| Dev-agent churns through issues without waiting for open PRs to land | No single-threaded enforcement | `WAITING_PRS` check in dev-poll holds new work — verify TOML `name` is consistent across invocations |
| Label ping-pong (issue reopened then immediately re-closed) | `already_done` handler doesn't close issue | Review dev-agent log; `already_done` status should auto-close the issue |