3.2 KiB
3.2 KiB
TASK: MOPAC self-host core — harness loop replaces the bash stack
Context
Charles (2026-08-28 ~21:30): "get to be self hosting asap — smallest core
that can bootstrap itself (redmine/gitea interaction fine, discourse later)"
and "moving away from the brittle _crossfeed setup and doorbell PMO<->work
channel". The MVP bar is already met (harness once --demo live, REPORT in
reports/). This turn makes the harness drive ITSELF: Redmine is the SoR,
the conductor is the worker, no bash middle layer.
What dies (list explicitly in REPORT, do not delete yet)
/home/_crossfeed/tooling/agent-stack/semaphore.sh+ slot-file cap (replaced by in-process concurrency limit)~/.coordinate/scripts/queue-next.sh,queue-after.sh,pmo-heartbeat.sh(replaced by the loop + its own wake discipline)- dispatch-turn.sh doorbell
screen -S reachableceo-PMO -X stuff— note: this doorbell is ALREADY dead (screen is named RCEO-PMO, message silently dropped). Mention in REPORT; deletion happens after Charles signs off.
Scope — smallest self-bootstrapping core
harness loopsubcommand (Go, stdlib only, chainable withonce):- Poll Redmine intake (existing
/issues.jsonquery) on interval (config, default 120s).--onceflag = single scan (cron-able). - For each new/updated task issue not yet processed: run the bounded turn (existing conductor), then write REPORT back (existing Redmine note writeback — currently stubbed; implement the note POST) and update issue status per config map (e.g. In Progress -> Done).
- State: append-only JSONL (one event per dispatch/report), dedup by issue id + updated_on. No _crossfeed paths, no slot files.
- v0 = SEQUENTIAL turns (one at a time). Concurrency knob can come later.
- Gitea: optional REPORT commit step behind config flag (off by default). Discourse: out of scope.
- Poll Redmine intake (existing
- Credentials: harness.toml
key_refgainsmpk:scheme → POST to keyproxy/v1/resolve(see ukrrs/mopac-keyproxy, built tonight).env:/file:refs keep working as fallback, so the loop runs with or without keyproxy up. Do not hardcode hosts — all in harness.toml. harness loopsupervises ITS OWN turns; PMO (me) verifies REPORTs and archives. The loop logs one line per action to stdout + JSONL.
Build discipline
- ALL DEV IN DOCKER: digest-pinned golang:1.26 builder, bind-mounted repo, Makefile build/vet/test through docker run. No host Go toolchain.
- Docs standard applies (README status table + config reference update).
- Tests: loop end-to-end against a fake Redmine HTTP server (pattern exists in internal/loop tests) — dispatch, dedup, writeback, status map.
Deliverables
- Commits + push to ukrrs/MOPAC main.
REPORT-20260828-2131-selfhost-core.mdin~/.coordinate/inbox-pmo/: what runs, exact command to start the loop, what it replaces (the die list), how to roll back (just stop the loop, bash stack still present).
Added by PMO (21:30, post docs-turn rot finding)
- Rename Go module path
reachableceo/...->ukrrs.com/mopac/...or similar (go.mod module line + all internal imports). Mechanical, verify with build+vet+test in the Docker builder. Cited as doc rot in docs-standards REPORT; folding here since it is a source change.