# hartlingowners — agents.md

Project constitution. Inherits from `/srv/CLAUDE.md` (server-scope) and
`/srv/apps/CLAUDE.md` (tenant-scope, interim). Only rules meeting the
admission rubric (failure-backed, tool-enforceable, decision-encoding, or
triggerable) belong here — no generic advice a model already applies.

Model-independence: this file is the source of truth. `CLAUDE.md` is a
symlink to it so Claude Code loads the same content.

## Read first (in order)
1. **`brief.md`** — what this project is. Stack DECIDED: Django + Postgres on
   DigitalOcean, three isolated instances. Rebuild scope + phases in
   `.logs/planning/rebuild-plan.md`.
2. **`/srv/projects/standards/coding.md`** then **`/srv/projects/standards/django.md`**
   — the universal baseline + this project's stack standard (the auth-shape
   dispatch, WP-hash migration, private-file serving). Read before touching `main/`.
3. **`.logs/handoff.md`** — newest-first; latest session state.

## Project-specific rules
- **Never send an HTTP request to the live sites' `?garment-prototype-blocks=…`
  trigger URL.** The Sands' old WordPress carried a backdoor plugin whose trigger
  forges an admin session; probing it on production would authenticate an attacker
  path. The staging copy is quarantined; production is rian's to check. Context:
  `.memory/2026-08-24-sands-backdoor-and-doc-leak.md`.
- **The WP password verifier (`main/accounts/hashers.py`) is tested against REAL
  WordPress fixtures, never a reimplementation.** Two silent-failure traps live
  here (WP 6.8 uses HMAC-SHA-384 not plain SHA-384; verify does not trim). If you
  touch it, re-generate fixtures from a real WP install and keep the tests green.

## Operational
- **Type:** custom (gateway-scaffolded nginx static). Port `172.17.0.1:3150`.
- **Manage:** `srv-gw {deploy,restart,logs,status} --project hartlingowners`.
- **Write access:** `hartlingowners-dev` Unix group (setgid + default ACL).
  If a fresh terminal session can't write to project files, run
  `newgrp hartlingowners-dev` once, or `srv-gw fix-permissions --project
  hartlingowners` if a directory the gateway created (e.g. `.logs/`) isn't
  group-writable yet.
- **Deploy semantics:** `srv-gw restart` picks up edits under the volume
  bind-mount; `srv-gw deploy` re-runs `docker compose up -d` for compose /
  `.env` changes.

## Layout (v8 project shape, interim state)
```
/srv/apps/hartlingowners/
├── brief.md            # project genesis (fill me in)
├── agents.md            # this file — project constitution
├── CLAUDE.md            # symlink → agents.md (Claude Code discovery)
├── .logs/
│   ├── .last-deploy     # gateway-owned deploy marker — do not remove
│   ├── planning/        # plans live here (type: plan frontmatter)
│   ├── handoff.md       # append-only, newest-first
│   └── diary.md         # session summaries (interim: manual)
├── .memory/             # project memory (append-only)
├── .archive/             # preserved indefinitely; never auto-purged
├── notes/               # human reference material (contracts, screenshots, …)
│                        # NOT loaded by agents unless referenced from brief.md
├── docker-compose.yml   # gateway-scaffolded — nginx:alpine → ./public
├── nginx.conf           # gateway-scaffolded
├── .env                 # gateway-managed (PROJECT_NAME, PORT)
├── .project.json        # gateway registry entry
└── public/              # static site served at hartlingowners.demoing.info
    └── index.html
```

`.logs/` is scaffolded by the gateway itself (a `.last-deploy` marker appears
on `create-project`), owned by `srv-gateway`. This session added the
human-facing files (`planning/`, `handoff.md`, `diary.md`) alongside it via
`srv-gw fix-permissions`, which grants the project group write access via
ACL. Don't remove `.last-deploy` — it's gateway deploy-state tracking (v8 §3.10.4).

The v8 target is code-in-`instances/` beneath a workspace, but the gateway
hasn't been retooled for `create-project` (workspace) + `add-instance`
(deliverable) yet (T3.1). Until then the code stays at the project root and
this shape is compatible — the workspace docs are in place already.

## Standing tasks (delete when done)
- Phase 1 remaining: private-file download view (auth+authz, noindex/attachment
  headers, download logging) → containerize + deploy the dev instance → DO test
  Droplet. See `.logs/handoff.md` (newest entry) for the ordered next steps.
