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

3.3 KiB

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:
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):
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.