# 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`](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 sbom/ — SBOM generator (fully built — Phase 4) generator.go — CycloneDX 1.4 generation, auto on pipeline success + on-demand cyclonedx.go — CycloneDX document model and helpers parsers.go — Manifest parsers: go.mod, package.json, requirements.txt, Cargo.toml, Gemfile.lock, pom.xml scanning/ — Secret scanner (fully built — Phase 4) scanner.go — Push-triggered regex scanning, listing, dismissal secrets.go — 15 high/medium severity secret patterns (AWS, GitHub, SSH, JWT, etc.) vulnscan/ — Vulnerability scanner (fully built — Phase 4) scanner.go — OSV API-backed dependency vulnerability scanning osv.go — HTTP client for api.osv.dev/v1 signing/ — Artifact signing (fully built — Phase 4) keystore.go — ECDSA P-256 signing and verification, self-verifying bundles oci/ — OCI registry (fully built — Phase 4) registry.go — Content-addressable blob store, upload sessions, OCI Distribution Spec v1.1 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 + 20 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 | SBOM generation, secret scanning, vuln scanning, signed artifacts, OCI registry, security page | **Complete** | | 5 | Deployment promotions, rollback visualization | 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. ```go // 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: **020**. - 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. ```tsx // CORRECT — use token classes via Tailwind