# with.bowden.works — the Bowden Works operations platform (rebuild)

> Orient from [`brief.md`](brief.md) first (genesis + where everything lives); this file
> is the build-session operating rules.

**This project is the ground-up rebuild of work.bowden.works** (time
tracking, invoicing, CC pass-through — growing into multi-agency
project management + bookkeeping). It is being built to feature
parity with MINIMAL owner interaction, following a complete,
adversarially-reviewed plan.

## THE PLAN IS THE BOSS — read before building anything

Everything is specified at **/srv/apps/work/docs/rebuild/** (25 docs):

1. **09-build-plan.md** — the M0–M9 milestone ladder. Find the current
   milestone in BUILD-STATE.md (this directory), do the next unchecked
   item, keep the gates honest.
2. **01-current-system/** — the parity bar: per-feature specs with
   numbered behaviors (B1…Bn) + test specs. Build features FROM THESE,
   not from memory of the old app.
3. **02-domain-model.md / 04-architecture.md** — schema + architecture
   as amended (compensation_terms `kind` model; no sets/tasks tables;
   raw_* import payload; scope() as Select transformer; SQL-side
   aggregation; Pattern B auth per the shipped kit).
4. **05-migration-plan.md** — transforms, nightly rehearsal, replay
   month. **06-test-plan.md** — 415 tests, tier A gates cutover.
5. **07-judgment-calls.md** — 33 decided calls. Do NOT relitigate;
   rian overrules by editing that file.

Auth: follow **/srv/system/id-auth/app-auth/** (README → PATTERN-B.md
→ CHECKLIST.md; copy bw_auth.py semantics). Domain mode = account.

## Operating rules (from 09 §Operating principles — binding)

- **Milestone gates are scripts/checklists, never vibes.** Update
  BUILD-STATE.md every session (what landed, gate status, next item).
- **Single-writer**: only one session at a time touches alembic
  migrations, services/money/, or the migration transforms.
- **The old app (/srv/apps/work) is read-only reference + bugfix-only.**
  Its docs/ discipline (features/, decisions.md, tests) applies HERE
  from day one.
- Deploy: `srv-gw deploy --project with --build`. Port 3126. Postgres
  sidecar binds 127.0.0.1 only. Secrets: mode-600 env files, never in
  chat/logs; `.supabase-export.env` holds the export connection string
  (staged; rian fills it).
- **Parity acceptance for rian**: maintain docs/ACCEPTANCE.md here — a
  living checklist of the scripted gates he can run himself (M3
  side-by-side months, M4 CSV re-upload, M5 bulk-safety replay, M6
  paste-block byte-diff, M7 CC statement). Keep it current as
  milestones land.

## Project facts

- Stack: FastAPI + SQLAlchemy 2/Alembic + Postgres sidecar + Vite React
  SPA (served by FastAPI). Standards: /srv/projects/standards/
  (coding.md → react.md → frontend.md).
- id-auth: rian + adi accounts exist and are granted to
  with.bowden.works. BW Auth client: register at M1 via
  `srv-gw app-client-register --name with --redirect-uri
  https://with.bowden.works/auth/callback --secret-out
  /srv/apps/with/.bw-auth.env` (owner session runs this directly).
- The Supabase source of truth stays live at work.bowden.works until
  cutover (M9). Nothing here may modify it (its .env is read-only
  reference for the harness).
