Files
hyperguild/AGENTS.md
T
mathiasandClaude Sonnet 5.5 5dfd2c0f7e
CI / Lint / Test / Vet (push) Successful in 1m28s
CI / Mirror to GitHub (push) Successful in 3s
docs: main is protected, ship by PR (local-dev#42)
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
2026-10-08 08:34:50 +02:00

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-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

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}.