Files
ForgeBucket/AGENTS.md
T
2026-05-12 20:55:13 +02:00

12 KiB

AGENTS.md — ForgeBucket AI Agent Guide

This file is for AI coding agents (Claude Code, GitHub Copilot, etc.) working in this repository. Read it before making changes.


Mission

ForgeBucket is a unified operating system for software delivery — not a Git repository viewer with CI attached. The guiding philosophy:

Repositories are runtime systems. The dashboard is a command center. GitOps is first-class.

Every feature decision should answer: does this reduce cognitive load? Does this improve operational awareness? Does this improve developer flow?

The full product vision lives in ai_agent_master_prompt_for_building_modern_git_platform.md.


Architecture Map

cmd/forgebucket/              — binary entry point (main.go)
internal/
  api/
    router.go                 — Chi router, all route definitions (60+ routes)
    middleware/               — auth.go, csrf.go, rbac.go, audit.go
    handlers/                 — one file per domain area (see Key Files below)
  domain/
    git/                      — sanitized git binary wrapper (exec.Command only, no shell)
      binary.go               — Run, Log, Tree, Diff, BlobCat, RevParse, etc.
      agit.go                 — AGit ref parsing
    ci/                       — CI/CD execution engine (fully built — Phase 2B)
      orchestrator.go         — NATS-driven DAG orchestrator
      runner_manager.go       — job dispatch with Docker executor
      executor.go             — docker run, log streaming, workspace extraction
      dag.go                  — topological sort, ReadyJobs
      parser.go               — .forgebucket/workflows/*.yml parser
      types.go                — WorkflowFile, WorkflowJob, WorkflowStep structs
    gitops/                   — GitOps controller (fully built — Phase 3D)
      controller.go           — NATS subscriptions, startup, periodic ticker
      drift.go                — CheckDrift, handlePush, periodicCheck
      reconciler.go           — TriggerSync, handleDeploymentSucceeded/Failed
    federation/               — ActivityPub / ForgeFed (fully built — Phase 3F)
      actor.go                — GetOrCreate, ActorJSON, APID, RSA-2048 key gen
      signatures.go           — HTTP signature sign/verify (draft-cavage-http-signatures)
      inbox.go                — Receive, handleFollow (auto-accept), handleAccept, handleUndo
      outbox.go               — Collection builder, StubCollection
      remote.go               — FetchActor (cached), DeliverActivity (signed POST)
  observability/              — Prometheus metrics + health (fully built — Phase 3E)
    metrics.go                — metric definitions, HTTP middleware, NATS watcher
    health.go                 — Check() returning HealthStatus (DB ping + NATS)
  models/                     — XORM structs + 14 migration files
  config/                     — ENV-driven config, fails fast on missing secrets
  events/                     — NATS EventBus interface + NATSBus + NoOpBus (Healthy() bool)
web/                          — //go:embed target for the built React SPA
frontend/
  src/
    pages/                    — route-level page components
    components/               — shared UI (AppShell, Sidebar, Header, DiffViewer, etc.)
    ui/
      tokens.ts               — SINGLE SOURCE OF TRUTH for all design tokens
    hooks/                    — custom React hooks
    api/                      — typed API client (fetch wrappers)

Middleware chain — this order is fixed, do not reorder:

Logger → RealIP → Recoverer → Metrics → CORS → CSRF → SessionAuth → AuditLog → Handler

Current Phase Status

Phase Scope Status
1 Auth, Git HTTP, repos, PRs, issues, RBAC, webhooks, LFS, design system Complete
2A NATS event bus, WebSocket hub, audit log Complete
2B CI orchestrator, runner manager, Docker executor, artifact registry Complete
2C Pipeline DAG visualization, dashboard CI upgrade, command palette Complete
3A Environment model + deployment tracking Complete
3B Unified operational timeline Complete
3C Workspaces + secret management (Global → Workspace → Repo → Env) Complete
3D GitOps controller + drift detection + auto-sync Complete
3E Observability (Prometheus /metrics, structured /health, repo health API) Complete
3F Federation handlers (ActivityPub WebFinger, actor, inbox/outbox, HTTP signatures, Follow/Accept) Complete
4 AI diagnostics, signed artifacts, OCI registry, dep/secret scanning Planned

Go Conventions

Git commands — critical rule

Always use exec.Command("git", arg1, arg2, ...) with discrete arguments. Never build a shell string from user input.

// CORRECT
cmd := exec.Command("git", "clone", "--bare", repoURL, destPath)

// WRONG — never do this
cmd := exec.Command("sh", "-c", "git clone "+userInput)

This rule is non-negotiable. It prevents command injection.

Router / handlers

  • Chi router. Route definitions in internal/api/router.go.
  • One handler file per domain area. Keep handlers thin — business logic belongs in domain packages.
  • All POST/PUT/DELETE routes require X-CSRF-Token header matching the session cookie. The CSRF middleware enforces this, but don't remove it from route definitions.
  • There is a shared resolveRepoID(db, w, r) function in internal/api/handlers/repo_lookup.go — use it instead of duplicating repo resolution logic.

Database

  • XORM for all DB access. Structs in internal/models/.
  • Migrations are numbered files in internal/models/migrations/. Always add a new file; never edit existing ones. Current highest: 014.
  • No raw SQL strings built from user input.

Events

  • Publish to NATS via bus.Publish(events.SubjectXxx, payload) where the subject is a constant from internal/events/subjects.go.
  • Payload types are in internal/events/types.go — use them for type-safe unmarshaling in subscribers.
  • NoOpBus silently drops events when NATS_URL is unset — the app must work normally without NATS.

Secrets and config

  • All secrets come from environment variables via internal/config/.
  • Never hardcode secrets, tokens, or credentials anywhere.
  • SESSION_SECRET ≥ 32 chars. CSRF_SECRET = exactly 32 chars.

Error handling

  • Return errors up the call stack. Don't swallow them silently.
  • HTTP handlers use consistent JSON error responses — follow the pattern in jsonError / jsonOK in internal/api/handlers/helpers.go.

TypeScript / React Conventions

Design tokens — critical rule

All spacing, color, and sizing values must come from frontend/src/ui/tokens.ts. Do not introduce new hardcoded pixel values or color hex codes.

// CORRECT — use token classes via Tailwind
<div className="p-sm gap-xs">

// WRONG — arbitrary values
<div style={{ padding: "12px" }}>

Grid system

  • Base unit: 8px. All spacing is multiples of 4px (xs) or 8px (sm).
  • Touch targets: 44px minimum height/width on all interactive elements (buttons, links, icon buttons).

Dark mode

  • Use Tailwind v4 @variant dark — not hardcoded dark: classes unless inside a component that explicitly handles both.
  • Colors must work in both light and dark modes. Test both.

Component patterns

  • AppShell wraps all authenticated pages. Don't bypass it.
  • Sidebar has three states: expanded (320px), collapsed (56px), mobile bottom bar. Respect all three.
  • Mobile-first: design for 375px, enhance for 1440px. Use the BottomTabBar for mobile nav — don't add new nav patterns.
  • Loading states: use Skeleton components for perceived performance, not spinners.
  • Mobile code review: use the MobileComment bottom-sheet pattern — not modals.

API calls

  • Use the typed API client in frontend/src/api/ — don't write raw fetch calls in components.
  • Always include X-CSRF-Token header on mutating requests (the client does this automatically via getCSRFToken()).

What NOT to Do

  • No shell string injection — see Go conventions above; always discrete exec.Command args
  • No hardcoded secrets — everything via env
  • No skipping CSRF — all mutating routes require it
  • No arbitrary design valuestokens.ts is the law
  • No new color tokens without discussion — the existing palette covers all cases
  • No modal-heavy UX — progressive disclosure; avoid deep modal chains
  • No YAML-centric UI — pipeline and GitOps config should feel operational, not config-file editing
  • No editing existing migration files — always add a new numbered migration
  • No direct fmt.Println for logging — use log.Printf so structured logs work correctly

Testing

make test     # Go tests (go test ./...) + Vitest (frontend unit tests)
make lint     # go vet + ESLint
  • Go: test files live alongside source files (*_test.go)
  • Frontend: Vitest for unit tests, component tests alongside components
  • All UI changes must be manually verified at 1440px desktop and 375px mobile

Key Files Reference

File Purpose
internal/api/router.go All route definitions — start here for backend work
internal/api/handlers/repo_lookup.go Shared resolveRepoID helper
internal/models/ All XORM models + 13 migration files
internal/config/config.go All env vars, fail-fast validation
internal/events/subjects.go All NATS event subject constants
internal/events/types.go Typed event payload structs
internal/domain/git/binary.go Git binary wrapper — safe exec patterns, RevParse, BlobCat, etc.
internal/domain/ci/orchestrator.go CI DAG orchestrator
internal/domain/ci/executor.go Docker job executor + log streaming
internal/domain/gitops/controller.go GitOps reconciliation controller
internal/domain/gitops/drift.go CheckDrift, drift detection logic
internal/observability/metrics.go Prometheus metric defs, HTTP middleware, NATS watcher
internal/observability/health.go Check() — DB ping + NATS liveness
internal/api/handlers/observability.go /health + /repos/.../health handlers
internal/api/handlers/environment.go Environment + deployment CRUD
internal/api/handlers/gitops.go GitOps config + drift HTTP endpoints
internal/api/handlers/federation.go ActivityPub WebFinger, actor, inbox, outbox, followers/following
internal/domain/federation/actor.go Actor lifecycle — GetOrCreate, ActorJSON, key generation
internal/domain/federation/signatures.go HTTP signature sign/verify
internal/domain/federation/inbox.go Receive + Follow/Accept auto-accept flow
internal/domain/federation/remote.go FetchActor (cached remote actors), DeliverActivity
internal/api/handlers/secret.go Scoped secret management
internal/api/handlers/workspace.go Workspace + member management
internal/api/middleware/audit.go Audit log middleware
frontend/src/ui/tokens.ts Design token source of truth
frontend/src/components/AppShell.tsx Root layout wrapper
frontend/src/api/client.ts Typed API client with CSRF handling
.env.example All environment variables with documentation
CLAUDE.md Developer guide (rules overlap with this file — CLAUDE.md takes precedence on conflicts)

Running Locally

cp .env.example .env     # fill SESSION_SECRET and CSRF_SECRET
make docker-up           # PostgreSQL + NATS via Docker Compose
make migrate             # run XORM migrations (currently 014)
make dev                 # Go :8080 + Vite :5173

CI execution requires Docker to be running locally. If unavailable, the runner logs a warning and CI jobs are queued but not executed.