# CLAUDE.md — Phase 0: Foundation

## Scope of This File

This file instructs you (Claude Code) to implement **Phase 0 only** of the Seedbox Command Center.

**Do not implement phases 1 through 15.** A separate CLAUDE.md will be written for each subsequent phase after this one is complete and verified. Stay in scope.

## Authoritative Specification

`PROJECT.md` in this repository is the master architecture document. When any question arises about design intent — what a feature should do, how a subsystem should behave, what technology to use — consult `PROJECT.md`. Do not invent design decisions not present there.

If you encounter a genuine ambiguity that `PROJECT.md` does not resolve, document the question and your chosen interpretation in `DECISIONS.md` and proceed. Do not stop to ask the operator unless the ambiguity blocks all forward progress.

## Phase 0 Mission

Build the foundation on which all subsequent phases will stand. After Phase 0, the operator should have:

- A Go module with the directory structure that subsequent phases will populate.
- A binary that builds, runs as a systemd service on Linux, and binds only to the Tailscale network interface.
- SQLite and DuckDB databases initialized with migration tooling.
- Structured logging with credential redaction verified.
- An age-based secrets primitive that encrypts and decrypts blobs.
- A config-as-code directory loader with YAML schema validation and hot reload.
- A health check endpoint that confirms the binary is alive and responsive.
- A frontend skeleton that builds, embeds into the binary, and displays a "Hello Command Center" page when accessed via Tailscale.

Phase 0 produces no user-facing features. It is scaffolding. Subsequent phases add the actual functionality.

## Deliverables Checklist

Phase 0 is complete when every item below is true:

- [ ] `go build ./cmd/command-center` produces a single binary on Linux.
- [ ] The binary boots, reads its config, opens SQLite and DuckDB connections, and serves HTTP on the Tailscale interface only.
- [ ] `GET /api/system/health` returns `200 OK` with a JSON body indicating database connectivity, age key availability, and config load status.
- [ ] `GET /api/system/events` returns recent system events with optional filtering by level and component.
- [ ] The binary fails to start gracefully (with a clear error message) if the Tailscale interface is not present, the age key cannot be loaded, or required config files are missing.
- [ ] `systemd/command-center.service` is present and documented in `DEPLOYMENT.md`. The service auto-restarts on failure with rate limiting.
- [ ] SQLite schema matches Appendix A of `PROJECT.md` exactly for the tables relevant to Phase 0 (see "Phase 0 Database Scope" below). Migration runner applies migrations on boot and records them in `schema_migrations`.
- [ ] DuckDB initializes with the analytical snapshot tables ready for later phases to write to. Empty tables are acceptable; the schema must be correct.
- [ ] Structured logger emits JSON-formatted logs to stdout. Redaction is verified: a test that logs a struct containing `password`, `cookie`, `mam_id`, `token`, `secret`, `authorization`, `api_key`, `set-cookie`, and `raw_cookie` fields produces output with each value replaced by `[REDACTED]`.
- [ ] Age secrets primitive: `internal/secrets` package exposes `Set(key, value)`, `Get(key)`, `Delete(key)` functions. Values are encrypted at rest using an age identity loaded from either the system keyring (preferred) or a file-permissions-restricted key at a documented path (fallback). A unit test verifies round-trip encryption and decryption.
- [ ] Config loader: `internal/config` package reads YAML files from a configurable directory (default `./config` for development, `/etc/command-center/config` for systemd deployment). Each file has a schema. Loader validates on read and on hot-reload via fsnotify. On validation failure, the previous valid config remains in effect and the failure is logged as a structured event.
- [ ] Frontend skeleton: `web/` directory contains a Vite + React + TypeScript + Tailwind + shadcn/ui project. `npm run build` produces a static bundle in `web/dist/`. The Go binary embeds `web/dist` via `go:embed` and serves it at the root path. Accessing `https://<tailscale-hostname>/` returns the "Hello Command Center" landing page.
- [ ] PWA manifest is present at `web/public/manifest.webmanifest` and referenced from `index.html`. Service worker registers without errors. The page is technically installable on iOS (this cannot be tested from your environment, but the manifest must be valid).
- [ ] `PROGRESS.md` is updated with phase completion summary, verification steps for the operator, and any blockers or deviations.
- [ ] `DECISIONS.md` contains any architectural decisions made where `PROJECT.md` was ambiguous.
- [ ] `DEPLOYMENT.md` contains the operator-runnable steps to install the service: install Tailscale, generate the age key, place the binary, install the systemd unit, start the service, verify health.
- [ ] `TESTING.md` documents how to verify Phase 0 manually and how to run the automated tests.
- [ ] A clean checkout of the repository can `go build`, `npm run build`, and pass all unit tests.

## Phase 0 Database Scope

For Phase 0, create the following SQLite tables exactly as specified in `PROJECT.md` Appendix A:

- `secrets`
- `schema_migrations`
- `system_events`
- `audit_log`

The other tables in Appendix A are out of scope for Phase 0 and will be created by subsequent phases via incremental migrations. Do not create them now.

For DuckDB, create the snapshot tables (`ratio_snapshots`, `torrent_snapshots`) so that subsequent phases have a place to write. They will be empty at the end of Phase 0.

The migration runner must support adding new tables in later migrations without rebuilding existing ones. Use one numbered SQL file per migration in `migrations/`.

## Repository Layout

Initialize this structure. Files that are out of scope for Phase 0 should be created as empty placeholders or directories where doing so clarifies the project structure; do not implement subsystems that belong to later phases.

