Handoff: promote the heartbeat decision and deploy-key gotcha to durable sections, prune Current state
Current state had grown into a running log of two adjudication cycles. The 2026-07-29 heartbeat drop is a decision, so it lives in Decisions with its reopen condition; the per-repo deploy-key requirement is a durable gotcha, so it sits with the Deploy command. What remains is present-tense status plus three ordered next steps: the orphaned-thread prune fix, triaging this repo's 3 inbox items, and the 2nd/3rd-repo poll-cycle check.
This commit is contained in:
@@ -45,6 +45,9 @@ flat JSON in a writable `state/` mount.
|
||||
**NVIDIA Sync** alias — host `spark-32d0`, user `modelo`, key-based; injected into `~/.ssh/config`
|
||||
via an `Include`. `modelo27`/`spark-27ea` is a second Spark on another LAN). `reset --hard` is safe:
|
||||
`.env`/`config.toml`/`state/` are gitignored.
|
||||
**Deploy-key gotcha:** each repo the Spark clones needs its *own* Gitea deploy key plus its own
|
||||
`Host` alias — Gitea refuses to reuse one SSH key across two repos' deploy keys, and the default
|
||||
`immense-voyage.local` block already carries matrix-bridge's key.
|
||||
- **Onboard a repo:** create a Matrix room named like the repo, invite this bot → it auto-joins,
|
||||
maps the room to `<owner>/<roomname>` (+ `~/Projects/<roomname>` on the Mac), and posts an
|
||||
onboarding message. Pick review agents in-chat: `agents +reviewer +security -adjudicator`.
|
||||
@@ -84,6 +87,13 @@ flat JSON in a writable `state/` mount.
|
||||
- **Reuse matrix-bridge's Mac wrappers + Spark→Mac SSH key** (don't duplicate the seam).
|
||||
- **Auto-map by name:** room `<x>` → Gitea `<owner>/<x>` + `~/Projects/<x>`; mapping persists to
|
||||
`state/` (mirrors matrix-bridge D14). One room per repo.
|
||||
- **No wedge-detection heartbeat** (adjudicated 2026-07-29). A healthcheck badge restarts nothing
|
||||
under this compose setup, the tile that would show it lives in spark-control (so it's a two-repo
|
||||
change), and serial per-room polling with a 10-min review budget makes any staleness threshold
|
||||
either too loose to be timely or noisy mid-review. Reopens only on an *observed* wedge **plus**
|
||||
confirmation the spark-control tile already renders Docker health. The cheaper half of the same
|
||||
goal is the ROADMAP fold-in: bound the unbounded awaits and die if the poll task dies, so
|
||||
`restart: unless-stopped` handles it.
|
||||
|
||||
## Sovereignty
|
||||
|
||||
@@ -93,36 +103,21 @@ revisit this — local inference via Spark Control would be the path.
|
||||
|
||||
## Current state
|
||||
|
||||
**LIVE and proven.** Bot runs on the Spark (`docker compose up -d`), `@reviewer` maps each review room
|
||||
to its repo, and the subagent panel is configured in-chat. Proven end-to-end on **ten31-site PR #4**
|
||||
(2026-06-28): threaded review → `merge` + `yes` → force_merge → auto-publish → thread redacted — and
|
||||
the previously-unproven bit, **headless `claude -p` spawning the reviewer/adjudicator/security
|
||||
subagents, works**. The ten31-site colleague is onboarded; the pipeline is in steady use.
|
||||
**LIVE and in steady use.** The bot runs on the Spark, maps each review room to its repo, and is proven
|
||||
end-to-end on **ten31-site PR #4** (2026-06-28): threaded review → `merge` + `yes` → force_merge →
|
||||
auto-publish → thread redacted, with headless `claude -p` genuinely spawning the reviewer / adjudicator /
|
||||
security subagents. ten31-site is the only repo onboarded so far.
|
||||
|
||||
Deployed to the Spark at `063e694`: a merge always redacts its thread on success, and a failed
|
||||
post-merge deploy posts its "deploy manually" warning at top level so it survives the redaction
|
||||
instead of orphaning the thread. `clear`/`resolve` redacts an orphaned thread without touching the PR.
|
||||
Running on the Spark at `063e694` (a merge always redacts its thread; a failed post-merge deploy warns at
|
||||
top level rather than orphaning one; `clear`/`resolve` clears an orphan without touching the PR). `master`
|
||||
is only docs ahead of that, so **no redeploy is pending**. No test suite: verification means exercising
|
||||
the bot in a real review room.
|
||||
|
||||
**Deploy gotcha (still true):** the Spark needs a *dedicated* per-repo Gitea deploy key + a `Host`
|
||||
alias (the default `immense-voyage.local` block uses matrix-bridge's key); Gitea won't reuse one SSH
|
||||
key across repos' deploy keys. Redeploy via the Spark Control tile, or `ssh modelo32`.
|
||||
|
||||
**Known issue / next fix (the concrete next step):** the poll loop prunes a PR's thread root from
|
||||
state when it leaves the open list (`src/bot.py` ~L594) *without redacting*, so a PR merged or closed
|
||||
**outside** the bot (the Gitea web UI) still orphans its thread, un-redactable by the bot afterward.
|
||||
The merge-redact fix covers bot-driven merges only; the prune should redact before dropping the root.
|
||||
|
||||
**Backlog adjudicated 2026-07-18** (`9adcdc8`): ROADMAP is down to one phase. Phase 2 (subagent panel,
|
||||
`agents +/-`) deleted as finished; Phase 4 deleted because spark-control has shipped this bot's tile
|
||||
since v0.28.0; deploy-on-a-non-static-repo dropped (no repo needs it, and the deploy step is hardcoded
|
||||
to the static-site publish script, so a per-repo deploy-command field would have to come first).
|
||||
That left two items: onboard 3 repos, and a wedged-loop heartbeat.
|
||||
|
||||
**Backlog adjudicated 2026-07-29:** the heartbeat is **dropped** — a healthcheck badge doesn't restart
|
||||
anything here, spark-control's tile would need its own change to read it, and serial per-room polling
|
||||
(a review may run 10 min) makes any staleness threshold either too loose to be timely or noisy
|
||||
mid-review; no wedge has ever been observed. Reopens only on an *observed* wedge **plus** confirmation
|
||||
the tile already renders Docker health. In its place ROADMAP carries a **fold-in**: bound the two
|
||||
unbounded awaits in `src/bot.py` (`await proc.wait()` after the timeout kill in `ssh_run`;
|
||||
`client.room_send` in `say()`) and stop the process if the poll task ever dies, so
|
||||
`restart: unless-stopped` + the tile cover it. Phase 3's onboard-3-repos verify item stands.
|
||||
**Next steps, in priority order:**
|
||||
1. **Fix the orphaned-thread prune** (`src/bot.py` ~L594): the poll loop drops a PR's thread root from
|
||||
state when the PR leaves the open list *without redacting*, so a PR merged or closed in the Gitea web
|
||||
UI strands its thread and `clear` can no longer reach it. Redact before dropping the root.
|
||||
2. **`/triage` the 3 untriaged inbox items** tagged for this repo — adjudication never reads the inbox, so
|
||||
their content is still unknown here.
|
||||
3. Onboard a 2nd/3rd repo, then watch one poll cycle (`docker compose logs -f`) for a long review
|
||||
head-of-line-blocking the next room — ROADMAP Phase 3's verify item, and the real scaling limit.
|
||||
|
||||
Reference in New Issue
Block a user