Files
hyperguild/.context/PROJECT.md
mathiasandClaude Opus 5.5 b5c227179f
CI / Lint / Test / Vet (pull_request) Successful in 35s
CI / Mirror to GitHub (pull_request) Skipped
fix(ingestion): close the PR #152 review findings on REST auth
- main.go's wiring was untested (the test built its own copy of the
  router, so dropping auth in main or re-registering POST /query as
  public stayed green). Routing is now one function, buildMux, which
  main calls and the tests call: it constructs the bearer middleware
  itself, registers public handlers only for patterns on a fixed
  allowlist (a public REST pattern would beat the authenticated
  catch-all by specificity), refuses an empty token, and returns an
  http.Handler so nothing can add a route to the result.
- hyperguild CLI: PassRate sent no token and would 401. Every request
  now goes through brainClient.do, which adds it; the test covers
  Query, Write and PassRate and is named for that.
- ResolveIngestPath returns one refusal for every bad path; the raw
  EvalSymlinks error let a caller probe which server files exist and
  leaked the brain directory.
- PROJECT.md (and derived adapters) and the pass-rate runbook state
  that the REST API needs BRAIN_MCP_TOKEN and is tailnet/in-cluster.

Refs #149

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:32:20 +02:00

3.7 KiB

Project context

Identity

  • Name: supervisor
  • Owner: Mathias
  • Client: personal
  • Repo:
  • Status: active

Stack

  • Primary language: Go
  • UI layer: HTMX + Templ (when applicable)
  • Fallback languages: Python, TypeScript (justify in PR if used)
  • Build: Task (taskfile.dev), not Make
  • Containers: Docker (compose for dev, k3s for deploy)
  • Target infra: koala (GPU workloads), iguana (services), flamingo (edge)

Conventions

Code style

  • Go: follow golines, gofumpt, golangci-lint with project config
  • Tests: table-driven, in _test.go next to source, testify for assertions
  • Errors: wrap with fmt.Errorf("operation: %w", err), no naked returns
  • Naming: stdlib conventions, no stuttering (http.Client not http.HTTPClient)

Architecture preferences

  • Prefer standard library over frameworks (net/http over gin/echo)
  • Dependency injection via constructor functions, not containers
  • Configuration via environment variables, parsed at startup into a typed struct
  • Structured logging via slog

Git

  • Conventional commits: feat:, fix:, chore:, docs:, refactor:
  • Branch naming: feat/short-description, fix/short-description
  • PRs: one concern per PR, description explains why not what

Security

  • No secrets in code, ever — use env vars or SOPS-encrypted files
  • Client data never leaves local network unless explicitly cleared
  • Dependencies: audit with govulncheck before adding

MCP endpoints

Two MCP servers are live, both reachable over Tailscale and via HTTPS domain:

  • brain at https://brain-mcp.d-ma.be/mcp (NodePort koala:30330) — brain_query, brain_write, brain_ingest, brain_ingest_raw, brain_answer, brain_classify, session_log. Hosted by the ingestion service. Auth: Dex JWT (claude.ai OAuth) or static BRAIN_MCP_TOKEN.
  • routing at http://koala:30310/mcp — Mode 2 routing pod. Advertises review, debug, retrospective, trainer; per-call routes to local model or Claude based on brain /pass-rate. Bearer auth via ROUTING_MCP_TOKEN (opt-in). Only mode client-local registers this endpoint.

The supervisor MCP (koala:30320) was retired in Plan 7 (2026-05-12). Its skill workers (tdd, spec) are now SKILL.md files; routed skills moved to the routing pod; brain tools moved to the brain MCP.

The brain HTTP REST API (/query, /write, /ingest, /ingest-raw, /ingest-path, /backfill-refs, /pass-rate) remains available on port 3300 for shell scripts and non-MCP clients, with the same bearer token as /mcp (BRAIN_MCP_TOKEN; hyperguild#149). It is not served on the public host (infra#517): use the tailnet (koala:8443) or in-cluster ingestion.supervisor.svc:3300. /ingest-path and brain_ingest path accept only paths inside brain/raw/.

brain_answer(query) performs BM25 retrieval + LLM synthesis (berget.ai gemma4:31b → iguana fallback). brain_classify(text) infers doc type, title, and tags. Both require BRAIN_LLM_PRIMARY_URL to be set in the ingestion pod.

Agent instructions

When acting as a coding agent on this project:

  1. Read this file and all SKILL.md files in .skills/ before starting work
  2. Run task check before committing (lint + test + vet)
  3. If unsure about a convention, check DECISIONS.md or ask
  4. Never modify files outside the project root without explicit permission
  5. When adding a dependency, explain why in the commit message
  6. For client projects: never send code or context to cloud APIs — use local models via LiteLLM