Procfile, Taskfile and smoke-routing.sh still invoke cmd/supervisor and cmd/routing, neither of which exists #120

Closed
opened 2026-09-16 22:25:40 +00:00 by mathias · 2 comments
Owner

Found while merge-gating #119 (which closed #116). Not caused by that PR — all of this predates it. Same defect class as #116: artifacts that look correct and are connected to nothing.

cmd/ contains exactly one binary: cmd/hyperguild. cmd/supervisor was deleted in c117634 ("feat(plan7): retire supervisor pod — delete cmd/supervisor, tdd/spec skills, Dockerfile"). cmd/routing does not exist anywhere in the tree (find . -type d -name routing returns nothing).

Four call sites still reference them:

Location Reference Effect
Procfile:2 go run ./cmd/supervisor/ task start / goreman start fails on this line
Taskfile.yml:38 (supervisor:dev) go run ./cmd/supervisor fails
Taskfile.yml:76 (supervisor:build) go build ... ./cmd/supervisor fails — and task build calls it, so task build is broken
scripts/smoke-routing.sh:23 (task smoke:routing) go build -o "$BIN" ./cmd/routing fails

Procfile:2 also still sets SUPERVISOR_MODELS_FILE=./config/models.yaml, now pointing at a file deleted in #119. Harmless in isolation (nothing reads the var), but it is the last textual reference to the routing config in a non-docs file.

None of this is caught by CI, because task check runs lint/test/vet and never task build — so a Taskfile target can reference a deleted package indefinitely while the gate stays green. That gap is the reason this survived since c117634.

Related dead surface found in the same sweep

internal/config has no non-test callers at all:

  • config.Load() / the Config struct — referenced only by internal/config/config_test.go
  • config.LoadRouting() / RoutingConfig — referenced only by internal/config/routing_test.go

RoutingConfig is the struct that documents the live env surface (HYPERGUILD_FAST_MODEL, HYPERGUILD_ROUTE_LOCAL_FLOOR, the Gitea MCP wiring), and its consumer — the routing pod — went with cmd/routing. So the whole package is currently tests-testing-themselves. Worth deciding deliberately rather than deleting on sight, since these structs are also the closest thing to documentation of the routing pod's contract.

Suggested scope

  1. Delete the four stale call sites (Procfile supervisor line, two Taskfile targets, smoke:routing + its script) — or restore cmd/routing if the routing pod is meant to come back.
  2. Decide on internal/config: delete, or re-point at a real consumer.
  3. Consider adding task build to check so a Taskfile target referencing a deleted package fails the gate.

Item 2 is a judgement call about whether the routing pod is coming back — flagging rather than deciding.


Created via git-mcp on behalf of @mathias

Found while merge-gating #119 (which closed #116). Not caused by that PR — all of this predates it. Same defect class as #116: **artifacts that look correct and are connected to nothing.** `cmd/` contains exactly one binary: `cmd/hyperguild`. `cmd/supervisor` was deleted in c117634 ("feat(plan7): retire supervisor pod — delete cmd/supervisor, tdd/spec skills, Dockerfile"). `cmd/routing` does not exist anywhere in the tree (`find . -type d -name routing` returns nothing). Four call sites still reference them: | Location | Reference | Effect | |---|---|---| | `Procfile:2` | `go run ./cmd/supervisor/` | `task start` / `goreman start` fails on this line | | `Taskfile.yml:38` (`supervisor:dev`) | `go run ./cmd/supervisor` | fails | | `Taskfile.yml:76` (`supervisor:build`) | `go build ... ./cmd/supervisor` | fails — and `task build` calls it, so **`task build` is broken** | | `scripts/smoke-routing.sh:23` (`task smoke:routing`) | `go build -o "$BIN" ./cmd/routing` | fails | `Procfile:2` also still sets `SUPERVISOR_MODELS_FILE=./config/models.yaml`, now pointing at a file deleted in #119. Harmless in isolation (nothing reads the var), but it is the last textual reference to the routing config in a non-docs file. None of this is caught by CI, because `task check` runs `lint`/`test`/`vet` and never `task build` — so a Taskfile target can reference a deleted package indefinitely while the gate stays green. That gap is the reason this survived since c117634. ## Related dead surface found in the same sweep `internal/config` has **no non-test callers at all**: - `config.Load()` / the `Config` struct — referenced only by `internal/config/config_test.go` - `config.LoadRouting()` / `RoutingConfig` — referenced only by `internal/config/routing_test.go` `RoutingConfig` is the struct that documents the live env surface (`HYPERGUILD_FAST_MODEL`, `HYPERGUILD_ROUTE_LOCAL_FLOOR`, the Gitea MCP wiring), and its consumer — the routing pod — went with `cmd/routing`. So the whole package is currently tests-testing-themselves. Worth deciding deliberately rather than deleting on sight, since these structs are also the closest thing to documentation of the routing pod's contract. ## Suggested scope 1. Delete the four stale call sites (`Procfile` supervisor line, two Taskfile targets, `smoke:routing` + its script) — or restore `cmd/routing` if the routing pod is meant to come back. 2. Decide on `internal/config`: delete, or re-point at a real consumer. 3. Consider adding `task build` to `check` so a Taskfile target referencing a deleted package fails the gate. Item 2 is a judgement call about whether the routing pod is coming back — flagging rather than deciding. --- _Created via git-mcp on behalf of @mathias_
mathias added the size/stype/fix labels 2026-09-16 22:25:40 +00:00
mathias reopened this issue 2026-09-16 22:36:57 +00:00
Author
Owner

