Gitea will refuse direct pushes to main in this repo. Rule 5's reviewed lane was enforced on the merge tools (tbd_ship / pr_merge, gitea-mcp v0.17.0/v0.18.0) but not on a direct commit; this overrides rule 5's "risk/low straight to main" for this repo and says why. Derived adapter files regenerated where the repo has them. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZkhi49hfeSqBp5aZJNXsM
4.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-lintwith project config - Tests: table-driven, in
_test.gonext to source,testifyfor assertions - Errors: wrap with
fmt.Errorf("operation: %w", err), no naked returns - Naming: stdlib conventions, no stuttering (
http.Clientnothttp.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
govulncheckbefore adding
MCP endpoints
Two MCP servers are live, both reachable over Tailscale and via HTTPS domain:
brainathttps://brain-mcp.d-ma.be/mcp(NodePortkoala: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 staticBRAIN_MCP_TOKEN.routingathttp://koala:30310/mcp— Mode 2 routing pod. Advertisesreview,debug,retrospective,trainer; per-call routes to local model or Claude based on brain/pass-rate. Bearer auth viaROUTING_MCP_TOKEN(opt-in). Onlymode client-localregisters 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:
- Read this file and all
SKILL.mdfiles in.skills/before starting work - Run
task checkbefore committing (lint + test + vet) - If unsure about a convention, check
DECISIONS.mdor ask - Never modify files outside the project root without explicit permission
- When adding a dependency, explain why in the commit message
- For client projects: never send code or context to cloud APIs — use local models via LiteLLM
main is protected: ship by PR (local-dev#42, decided 2026-10-08)
Gitea refuses direct pushes to main in this repo, and a PR merges only after its CI status (CI / Lint / Test / Vet (pull_request)) passes.
Why: local-dev rule 5's reviewed lane (risk/medium+ is reviewed by a human) was enforced on the merge tools
(tbd_ship, pr_merge: gitea-mcp v0.17.0/v0.18.0, merge only for an issue labelled exactly risk/low with green CI)
but not on a direct commit to main, which bypassed it. This overrides rule 5's "risk/low commits straight to main"
for this repo; control code is where the lane matters.
How: tbd_ship for a one-file change, or branch -> PR -> pr_merge (name the risk/low issue); above risk/low
open the PR and a human merges it in the Gitea UI after review. Tags are not protected. CD jobs push image tags to
the infra repo with deploy keys, never to this repo's main. Undo (Mathias only): Settings -> Branches, or
PATCH /repos/mathias/hyperguild/branch_protections/main {"enable_push": true}.