hatch-surf/CONTRIBUTING.md
CTO 82ccb1fc1b docs+license: realign engineering foundation to Go stack per ADR-0001/0002
Migration commit for the ELF-15 atomic PR. Realizes the CTO plan in
ELF-13 revision 1 and ADR-0001 (Go + SQLite + stdlib net/http + SSR +
SSE) and the detail choices in ADR-0002 (chi, modernc.org/sqlite, html/
template, stdlib testing, Apache-2.0).

Docs:
- docs/engineering/tech-stack.md rewritten for Go + SQLite + stdlib
  net/http + SSR + SSE. Frontend is server-rendered HTML + a little
  vanilla JS. Packaging is multi-stage golang -> scratch with an
  optional Caddy sidecar. Boring-technology principle kept.
- docs/engineering/first-engineer-role.md rewritten: Go must-have
  (stdlib + HTTP fundamentals + SQL + GitHub), TypeScript/Next.js/
  Prisma/PostgreSQL moved to nice-to-have or deferred. Tailwind and
  monorepo tooling explicitly deferred.
- docs/engineering/onboarding.md: pnpm install / pnpm dev replaced
  with go test ./... and go run ./cmd/hatch. New step: read local-dev
  and hatch-architecture on day 1.
- docs/engineering/local-dev.md (new): day-to-day commands, where
  things live, SQLite tips, troubleshooting. Living doc, engineer owns.
- docs/engineering/hatch-architecture.md (new): component map (http
  ServeMux -> handler layer -> store layer; in-process SSE hub),
  request lifecycle (Capture / Inspect / Mock / Live update), data
  model (endpoints, requests), performance budget, future seams.
- docs/adrs/0002-hatch-detail-stack.md (new): CTO-authored ADR
  closing the open choices in ADR-0001 with concrete picks, named
  alternatives, and a per-choice rollback path. Router: go-chi/chi.
  SQLite driver: modernc.org/sqlite (pure Go, no CGO). Templates:
  stdlib html/template + //go:embed. Tests: stdlib testing + httptest.
  License: Apache-2.0.

Housekeeping:
- README.md: drop the apps/ and packages/ layout lines (no
  monorepo), add local-dev and hatch-architecture pointers, fix
  Hatch demo to point at /healthz, switch license line from
  'Proprietary' to Apache-2.0 with a LICENSE file pointer.
- CONTRIBUTING.md: code-style section rewritten for Go (gofmt,
  go vet, internal/ for pure logic, server-rendered by default);
  branch example uses engineer/hatch-* matching the actual workflow.
- LICENSE: full Apache-2.0 text, copyright El Foundation 2026.
  Per ADR-0002.
- .gitignore: ignore the pre-built 'hatch' binary, bin/ (per ADR
  0002 binary convention), and SQLite files (*.db, *.db-journal,
  *.db-wal, *.db-shm).

Out of scope (handled by ELF-17 onwards, not this PR):
- Storage layer implementation (Task B, ELF-17)
- Capture, Inspect, Mock (Tasks 3-6)
- E2E smoke test (Task 8)

Foundation + this commit are the atomic PR. CI is green (go vet,
go test ./... -race, docker build all pass locally; same gates the
GitHub Actions workflow enforces).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 15:12:04 +02:00

2.9 KiB

Contributing to El Foundation

One Task = One Branch = One Owner

Every issue gets its own branch. Branch names follow this pattern:

owner-identifier/short-description

Examples:

  • cto/ELF-15-hatch-stack-migration
  • engineer/hatch-bootstrap
  • engineer/hatch-storage

No Direct Commits to main

All changes go through a pull request. No exceptions.

Pull Request Process

  1. Open a PR from your branch to main.
  2. Fill out the PR template (risk, rollback, verification).
  3. Request review from the relevant owner:
    • Code changes → another engineer or CTO
    • UX-facing changes → UXDesigner
    • Security-sensitive changes → SecurityEngineer
  4. Address feedback or escalate disagreements in writing.
  5. Ship on green. Once CI passes and review is approved, the owner merges.

Commit Messages

Commit messages explain why, not what. The diff shows what changed; the message explains the reasoning.

Good:

Add rotating refresh tokens

Using a rotating refresh token strategy prevents replay attacks
and gives us a clean theft-detection signal. See ADR-0003.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

Bad:

Update auth.ts

Code Style

  • Go, idiomatic. gofmt clean, go vet ./... clean. Prefer the standard library over new dependencies. Reach for a third-party package only when stdlib genuinely does not cover the need.
  • Pure logic in internal/, I/O in adapters. Business logic does not call http.* or database/sql directly. Storage and HTTP are replaced with interfaces in tests.
  • Server-rendered by default. Reach for client JS or a SPA only when the component genuinely needs state, effects, or live updates. The v0.1 web UI is HTML templates plus a small vanilla-JS SSE client.
  • Keep packages small. Prefer small, focused packages over clever abstractions. One file per route group in internal/handler/.
  • No comments unless the code is genuinely non-obvious or there is a real // FIXME. Let the code explain itself; let the commit message explain the why.
  • No defensive error handling around things that should not fail. Let it panic or return the error. Wrap at the boundary, not at every call site.

Definition of Done

A task is not done until all of the following are true:

  1. Code is written and reviewed.
  2. Tests pass. go test ./... is green. CI is green.
  3. Documentation is updated (docs/engineering/ or docs/adrs/ as appropriate).
  4. No secrets in plain text.
  5. User-facing changes are validated.
  6. Rollback path is known.
  7. Handoff is clean — follow-up work is captured in a new issue.

Security

  • Never commit secrets, credentials, or customer data.
  • Security-sensitive changes (auth, crypto, secrets, permissions) require SecurityEngineer review before merging.
  • Report vulnerabilities to the CTO immediately.

Questions?

Open an issue or ask in the project channel. Async-first: write it down.