# Project memory — with.bowden.works

This folder is the long-term memory of the app: what it does and why,
separate from the code that implements it. The discipline is inherited
from the old app (`/srv/apps/work/docs/README.md`) and applies here
from day one (CLAUDE.md operating rules).

During the build (R1), the **parity bar** lives in the founding spec
at `/srv/apps/work/docs/rebuild/` — per-feature behavior specs
(`01-current-system/`), domain model (02), architecture (04), test
catalog (06). Feature docs here describe what has actually SHIPPED in
this app: they cite the founding spec instead of restating it and
record any deltas from it.

## What lives here

```
docs/
  README.md          this file — docs discipline + definition of done
  features/          one .md per shipped feature area (+ INDEX.md)
  decisions.md       append-only ADR log; #001 points at the founding spec
  ACCEPTANCE.md      rian-facing parity checklist, one section per milestone gate
  UNDOCUMENTED.md    docs-debt log (see the DOCS-DEBT rule below)
```

## Definition of done

A **substantive** feature isn't done until ALL of these are true:

1. **Code ships clean** — `make check` passes (ruff + pytest + tsc +
   vitest) and `srv-gw deploy --project with --build` succeeds.
2. **Version bumped** + newest-first CHANGELOG.md line added. The SPA
   footer and `/api/meta` surface it — that's deploy confirmation.
3. **Feature doc updated** in `features/` (Changelog section + the
   affected sections), OR a new doc created from the template below
   plus a row in `features/INDEX.md`.
4. **`decisions.md` ADR appended** if any of these changed:
   - DB schema (new table, FK, or column with semantic meaning — i.e.
     any Alembic migration beyond mechanical housekeeping)
   - a lock / permission / precedence rule
   - a feature replaced or removed another
   - a non-obvious choice was made between viable alternatives
5. **ACCEPTANCE.md updated** if the change lands or alters a milestone
   gate's steps.
6. **BUILD-STATE.md updated** — every session, per CLAUDE.md (what
   landed, gate status, next item).

A feature is **substantive** if it involves any of: a new or altered
Alembic migration; a new page or route; a new service or a significant
change to one; a lock / permission / precedence / eligibility rule; a
new column or constraint on a core table (`time_entries`, `projects`,
`parties`, `engagements`, `invoices`, and kin). Tiny tweaks (copy,
styling, small refactors, internal renames) don't trigger the rule —
if unsure, treat it as substantive.

The workflow is **propose the doc update before writing code**, not
after — drafting the doc first surfaces edge cases.

**DOCS-DEBT rule:** if a feature ships without all of the above,
surface it in the session's final response as
`DOCS-DEBT: <what's missing>` AND append a row to
[UNDOCUMENTED.md](UNDOCUMENTED.md) so the gap stays visible. Cleared
as the docs are written. Don't pretend the feature is done.

## Removing or replacing a feature

This folder is forward-looking, not a history museum. **Removed
features get deleted, not tombstoned:**

1. Append a `decisions.md` ADR explaining the swap — the only place
   the historical context survives. Name the files being deleted.
2. Delete the `features/*.md` file and its `INDEX.md` row. No
   "(LEGACY)" or "deprecated" tombstones.
3. Delete the tests for behaviors that no longer apply.
4. Delete the code — routes, services, models; schema drops ship as
   an Alembic migration.
5. Grep the remaining docs and code for the removed concept; clean up
   dangling references.

## Tests

Test IDs come from the founding spec's catalog
(`/srv/apps/work/docs/rebuild/06-test-plan.md` — the stack-agnostic
behavior list; tier A gates cutover). Feature docs list the IDs they
cover, and test names include the ID. New behaviors discovered during
the build get an ID recorded in the owning feature doc's Tests
section — this project's catalog accretes there until the rebuild
package freezes at cutover.

## Feature doc template

```markdown
# <feature name>

**Status:** in production | partial | planned
**Lives at:** <route(s)> and <code paths>
**Spec:** <link into /srv/apps/work/docs/rebuild/ if ported; omit if new>

## Summary
1–2 sentences. What this feature is, in product terms.

## Why
Dated record of the original ask. Paraphrased from the user's words.

## Behavior
Bullet list of what the feature does. Product terms, not code.

## Constraints & edge cases
Things that can go wrong, things we explicitly handle, things we deferred.

## Permissions
Who can do what. Reference the authz capability grid.

## Open considerations
Future ideas, known limitations, "we should probably do X eventually".

## Tests
- T-XXX-001 … (IDs from 06-test-plan.md or accreted here)

## Changelog
- YYYY-MM-DD — what changed.
```

`deprecated` is deliberately not a status — if we'd mark it
deprecated, we should just remove it.
