Consolidate to single harness: pin regressions, icebox cmd/routing, confirm hyperguild-alone is sufficient #75

Open
opened 2026-07-01 11:12:37 +00:00 by mathias · 2 comments
Owner

Context

Mathias decided: consolidate to one harness (icebox agentsquad + Crush; see infra#170/#171-era loop-economics work). hyperguild is the harness — it's the only one with demonstrated loop-1 closure (infra#170, PR #16/#17) and already carries the two invariants that must survive: brain (vault/intellectual capital) and Gitea (audit trail). GitOps/OIDC stays the ops platform for everything built (.gitea/workflows/cd.yml already exists).

This issue is analysis-informed, not a guess. Read before executing:

What's already true (verified by reading the repo, not assumed)

  • cmd/hyperguild (tier probe, brain query/write, .mcp.json mode bootstrap) has zero import of internal/routing. It is already minimal and already separate.
  • Live .mcp.json (what an actual Claude Code session connects to) wires only brain-mcp. No routing pod, no gitea-mcp even listed here. This is exactly the config the infra#170 loop-1 experiment ran under — routing/brain-injection-machinery off, and it closed twice.
  • cmd/routing is a separate binary bundling two different things:
    1. internal/routing (Router/Fetcher/Policy/pass-rate) — the broken part. infra#174 found this signal is survivorship-biased and unusable for routing as-is.
    2. An MCP server hosting review/debug/retrospective/trainer as tools + project_create (Gitea project scaffolding), via internal/skills/{review,debug,retrospective,trainer,project}. Every one of these skill calls is wrapped through the broken router (wrap(skillName) in cmd/routing/main.go) — so today they are not independently usable; they're entangled with the broken part.
  • cmd/supervisor does not exist in the current tree. A comment in cmd/routing/main.go references "Plan 7 (supervisor retirement)" as a completed prior migration — historical, not a live constraint. No fourth binary to reconcile.
  • Both cmd/hyperguild and ingestion/ have extensive existing _test.go coverage (nearly 1:1 file-to-test ratio) — this is real, not something to build from scratch.

The conclusion this analysis supports

The live minimal harness already exists: cmd/hyperguild + brain-mcp + gitea-mcp (external, not in .mcp.json today but available). This is what ran the loop-1 experiment. cmd/routing in its entirety — including the skill-as-MCP-tool wiring — is dormant from the live session's perspective and entangled with the broken pass-rate signal. The clean move is not surgical extraction; it's confirm cmd/hyperguild is sufficient → icebox cmd/routing whole → keep ingestion/ (brain vault machinery, separately verify) → pin regression tests before and after so nothing that's actually used breaks.

Do (in order — each gates the next)

  1. Pin the regression baseline. Run the full existing test suite for both modules (cmd/hyperguild root module + ingestion/ submodule — separate go.mods) and record green. This is the safety net; nothing proceeds past this until it's green and captured.
  2. Confirm the cut boundary holds in code, not just by inspection. Verify (e.g. go list -deps or equivalent) that cmd/hyperguild genuinely has no transitive dependency on internal/routing or cmd/routing's packages. If it does, STOP and report — the analysis above is wrong somewhere and the plan needs revisiting before any deletion.
  3. Icebox cmd/routing in full, plus internal/routing, internal/tier (if solely routing-consumed — verify first), and internal/skills/{review,debug,retrospective,trainer,project} (verify these have no OTHER consumer before deleting — cmd/hyperguild doesn't use them per step 2, but double-check nothing else does). "Icebox" = move to a clearly-marked branch/tag or an icebox/ archive path, not git rm with no trace — this must be recoverable, not destroyed, per Mathias's "put it in an icebox" framing.
  4. Keep and verify ingestion/ (brain vault: capture, embed, vectorstore, graph, wiki, Gitea client) — this is the durable-capital invariant. Confirm its test suite is independently green (it doesn't depend on cmd/routing either, per the tree, but verify).
  5. Re-run the full regression baseline from step 1. Everything that passed before must still pass (minus the tests that were deleted with cmd/routing itself — those disappearing is expected, not a regression).
  6. Live smoke test (ground-truth, not just unit tests — same discipline as infra#170's M5 verification): actually run hyperguild brain query <q> and hyperguild mode <name> against real brain-mcp, confirm they work. Unit tests don't prove live wiring.
  7. Update .mcp.json / docs if needed to reflect gitea-mcp as an available (not required-but-absent) connection, since Gitea-as-audit-trail is an explicit invariant going forward.

Explicitly out of scope

  • Fixing internal/routing's survivorship bias (that's infra#174, separately gated — routing pod stays iceboxed regardless of #174's outcome, per Mathias: fresh start, not a resurrection plan).
  • Porting agentsquad's peer-to-peer/multi-agent capability into hyperguild — explicitly dropped, not carried forward (icebox, no resurrection commitment).
  • Deleting Crush or agentsquad repos themselves — out of scope for this ticket (may be separate cleanup issues).
  • Any new feature work. This is subtraction + verification only.

Acceptance Criteria

  • Step 1 baseline captured (test output saved/linked, both modules green)
  • Step 2 dependency check confirms zero coupling from cmd/hyperguild into routing-only packages (or: coupling found, reported, plan revised before proceeding)
  • cmd/routing + broken-router-entangled skill packages iceboxed (recoverable, not destroyed)
  • ingestion/ (brain vault) confirmed independently green
  • Full regression re-run green (step 5), diffed against step 1 baseline — only expected deletions missing, nothing else
  • Live smoke test (step 6) passes against real brain-mcp
  • .mcp.json/docs updated if gitea-mcp needs to be added as an available connection

Report back (required)

Post a comment on this issue with:

  • Baseline result: pass/fail count for both modules, before and after
  • Dependency check result: confirmed clean, or coupling found (describe it)
  • What was iceboxed: exact paths/packages, and where they were moved to (branch/tag/archive path)
  • Regression diff: anything that failed post-cut that passed pre-cut (should be empty — if not, describe and do NOT close this issue until resolved)
  • Live smoke test result: actual output of hyperguild brain query and hyperguild mode, not just "it worked"
  • One-line verdict at the top: clean-cut / regression-found / blocked-on-<X>

This is inter-agent work — report via this issue thread (not just a brain note), per the standing rule that issue comments are the surface signal the reconcile pass (infra#172) and Mathias both read.

Refs

  • brain wiki/homelab/hypotheses/loop-economics-inversion-2026-06.md (why machinery-off is the baseline to protect)
  • brain wiki/homelab/decisions/agentsquad-vs-hyperguild-boundary-2026-05-28.md (prior boundary decision — now superseded by this consolidation; do not resurrect its "keep separate" conclusion)
  • brain wiki/homelab/decisions/platform-premortem-findings-2026-05-29.md (originally recommended nominating hyperguild as the single measured harness — this ticket finally executes that)
  • infra#170 (loop-1 experiment — proof hyperguild-alone closes)
  • infra#174 (routing pod survivorship bias — routing stays iceboxed regardless of that ticket's outcome)
  • cmd/routing/main.go header comment (historical "Plan 7 supervisor retirement" reference — supervisor already gone, not a live blocker)

Risk: LOW-MEDIUM — deletion/relocation of unused code guarded by regression tests at each step; no production traffic depends on cmd/routing today (not even wired into the live .mcp.json). Medium only because "verify no other consumer" steps require actual dependency-graph checking, not assumption.

## Context Mathias decided: consolidate to one harness (icebox agentsquad + Crush; see infra#170/#171-era loop-economics work). hyperguild is the harness — it's the only one with demonstrated loop-1 closure (infra#170, PR #16/#17) and already carries the two invariants that must survive: brain (vault/intellectual capital) and Gitea (audit trail). GitOps/OIDC stays the ops platform for everything built (`.gitea/workflows/cd.yml` already exists). **This issue is analysis-informed, not a guess.** Read before executing: ### What's already true (verified by reading the repo, not assumed) - **`cmd/hyperguild`** (tier probe, `brain query`/`write`, `.mcp.json` mode bootstrap) has **zero import of `internal/routing`**. It is already minimal and already separate. - **Live `.mcp.json`** (what an actual Claude Code session connects to) wires **only `brain-mcp`**. No routing pod, no gitea-mcp even listed here. This is exactly the config the infra#170 loop-1 experiment ran under — routing/brain-injection-machinery off, and it closed twice. - **`cmd/routing`** is a *separate binary* bundling two different things: 1. `internal/routing` (Router/Fetcher/Policy/pass-rate) — the broken part. infra#174 found this signal is survivorship-biased and unusable for routing as-is. 2. An MCP server hosting `review`/`debug`/`retrospective`/`trainer` as tools + `project_create` (Gitea project scaffolding), via `internal/skills/{review,debug,retrospective,trainer,project}`. Every one of these skill calls is wrapped through the broken router (`wrap(skillName)` in `cmd/routing/main.go`) — so today they are not independently usable; they're entangled with the broken part. - **`cmd/supervisor` does not exist in the current tree.** A comment in `cmd/routing/main.go` references "Plan 7 (supervisor retirement)" as a completed prior migration — historical, not a live constraint. No fourth binary to reconcile. - Both `cmd/hyperguild` and `ingestion/` have extensive existing `_test.go` coverage (nearly 1:1 file-to-test ratio) — this is real, not something to build from scratch. ### The conclusion this analysis supports The **live minimal harness already exists**: `cmd/hyperguild` + brain-mcp + gitea-mcp (external, not in `.mcp.json` today but available). This is what ran the loop-1 experiment. `cmd/routing` in its entirety — including the skill-as-MCP-tool wiring — is dormant from the live session's perspective and entangled with the broken pass-rate signal. The clean move is not surgical extraction; it's **confirm `cmd/hyperguild` is sufficient → icebox `cmd/routing` whole → keep `ingestion/` (brain vault machinery, separately verify) → pin regression tests before and after so nothing that's actually used breaks.** ## Do (in order — each gates the next) 1. **Pin the regression baseline.** Run the full existing test suite for both modules (`cmd/hyperguild` root module + `ingestion/` submodule — separate `go.mod`s) and record green. This is the safety net; nothing proceeds past this until it's green and captured. 2. **Confirm the cut boundary holds in code, not just by inspection.** Verify (e.g. `go list -deps` or equivalent) that `cmd/hyperguild` genuinely has no transitive dependency on `internal/routing` or `cmd/routing`'s packages. If it does, STOP and report — the analysis above is wrong somewhere and the plan needs revisiting before any deletion. 3. **Icebox `cmd/routing` in full**, plus `internal/routing`, `internal/tier` (if solely routing-consumed — verify first), and `internal/skills/{review,debug,retrospective,trainer,project}` (verify these have no OTHER consumer before deleting — `cmd/hyperguild` doesn't use them per step 2, but double-check nothing else does). "Icebox" = move to a clearly-marked branch/tag or an `icebox/` archive path, not `git rm` with no trace — this must be recoverable, not destroyed, per Mathias's "put it in an icebox" framing. 4. **Keep and verify `ingestion/`** (brain vault: capture, embed, vectorstore, graph, wiki, Gitea client) — this is the durable-capital invariant. Confirm its test suite is independently green (it doesn't depend on `cmd/routing` either, per the tree, but verify). 5. **Re-run the full regression baseline from step 1.** Everything that passed before must still pass (minus the tests that were deleted with `cmd/routing` itself — those disappearing is expected, not a regression). 6. **Live smoke test** (ground-truth, not just unit tests — same discipline as infra#170's M5 verification): actually run `hyperguild brain query <q>` and `hyperguild mode <name>` against real brain-mcp, confirm they work. Unit tests don't prove live wiring. 7. **Update `.mcp.json` / docs if needed** to reflect gitea-mcp as an available (not required-but-absent) connection, since Gitea-as-audit-trail is an explicit invariant going forward. ## Explicitly out of scope - Fixing `internal/routing`'s survivorship bias (that's infra#174, separately gated — routing pod stays iceboxed regardless of #174's outcome, per Mathias: fresh start, not a resurrection plan). - Porting agentsquad's peer-to-peer/multi-agent capability into hyperguild — explicitly dropped, not carried forward (icebox, no resurrection commitment). - Deleting Crush or agentsquad repos themselves — out of scope for this ticket (may be separate cleanup issues). - Any new feature work. This is subtraction + verification only. ## Acceptance Criteria - [ ] Step 1 baseline captured (test output saved/linked, both modules green) - [ ] Step 2 dependency check confirms zero coupling from `cmd/hyperguild` into routing-only packages (or: coupling found, reported, plan revised before proceeding) - [ ] `cmd/routing` + broken-router-entangled skill packages iceboxed (recoverable, not destroyed) - [ ] `ingestion/` (brain vault) confirmed independently green - [ ] Full regression re-run green (step 5), diffed against step 1 baseline — only expected deletions missing, nothing else - [ ] Live smoke test (step 6) passes against real brain-mcp - [ ] `.mcp.json`/docs updated if gitea-mcp needs to be added as an available connection ## Report back (required) Post a comment on this issue with: - **Baseline result:** pass/fail count for both modules, before and after - **Dependency check result:** confirmed clean, or coupling found (describe it) - **What was iceboxed:** exact paths/packages, and where they were moved to (branch/tag/archive path) - **Regression diff:** anything that failed post-cut that passed pre-cut (should be empty — if not, describe and do NOT close this issue until resolved) - **Live smoke test result:** actual output of `hyperguild brain query` and `hyperguild mode`, not just "it worked" - **One-line verdict at the top:** `clean-cut / regression-found / blocked-on-<X>` This is inter-agent work — report via this issue thread (not just a brain note), per the standing rule that issue comments are the surface signal the reconcile pass (infra#172) and Mathias both read. ## Refs - brain `wiki/homelab/hypotheses/loop-economics-inversion-2026-06.md` (why machinery-off is the baseline to protect) - brain `wiki/homelab/decisions/agentsquad-vs-hyperguild-boundary-2026-05-28.md` (prior boundary decision — now superseded by this consolidation; do not resurrect its "keep separate" conclusion) - brain `wiki/homelab/decisions/platform-premortem-findings-2026-05-29.md` (originally recommended nominating hyperguild as the single measured harness — this ticket finally executes that) - infra#170 (loop-1 experiment — proof hyperguild-alone closes) - infra#174 (routing pod survivorship bias — routing stays iceboxed regardless of that ticket's outcome) - `cmd/routing/main.go` header comment (historical "Plan 7 supervisor retirement" reference — supervisor already gone, not a live blocker) **Risk:** LOW-MEDIUM — deletion/relocation of unused code guarded by regression tests at each step; no production traffic depends on `cmd/routing` today (not even wired into the live `.mcp.json`). Medium only because "verify no other consumer" steps require actual dependency-graph checking, not assumption.
Author
Owner

clean-cut — PR #76 (feat/consolidate-single-harness).

Baseline result (before → after)

Module Before After
root (github.com/mathiasbq/supervisor) 21 ok / 0 fail 14 ok / 0 fail
ingestion/ 24 ok / 0 fail 24 ok / 0 fail

Forced (-count=1), go vet clean. The −7 in root = exactly the removed packages.

Dependency check result — confirmed clean

  • go list -deps ./cmd/hyperguild → in-module deps are only cmd/hyperguild + internal/tier. Zero transitive dep on internal/routing or cmd/routing's packages.
  • Reverse check: internal/routing and all five skills (review/debug/retrospective/trainer/project) are imported only by cmd/routing. Leak check (any kept package importing the removal set) = empty.
  • Caught by the "verify first" guard: internal/tier is not routing-only (cmd/hyperguild + internal/skills/org use it) → kept.

What was iceboxed (recoverable, not destroyed)

Moved to tag icebox/cmd-routing-2026-07-01 + branch icebox/cmd-routing (commit 00e5f62), then removed on the feature branch:

  • cmd/routing/, internal/routing/
  • internal/skills/{review,debug,retrospective,trainer,project}/
  • Dockerfile.routing
  • .gitea/workflows/cd.yml routing steps (build + infra bump + Flux-wait/rollout-verify) — ingestion deploy unchanged

Recovery documented in ICEBOX.md. Kept: cmd/hyperguild, ingestion/, internal/tier, internal/skills/{brain,org,sessionlog} (per ticket; already orphaned).

Regression diff — empty (no regressions)

Every package that dropped is a real deletion (7 removal-set packages); no package still on disk failed post-cut. ingestion/ byte-identical to baseline.

Live smoke test result (actual output)

$ hyperguild brain query "loop economics inversion single harness"
wiki/homelab/hypotheses/loop-economics-inversion-2026-06.md  score=73  loop-economics-inversion-2026-06
wiki/claude-sessions/facts/session-koala-175a181a-...md       score=68  ...
wiki/claude-sessions/facts/session-koala-6fc6513f-...md       score=44  ...
(+2 more, live BM25 from brain-mcp koala:30330)

$ hyperguild mode client-local   # (in scratch dir)
wrote .mcp.json (mode: client-local)
servers: ['brain', 'gitea']    has routing: False    gitea url: https://git-mcp.d-ma.be/mcp

.mcp.json / docs (step 7)

Added gitea-mcp to .mcp.json (Bearer ${GITEA_MCP_TOKEN}) and to all three mode templates (audit-trail invariant); removed the client-local routing entry. Tests + CLI README updated.

⚠️ Out-of-repo follow-up (flagged, not done here)

The live k8s routing deployment (infra k3s/apps/routing/) still runs its last image — CD no longer rebuilds/redeploys it, but the pod is not torn down. That's a separate infra-repo task. Not closing anything on that count; this repo-side cut is clean.

**`clean-cut`** — PR #76 (`feat/consolidate-single-harness`). ### Baseline result (before → after) | Module | Before | After | |---|---|---| | root (`github.com/mathiasbq/supervisor`) | 21 ok / 0 fail | 14 ok / 0 fail | | `ingestion/` | 24 ok / 0 fail | 24 ok / 0 fail | Forced (`-count=1`), `go vet` clean. The −7 in root = exactly the removed packages. ### Dependency check result — confirmed clean - `go list -deps ./cmd/hyperguild` → in-module deps are **only** `cmd/hyperguild` + `internal/tier`. Zero transitive dep on `internal/routing` or `cmd/routing`'s packages. - Reverse check: `internal/routing` and all five skills (`review/debug/retrospective/trainer/project`) are imported **only by `cmd/routing`**. Leak check (any kept package importing the removal set) = empty. - Caught by the "verify first" guard: `internal/tier` is **not** routing-only (`cmd/hyperguild` + `internal/skills/org` use it) → **kept**. ### What was iceboxed (recoverable, not destroyed) Moved to **tag `icebox/cmd-routing-2026-07-01`** + **branch `icebox/cmd-routing`** (commit `00e5f62`), then removed on the feature branch: - `cmd/routing/`, `internal/routing/` - `internal/skills/{review,debug,retrospective,trainer,project}/` - `Dockerfile.routing` - `.gitea/workflows/cd.yml` routing steps (build + infra bump + Flux-wait/rollout-verify) — ingestion deploy unchanged Recovery documented in `ICEBOX.md`. Kept: `cmd/hyperguild`, `ingestion/`, `internal/tier`, `internal/skills/{brain,org,sessionlog}` (per ticket; already orphaned). ### Regression diff — empty (no regressions) Every package that dropped is a real deletion (7 removal-set packages); no package still on disk failed post-cut. `ingestion/` byte-identical to baseline. ### Live smoke test result (actual output) ``` $ hyperguild brain query "loop economics inversion single harness" wiki/homelab/hypotheses/loop-economics-inversion-2026-06.md score=73 loop-economics-inversion-2026-06 wiki/claude-sessions/facts/session-koala-175a181a-...md score=68 ... wiki/claude-sessions/facts/session-koala-6fc6513f-...md score=44 ... (+2 more, live BM25 from brain-mcp koala:30330) $ hyperguild mode client-local # (in scratch dir) wrote .mcp.json (mode: client-local) servers: ['brain', 'gitea'] has routing: False gitea url: https://git-mcp.d-ma.be/mcp ``` ### `.mcp.json` / docs (step 7) Added gitea-mcp to `.mcp.json` (Bearer `${GITEA_MCP_TOKEN}`) and to all three `mode` templates (audit-trail invariant); removed the client-local `routing` entry. Tests + CLI README updated. ### ⚠️ Out-of-repo follow-up (flagged, not done here) The **live k8s routing deployment** (`infra` `k3s/apps/routing/`) still runs its last image — CD no longer rebuilds/redeploys it, but the pod is not torn down. That's a separate infra-repo task. Not closing anything on that count; this repo-side cut is clean.
Author
Owner

Follow-up filed: infra#176

The out-of-repo item flagged above — tearing down the still-running k8s routing deployment — is now tracked as infra#176 (Tear down k3s routing deployment — cmd/routing iceboxed). It's self-contained (no other estate app references routing.svc / NodePort 30310): remove k3s/apps/routing/ + the - routing line from the apps kustomization, then flux reconcile prunes the namespace. That ticket also notes it supersedes the live-deploy portion of #35 (the qwen36 koala llama-swap slot itself is unaffected and stays). This repo-side cut (PR #76) stays clean-cut and independent of that infra teardown.

### Follow-up filed: infra#176 The out-of-repo item flagged above — tearing down the still-running k8s routing deployment — is now tracked as **infra#176** (`Tear down k3s routing deployment — cmd/routing iceboxed`). It's self-contained (no other estate app references `routing.svc` / NodePort 30310): remove `k3s/apps/routing/` + the `- routing` line from the apps kustomization, then `flux reconcile` prunes the namespace. That ticket also notes it supersedes the live-deploy portion of #35 (the qwen36 koala llama-swap slot itself is unaffected and stays). This repo-side cut (PR #76) stays `clean-cut` and independent of that infra teardown.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/hyperguild#75