forgejo-mcp-broker/CLAUDE.md
Ole-Morten Duesund 1555c285ba docs: fill CLAUDE.md with phase-1 session learnings
Populate the Build & Test, Architecture Overview, and Conventions
& Patterns sections of CLAUDE.md with context captured during the
phase-1 implementation work. Highlights the non-obvious gotchas
(http.Server.Shutdown not interrupting active conns; bd link
direction; bd init auto-committing) so future sessions don't
re-discover them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:37:36 +02:00

4.1 KiB

Project Instructions for AI Agents

This file provides instructions and context for AI coding agents working on this project.

Beads Issue Tracker

This project uses bd (beads) for issue tracking. Run bd prime to see full workflow context and commands.

Quick Reference

bd ready              # Find available work
bd show <id>          # View issue details
bd update <id> --claim  # Claim work
bd close <id>         # Complete work

Rules

  • Use bd for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
  • Run bd prime for detailed command reference and session close protocol
  • Use bd remember for persistent knowledge — do NOT use MEMORY.md files

Session Completion

When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.

MANDATORY WORKFLOW:

  1. File issues for remaining work - Create issues for anything that needs follow-up
  2. Run quality gates (if code changed) - Tests, linters, builds
  3. Update issue status - Close finished work, update in-progress items
  4. PUSH TO REMOTE - This is MANDATORY:
    git pull --rebase
    bd dolt push
    git push
    git status  # MUST show "up to date with origin"
    
  5. Clean up - Clear stashes, prune remote branches
  6. Verify - All changes committed AND pushed
  7. Hand off - Provide context for next session

CRITICAL RULES:

  • Work is NOT complete until git push succeeds
  • NEVER stop before pushing - that leaves work stranded locally
  • NEVER say "ready to push when you are" - YOU must push
  • If push fails, resolve and retry until it succeeds

Build & Test

  • make build./fjmcp-broker with -trimpath + ldflags-stamped build info
  • make testgo test -race ./... (includes integration tests under cmd/broker/)
  • make lintgo vet; golangci-lint if installed
  • make tidygo mod tidy
  • ./fjmcp-broker --version — inspect build info without supplying the rest of the config

Architecture Overview

OAuth 2.1 authorization-server facade that fronts forgejo-mcp: brokers the OAuth dance against Forgejo, then spawns a per-session forgejo-mcp --transport stdio subprocess with the authenticated user's token in env. Module path: kode.naiv.no/olemd/forgejo-mcp-broker.

Full design: docs/design.md. Phased plan: docs/plan.md.

Layout: cmd/broker/internal/configinternal/storeinternal/httpserver, with internal/buildinfo (ldflags-stamped) and internal/log (slog) as shared utilities.

Conventions & Patterns

  • SQLite driver: modernc.org/sqlite (pure Go, no CGO). DSN pragmas via ?_pragma=name(value).
  • Migrations: embed.FS under internal/store/migrations/NNNN_name.sql; loadMigrations takes fs.FS so tests inject synthetic sets via testing/fstest.
  • Graceful HTTP shutdown: srv.Shutdown() does NOT interrupt active connections; on deadline, fall back to srv.Close() to force-close and cancel handler contexts.
  • Signal handling belongs in main via signal.NotifyContext(SIGINT, SIGTERM); packages take a ctx and never wire signals themselves.
  • Config validation aggregates errors via errors.Join so operators see every problem at once.
  • Logger: internal/log.New(w, debug) (JSON slog); internal/log.Discard() for tests (uses slog.DiscardHandler, Go ≥ 1.24).
  • Empty future packages carry a doc.go stub whose package comment references the bd issue that will fill it in.
  • Integration tests under cmd/broker/*_integration_test.go build the binary once in TestMain and exercise it as a subprocess.
  • Tests use t.Context() (Go 1.24+) and t.TempDir() throughout — no context.Background() or manual cleanup.
  • bd link A B means "A depends on B" (B blocks A). bd create --deps "blocks:id" reverses this and is usually wrong — prefer bare --deps "id".
  • bd init auto-commits its scaffolding; a follow-up git commit for the same files will be a no-op.
  • fj outside a cloned repo needs -H kode.naiv.no to know the host.