```
/
├── README.md                      # Operator-facing overview (Phase 0: stub OK)
├── PROJECT.md                     # Already exists. Do not modify.
├── CLAUDE.md                      # This file
├── PROGRESS.md                    # Update at every milestone
├── DECISIONS.md                   # Architectural decisions and deviations
├── TESTING.md                     # How to verify Phase 0
├── DEPLOYMENT.md                  # Install steps for Phase 0
├── go.mod
├── go.sum
├── cmd/
│   └── command-center/
│       └── main.go                # Single binary entry point
├── internal/
│   ├── config/                    # YAML loader, file watcher, schema validation
│   ├── db/                        # SQLite + DuckDB clients, migrations
│   ├── secrets/                   # age-based encrypted secrets
│   ├── logging/                   # zerolog with redaction
│   ├── observability/             # health endpoint, system events (Phase 0 only)
│   └── server/                    # HTTP server, route registration
├── web/
│   ├── package.json
│   ├── vite.config.ts
│   ├── tsconfig.json
│   ├── tailwind.config.ts
│   ├── postcss.config.js
│   ├── index.html
│   ├── public/
│   │   ├── manifest.webmanifest
│   │   └── icons/                 # Placeholder PWA icons (SVG sufficient)
│   └── src/
│       ├── main.tsx
│       ├── App.tsx
│       ├── components/            # Empty in Phase 0
│       └── styles/
│           └── index.css          # Tailwind directives
├── config/                        # Default config-as-code directory
│   └── system.yaml                # Minimal Phase 0 config
├── migrations/
│   └── 001_phase0_foundation.sql  # SQLite tables listed above
├── scripts/
│   ├── dev.sh                     # Local dev launcher
│   └── build.sh                   # Build script: npm run build then go build
├── systemd/
│   └── command-center.service     # Unit file for installation
└── test/
    ├── unit/                      # Go unit tests (use standard testing package)
    └── fixtures/                  # Test data
```

Directory names for `internal/auth`, `internal/eventbus`, `internal/integrations/*`, `internal/scrape`, `internal/snapshot`, `internal/intelligence`, `internal/simulation`, `internal/decisions`, `internal/budgets`, `internal/corpus`, `internal/notifications`, `internal/llm`, `internal/bandit`, `internal/audit`, `internal/emergency`, and `internal/webhooks` should **not** be created yet. Subsequent phases will add them. Premature directory creation produces dead-code clutter.

## Working Rules

**Update `PROGRESS.md` continuously.** Every meaningful milestone, write what was completed, what is in progress, what is blocked, and what is next. Format:

```markdown
# Phase 0 Progress

## Completed
- [timestamp or step number] [description]

## In Progress
- [current task]

## Blocked
- [blocker description, if any]

## Next
- [next planned task]
```

**Test as you build.** Each subsystem in `internal/` has a `_test.go` file with at least one meaningful test. Examples:
- `internal/secrets/secrets_test.go` verifies round-trip encryption.
- `internal/config/config_test.go` verifies schema validation rejects malformed YAML.
- `internal/logging/redaction_test.go` verifies all sensitive field names are redacted.
- `internal/db/migrate_test.go` verifies migrations apply cleanly and are idempotent.

**Document deviations.** If you make an architectural decision that differs from `PROJECT.md` — for any reason — write it into `DECISIONS.md` with the reasoning. Do not silently deviate.

**Respect platform conventions.** systemd unit follows standard layout. Go module layout follows Go community conventions (`cmd/`, `internal/`). Frontend follows Vite conventions.

**No secrets in commits.** The age key is generated at first boot and stored outside the repo. Example config files use placeholder values. `.gitignore` excludes `*.key`, `*.db`, `*.db-wal`, `*.db-shm`, `node_modules/`, `web/dist/`, `command-center` (the built binary).

**Single binary.** No external runtime dependencies beyond the operating system and Tailscale. The frontend is embedded. SQLite is statically linked (use `modernc.org/sqlite` for pure-Go, or `mattn/go-sqlite3` with CGO if cross-compilation tradeoffs are acceptable; document choice in `DECISIONS.md`).

**Hot reload for config.** Use `fsnotify` to watch the config directory. Validate before applying. Keep the last-known-good config in memory as a fallback.

## What "Phase 0 Complete" Looks Like

After Phase 0 ships, the operator can:

1. Clone the repository.
2. Run `./scripts/build.sh` and produce a binary plus an embedded frontend.
3. Copy the binary, `config/system.yaml`, and `systemd/command-center.service` to a Linux host with Tailscale already running.
4. Generate the age key (instructions in `DEPLOYMENT.md`).
5. `sudo systemctl enable --now command-center`.
6. Visit `https://<tailscale-hostname>/` from a Tailscale-connected device.
7. See the "Hello Command Center" page.
8. `curl https://<tailscale-hostname>/api/system/health` returns `200 OK` with database and config status.
9. Edit `config/system.yaml`, save, observe the change reflected in logs without restart.
10. Read `PROGRESS.md` and understand exactly what Phase 0 delivered and what comes next.

Subsequent phases will add tracker scraping, authentication, dashboards, and all the features in `PROJECT.md` sections 7 and 8. Phase 0's job is to make those phases possible. Nothing more.

## Begin

Start by creating the directory structure and initializing the Go module. Update `PROGRESS.md` after each subsystem is complete. When the deliverables checklist is fully satisfied, write a final `PROGRESS.md` entry summarizing Phase 0 completion and stop. Do not begin Phase 1.