Files
steve 0526bada90 docs: land prior ADR + prompt updates
Commit pre-existing uncommitted working-tree changes that predate the
license/public-readiness work — NOT authored in this session, just flushed so
they're not lost: ADR-0003/0005/0009/0012 edits, the new ADR-0013
(embeddings-bypass + two-slot residency, already referenced by CLAUDE.md), and
the phase-0..3 prompt revisions + prompts/README.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 20:33:39 -04:00

91 lines
3.3 KiB
Markdown

# phase-1.md — Scaffold, config, store, health, CI, Dockerfile
Re-ground: skim `CLAUDE.md`, `docs/adr/` (esp. 0002 placement, 0008 SQLite,
0010 security), and `progress.md`. Plan, get my approval, then implement.
## Objective
A buildable, testable, containerized skeleton with the persistence layer and a
health endpoint — no Ollama logic yet.
## Tasks
- Initialize the module: `gitea.stevedudenhoeffer.com/steve/foreman`, Go 1.26.
- Layout per CLAUDE.md: `cmd/foreman/main.go` (single binary, subcommand
skeleton: `serve`, plus stubs for `submit`, `jobs`, `ps`), `internal/config`,
`internal/store`, `internal/server`. Don't create empty packages for later
phases.
- `internal/config`: load from env into a struct — `FOREMAN_ADDR` (listen addr,
default `:8080`), `FOREMAN_OLLAMA_URL` (target, required), `FOREMAN_OLLAMA_TOKEN`
(optional outbound bearer to the target, for Ollama-Cloud-style auth),
`FOREMAN_TOKEN` (optional inbound bearer foreman requires of its callers),
`FOREMAN_EMBED_MODEL` (the always-resident embedder, e.g. `nomic-embed-text`),
`FOREMAN_DB_PATH`, `FOREMAN_POLL_INTERVAL`. Namespace **every** key under
`FOREMAN_` (do not use bare `OLLAMA_*`, which collide with real Ollama client
vars). Provide a `.env.example` documenting every key.
- `internal/store`: SQLite via `modernc.org/sqlite`, WAL mode, with an embedded
migration for the `jobs` and `artifacts` tables (schema sketch in ADR-0008 /
ADR-0006). Include open/close, migrate-on-start, and basic CRUD with tests
(use a temp-file DB per test).
- `internal/server`: `net/http` server with `GET /healthz` (returns ok + a
placeholder degraded flag for later) and optional bearer-token middleware
(validate `Authorization: Bearer` only when `FOREMAN_TOKEN` is set).
- `.gitea/workflows/ci.yaml` — mirror `go-llm`'s, single-module:
```yaml
name: CI
on:
push: { branches: ["*"] }
pull_request: { branches: ["*"] }
jobs:
build:
name: Build & Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with: { go-version: "1.26" }
- run: go mod download
- run: go build ./...
- run: go vet ./...
- run: go test -race -count=1 ./...
tidy:
name: Tidy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with: { go-version: "1.26" }
- run: |
go mod tidy
git diff --exit-code go.mod go.sum
```
- `Dockerfile` — multi-stage, pure-Go static build (works because modernc is
CGO-free):
```dockerfile
FROM golang:1.26 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /out/foreman ./cmd/foreman
FROM gcr.io/distroless/static-debian12
COPY --from=build /out/foreman /foreman
EXPOSE 8080
ENTRYPOINT ["/foreman", "serve"]
```
- `.gitignore` (use the project's), `README.md` (what + quickstart), and seed
`progress.md` with the M0 entry.
## Definition of done
- `go build/vet/test -race` all green; `store` has passing tests.
- `docker build .` succeeds; running the image serves `GET /healthz`.
- `cmd/foreman serve` boots, reads config from env, opens/migrates the DB.
Wrap up: append to `progress.md`, commit on `phase-1-scaffold`, summarize what's
done and what Phase 2 will need.