Merge gate — PR #121 MERGED, this issue stays OPEN

Squashed to main as 6e449b4. #120 is deliberately still open: only items 1 and 3 of "Suggested scope" are done. Item 2 (internal/config has no non-test callers) is untouched and is the reason this issue is not closed.

Note on numbering: PR #121's description says it closes "items 2 and the suggested gate fix", and later calls internal/config "#120's third item". That is off by one against this issue's own list — what shipped is item 1 (delete the four stale call sites) and item 3 (build in check). What remains is item 2 (internal/config). Recording it here so the leftover is not misidentified later.

Gitea auto-closed this issue on merge (the PR body carried Closes #120); reopened by hand immediately after. The squash commit message says Refs #120, not Closes, so it will not re-close on any later replay.

What I verified, not took on trust

The gate change is load-bearing — flip-tested both directions. Re-added a supervisor:build target pointing at ./cmd/supervisor on top of the PR head:

task: [supervisor:build] go build -trimpath -o bin/supervisor ./cmd/supervisor
stat .../cmd/supervisor: directory not found
CI=1 task check -> exit 201

Then, with that broken target still present, removed only - task: build from check (i.e. the pre-PR gate):

CI=1 task check -> exit 0, "no leaks found"

So the old gate really was blind to a build target naming a deleted package, and the new one really catches it. Tree restored byte-for-byte afterwards (Taskfile.yml sha256 5fc04891…, git status --porcelain empty).

Adding build to check does not dirty the tree or break CI. bin/ is gitignored (.gitignore:5) and is the only path written: hyperguild:build does mkdir -p bin + -o bin/hyperguild, ingestion:build writes ../bin/ingestion-server from dir: ingestion — same bin/. hyperguild:build runs first, so the mkdir -p covers ingestion:build on a fresh runner with no bin/. git status --porcelain is empty after a full CI=1 task check. The porcelain/context-sync assertion in check only covers AGENTS.md, CLAUDE.md, .context/system-prompt.txt and runs before build anyway.

build now runs before security:gitleaks — checked that interaction rather than assuming it. gitleaks runs --no-git --source . with 57 MB of fresh binaries sitting in bin/, and scanned 1.81 MB in both my local run and CI run 7387 — it honours .gitignore, so the binaries are not scanned. No slowdown, no false positives.

Nothing removed is still reachable. Grepped supervisor:dev, supervisor:build, supervisor:test:smoke, smoke:routing, smoke-routing across the whole repo. Every surviving hit is in docs/superpowers/plans/ and docs/superpowers/specs/ — dated historical plan records, not live call sites. Zero hits in .gitea/workflows/, README.md, Procfile or any other task. The supervisor strings in cd.yml are the k8s namespace, unrelated to the binary.

Both binaries are genuinely meant to be gone.

  • cmd/supervisor — deleted 2026-05-12 in c117634, and the retirement is written down twice: DECISIONS.md "Plan 7: supervisor pod retired (2026-05-12)" and CLAUDE.md "The supervisor MCP (koala:30320) was retired in Plan 7". No commit anywhere in the repo has tried to re-add it (git log --all --diff-filter=A -- cmd/supervisor returns only the original creation).
  • cmd/routing — iceboxed 2026-07-01 in fb59c39 (#75), with ICEBOX.md giving a restore recipe pinned to tag icebox/cmd-routing-2026-07-01. scripts/smoke-routing.sh built ./cmd/routing from this tree, so it has been non-runnable since that day regardless of whether the routing pod still runs in the cluster.

The deleted smoke script was also an instance of the defect class this repo keeps hitting. scripts/smoke-routing.sh exited 0 with a SKIP: line whenever LiteLLM or the brain was unreachable. Run anywhere without Tailscale it was a guaranteed green that proved nothing — and after cmd/routing went, it could not even reach that point. Deleting it removes a check that could only ever pass.

Spot-checked the author's dir:-aware sweep on this repo. Every remaining path in Taskfile.yml resolves once the task's working directory is applied: scripts/context-sync.sh, cmd/hyperguild (root module), ingestion/cmd/server and ingestion/cmd/frontmatterlint (both via dir: ingestion or cd ingestion), plus the Procfile line. No remaining dead target here. I did not re-run the sweep across the estate, so the "only this repo and dma-cli" claim is unverified beyond this repo.

CI

Run 7387, job 10984 "Lint / Test / Vet", head 760aa45 (the exact PR head, i.e. the commit that adds build to check) — success, 22:33:06→22:34:00Z. The log proves the new step actually executed on the runner, not just that the job was green:

task: [hyperguild:build] mkdir -p bin
task: [hyperguild:build] go build -o bin/hyperguild ./cmd/hyperguild
task: [ingestion:build] go build -trimpath -ldflags="-s -w" -o ../bin/ingestion-server ./cmd/server
task: [security:gitleaks] ... no leaks found

Local CI=1 task check on koala: exit 0, 7.6 s wall.

Follow-ups this merge does not cover (recording so they have a locator)

  1. Item 2 — internal/config. Still zero non-test callers. Unchanged, and the reason this issue stays open.
  2. ICEBOX.md is now slightly stale. Its restore recipe for cmd/routing lists cmd/routing internal/routing internal/skills/* Dockerfile.routing, and its "what was iceboxed" table does not mention scripts/smoke-routing.sh or the smoke:routing task — which is exactly why they survived the 2026-07-01 cut and were still here today. A future restore from icebox/cmd-routing-2026-07-01 will bring the binary back without its smoke test, and nothing will say the script ever existed. Recoverable via git show 6e449b4^:scripts/smoke-routing.sh, but the recipe should say so.
  3. .gitignore:7 still ignores cmd/supervisor/supervisor — a rule for a directory deleted 4 months ago. Harmless, same dead-reference class.
  4. stop still kills port 3200, the retired supervisor's port. Harmless leftover.
  5. Pre-existing, not introduced here, but it caps what "CI green" is worth in this repo: vet runs govulncheck ./... || true (a vulnerability finding cannot fail the gate), and security:gitleaks exit 0s when gitleaks is absent. gitleaks was genuinely present and did run in CI 7387 — verified in the log — but that is an environmental fact, not a guarantee.

Not checked

  • Whether the live routing pod in infra k3s/apps/routing/ is still deployed. Out of this PR's scope — it touches no manifests — but ICEBOX.md:43 says that deployment still runs its last image and tearing it down is a separate infra task.
  • The estate-wide sweep (dma-cli and the other repos).
  • The content of the archived plan/spec docs that still name the removed tasks; left as historical records by design.

Merge-gate review by Claude Opus 5 on behalf of @mathias

## Merge gate — PR #121 MERGED, this issue stays OPEN Squashed to `main` as `6e449b4`. **#120 is deliberately still open**: only items 1 and 3 of "Suggested scope" are done. Item 2 (`internal/config` has no non-test callers) is untouched and is the reason this issue is not closed. Note on numbering: PR #121's description says it closes "items 2 and the suggested gate fix", and later calls `internal/config` "#120's third item". That is off by one against this issue's own list — what shipped is **item 1** (delete the four stale call sites) and **item 3** (`build` in `check`). What remains is **item 2** (`internal/config`). Recording it here so the leftover is not misidentified later. Gitea auto-closed this issue on merge (the PR body carried `Closes #120`); reopened by hand immediately after. The squash commit message says `Refs #120`, not `Closes`, so it will not re-close on any later replay. ### What I verified, not took on trust **The gate change is load-bearing — flip-tested both directions.** Re-added a `supervisor:build` target pointing at `./cmd/supervisor` on top of the PR head: ``` task: [supervisor:build] go build -trimpath -o bin/supervisor ./cmd/supervisor stat .../cmd/supervisor: directory not found CI=1 task check -> exit 201 ``` Then, with that broken target still present, removed only `- task: build` from `check` (i.e. the pre-PR gate): ``` CI=1 task check -> exit 0, "no leaks found" ``` So the old gate really was blind to a build target naming a deleted package, and the new one really catches it. Tree restored byte-for-byte afterwards (`Taskfile.yml` sha256 `5fc04891…`, `git status --porcelain` empty). **Adding `build` to `check` does not dirty the tree or break CI.** `bin/` is gitignored (`.gitignore:5`) and is the only path written: `hyperguild:build` does `mkdir -p bin` + `-o bin/hyperguild`, `ingestion:build` writes `../bin/ingestion-server` from `dir: ingestion` — same `bin/`. `hyperguild:build` runs first, so the `mkdir -p` covers `ingestion:build` on a fresh runner with no `bin/`. `git status --porcelain` is empty after a full `CI=1 task check`. The porcelain/context-sync assertion in `check` only covers `AGENTS.md`, `CLAUDE.md`, `.context/system-prompt.txt` and runs *before* `build` anyway. **`build` now runs before `security:gitleaks` — checked that interaction rather than assuming it.** gitleaks runs `--no-git --source .` with 57 MB of fresh binaries sitting in `bin/`, and scanned 1.81 MB in both my local run and CI run 7387 — it honours `.gitignore`, so the binaries are not scanned. No slowdown, no false positives. **Nothing removed is still reachable.** Grepped `supervisor:dev`, `supervisor:build`, `supervisor:test:smoke`, `smoke:routing`, `smoke-routing` across the whole repo. Every surviving hit is in `docs/superpowers/plans/` and `docs/superpowers/specs/` — dated historical plan records, not live call sites. Zero hits in `.gitea/workflows/`, `README.md`, `Procfile` or any other task. The `supervisor` strings in `cd.yml` are the k8s **namespace**, unrelated to the binary. **Both binaries are genuinely meant to be gone.** - `cmd/supervisor` — deleted 2026-05-12 in `c117634`, and the retirement is written down twice: `DECISIONS.md` "Plan 7: supervisor pod retired (2026-05-12)" and `CLAUDE.md` "The supervisor MCP (koala:30320) was retired in Plan 7". No commit anywhere in the repo has tried to re-add it (`git log --all --diff-filter=A -- cmd/supervisor` returns only the original creation). - `cmd/routing` — iceboxed 2026-07-01 in `fb59c39` (#75), with `ICEBOX.md` giving a restore recipe pinned to tag `icebox/cmd-routing-2026-07-01`. `scripts/smoke-routing.sh` built `./cmd/routing` from *this* tree, so it has been non-runnable since that day regardless of whether the routing pod still runs in the cluster. **The deleted smoke script was also an instance of the defect class this repo keeps hitting.** `scripts/smoke-routing.sh` exited **0** with a `SKIP:` line whenever LiteLLM or the brain was unreachable. Run anywhere without Tailscale it was a guaranteed green that proved nothing — and after `cmd/routing` went, it could not even reach that point. Deleting it removes a check that could only ever pass. **Spot-checked the author's `dir:`-aware sweep on this repo.** Every remaining path in `Taskfile.yml` resolves once the task's working directory is applied: `scripts/context-sync.sh`, `cmd/hyperguild` (root module), `ingestion/cmd/server` and `ingestion/cmd/frontmatterlint` (both via `dir: ingestion` or `cd ingestion`), plus the `Procfile` line. No remaining dead target here. I did **not** re-run the sweep across the estate, so the "only this repo and dma-cli" claim is unverified beyond this repo. ### CI Run **7387**, job **10984** "Lint / Test / Vet", head `760aa45` (the exact PR head, i.e. the commit that adds `build` to `check`) — **success**, 22:33:06→22:34:00Z. The log proves the new step actually executed on the runner, not just that the job was green: ``` task: [hyperguild:build] mkdir -p bin task: [hyperguild:build] go build -o bin/hyperguild ./cmd/hyperguild task: [ingestion:build] go build -trimpath -ldflags="-s -w" -o ../bin/ingestion-server ./cmd/server task: [security:gitleaks] ... no leaks found ``` Local `CI=1 task check` on koala: **exit 0**, 7.6 s wall. ### Follow-ups this merge does not cover (recording so they have a locator) 1. **Item 2 — `internal/config`.** Still zero non-test callers. Unchanged, and the reason this issue stays open. 2. **`ICEBOX.md` is now slightly stale.** Its restore recipe for `cmd/routing` lists `cmd/routing internal/routing internal/skills/* Dockerfile.routing`, and its "what was iceboxed" table does not mention `scripts/smoke-routing.sh` or the `smoke:routing` task — which is exactly why they survived the 2026-07-01 cut and were still here today. A future restore from `icebox/cmd-routing-2026-07-01` will bring the binary back without its smoke test, and nothing will say the script ever existed. Recoverable via `git show 6e449b4^:scripts/smoke-routing.sh`, but the recipe should say so. 3. **`.gitignore:7` still ignores `cmd/supervisor/supervisor`** — a rule for a directory deleted 4 months ago. Harmless, same dead-reference class. 4. **`stop` still kills port 3200**, the retired supervisor's port. Harmless leftover. 5. **Pre-existing, not introduced here, but it caps what "CI green" is worth in this repo:** `vet` runs `govulncheck ./... || true` (a vulnerability finding cannot fail the gate), and `security:gitleaks` `exit 0`s when gitleaks is absent. gitleaks *was* genuinely present and did run in CI 7387 — verified in the log — but that is an environmental fact, not a guarantee. ### Not checked - Whether the live routing pod in `infra` `k3s/apps/routing/` is still deployed. Out of this PR's scope — it touches no manifests — but `ICEBOX.md:43` says that deployment still runs its last image and tearing it down is a separate infra task. - The estate-wide sweep (`dma-cli` and the other repos). - The content of the archived plan/spec docs that still name the removed tasks; left as historical records by design. --- _Merge-gate review by Claude Opus 5 on behalf of @mathias_
Author
Owner

Already fixed, just never linked to close this issue. PR #121 (commit 6e449b4, "fix(taskfile): remove build targets for binaries deleted months ago, and make check build") landed all three suggested-scope items:

  1. Stale call sites deleted: Procfile now has only the ingestion target (./cmd/server/), no supervisor line. Taskfile.yml has no supervisor:dev/supervisor:build/smoke:routing targets. scripts/smoke-routing.sh is gone.
  2. task build added to check, deliberately, with a comment in Taskfile.yml citing this issue by number and explaining why (vet/test walk ./..., which only enumerates packages that exist — a build target naming a deleted package was invisible to both).
  3. Verified independently just now: task build succeeds cleanly (bin/hyperguild + bin/ingestion-server both build).

Not resolved, and deliberately not touched — the one item the issue itself flagged as a judgment call, not something to decide unilaterally: internal/config's config.go/routing.go still have zero non-test callers (config.Load()/RoutingConfig are only referenced from their own _test.go files). Whether to delete this package or re-point it at a real consumer depends on whether the routing pod is coming back — that's still an open question for whenever it's decided, not a defect.

🤖 Generated with Claude Code


Created via git-mcp on behalf of @mathias

Already fixed, just never linked to close this issue. PR #121 (commit `6e449b4`, "fix(taskfile): remove build targets for binaries deleted months ago, and make check build") landed all three suggested-scope items: 1. **Stale call sites deleted**: `Procfile` now has only the `ingestion` target (`./cmd/server/`), no supervisor line. `Taskfile.yml` has no `supervisor:dev`/`supervisor:build`/`smoke:routing` targets. `scripts/smoke-routing.sh` is gone. 2. **`task build` added to `check`**, deliberately, with a comment in `Taskfile.yml` citing this issue by number and explaining why (`vet`/`test` walk `./...`, which only enumerates packages that exist — a build target naming a deleted package was invisible to both). 3. Verified independently just now: `task build` succeeds cleanly (`bin/hyperguild` + `bin/ingestion-server` both build). **Not resolved, and deliberately not touched** — the one item the issue itself flagged as a judgment call, not something to decide unilaterally: `internal/config`'s `config.go`/`routing.go` still have zero non-test callers (`config.Load()`/`RoutingConfig` are only referenced from their own `_test.go` files). Whether to delete this package or re-point it at a real consumer depends on whether the routing pod is coming back — that's still an open question for whenever it's decided, not a defect. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Created via git-mcp on behalf of @mathias_
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/hyperguild#120