0526bada90
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>
91 lines
3.3 KiB
Markdown
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.
|