82 lines
6.1 KiB
Markdown
82 lines
6.1 KiB
Markdown
# Architecture
|
|
|
|
```
|
|
Status: Current
|
|
Owner: <who maintains this>
|
|
Last reviewed: <YYYY-MM-DD>
|
|
Governs: docs/architecture/**
|
|
Review trigger: Any new module, any change to a module boundary or a data shape
|
|
```
|
|
|
|
## What belongs here
|
|
|
|
How the thing is built, for somebody who has to change it:
|
|
|
|
- **Module boundaries** — what each part owns, and what it is not allowed to
|
|
know about. The boundaries are the architecture; everything else is detail.
|
|
- **Data shapes** — the structures that outlive a single function, especially
|
|
anything persisted or sent over a wire.
|
|
- **Reference manuals** — the long documents that answer "how does X work"
|
|
without requiring a full read of X.
|
|
- **Decisions with consequences** — why this database, why this concurrency
|
|
model, why this dependency. Include the option that was rejected and what it
|
|
would have cost, because that is the part nobody can reconstruct later.
|
|
|
|
## Documents here
|
|
|
|
- **`GUARDS.md`** — how to write a check that actually checks. Read it before
|
|
adding a structural test or a probe; every rule in it was learned from a guard
|
|
that had been green over something broken.
|
|
|
|
## What ships in this folder
|
|
|
|
Working code, not just prose. Copy what a project needs and delete the rest —
|
|
these are a starting point with the arguments already made, not a framework.
|
|
|
|
This table is the one copy of that list. [`docs/TOOLS.md`](../TOOLS.md) is the
|
|
signpost every project is expected to have — it points here rather than
|
|
repeating it, and answers the two questions this table does not: which scripts
|
|
can stop you, and where to start in a fresh clone.
|
|
|
|
| Path | What it is |
|
|
| --- | --- |
|
|
| `scripts/release.sh` | version bump, guards, build, verify, push, prune. Refuses to build on a half-run test suite or a malformed public origin. |
|
|
| `scripts/verify.sh` | the repo's own checks, in one command |
|
|
| `scripts/check-env.sh` | which variables are set, which are missing, before anything reads them |
|
|
| `scripts/migrate.sh` | apply and report migrations, including the ones that run outside a transaction |
|
|
| `scripts/backup.sh` | a dump that is verified before it is trusted |
|
|
| `scripts/restore-check.sh` | the other half of `backup.sh`: restores the newest dump into a scratch database it creates and drops, counts the tables, and **times it** — the number an incident actually needs. Never accepts a target, because naming one is the mistake `--clean` punishes. |
|
|
| `scripts/healthcheck.sh` | a liveness tick with the URL written down rather than re-derived each run |
|
|
| `scripts/status.sh` | what is deployed, and whether it matches this checkout |
|
|
| `scripts/controls.sh` | which operational controls this project actually has, each row saying **how** it is known: measured, declared, n/a, or unknown. An unknown is never rendered as absent — "I could not tell" and "it is not there" send people to different places. |
|
|
| `scripts/dev.sh` | bring the local stack up |
|
|
| `scripts/scaffold.sh` | lay out a new project in this shape |
|
|
| `scripts/doc-triggers.py` | which documents a **pending** change fires, read from their `Governs:` headers. The `Review trigger` on each document names the change that should send somebody back to it; this is the check that asks before the commit rather than after |
|
|
| `scripts/prove-guard.sh` | breaks the thing a guard protects, requires the guard to go red, restores the file from a trap. `GUARDS.md` §1 written out as a command, including the count — one failing test reported on six lines is not six failures |
|
|
| `scripts/commit-mine.sh` | commits only the paths you name, by pathspec, after the secret scan. For a tree something else is also writing: what anyone else has staged is reported and left exactly as it was |
|
|
| `scripts/doc-claims.sh` | every file a document names must exist, and (`--covers`) every file that exists is named — the second is the one that catches a list missing rows |
|
|
| `scripts/duplication.py` | code that exists twice, tuned so what it reports is worth reading |
|
|
| `scripts/dead-code.py` | exports nothing imports, and assets nothing renders |
|
|
| `scripts/secrets.sh` | credential shapes in a staged diff, using the project's own patterns where it has them |
|
|
| `scripts/audit-gate.mjs` | high/critical advisories in **production** dependencies, with the allowlist npm does not have. An entry must say why the advisory cannot reach this app, what would make it reachable, and what retires the entry — three fields, so a waiver stays falsifiable. Exits 2 when nothing was checked. |
|
|
| `scripts/forgejo-issue.py` | file and close issues in the tracker convention, with every rule of it as a check |
|
|
| `scripts/deploy.py` | update the running stack to a published image. Publishing and deploying are separate; this is the second one. **The only copy** — it existed twice and drifted (#209); the `privacyllc-deploy` skill's is now a symlink to this file. Identity-free by design: it reads `DEPLOY_IMAGE`, `DEPLOY_STACK_ID`, `DEPLOY_CONTAINER` and `DEPLOY_SITE_URL` from the environment and refuses to run without them, so each project supplies its own via a wrapper. Never hard-code one here — least of all the site URL, which is frozen into the image at build time. |
|
|
| `scripts/release-notes.mjs` | tags the release and writes its notes, grouped by the commit types the message hook already enforces. Runs after `release.sh` has published, so a failure here cannot cost an image. Scrubs credential shapes out of commit subjects first — the body goes to a public repository. |
|
|
| `githooks/` | pre-commit, commit-msg, post-commit — see its README for the one install command |
|
|
|
|
Every script takes its configuration from the environment and hard-codes nothing
|
|
about any particular deployment. `check-env.sh` is the one to run first.
|
|
|
|
## What does not belong here
|
|
|
|
- Product intent — that is `docs/planning/PROJECT_PLAN.md`
|
|
- What it should feel like — that is `docs/design/`
|
|
- What happened while building it — that is a history log, not architecture
|
|
|
|
## A note on drift
|
|
|
|
Architecture docs go stale faster than any other kind, because code changes
|
|
under them silently. This is exactly what the **Review trigger** line is for:
|
|
name the change that should send somebody back here, and a reader can tell
|
|
whether the trigger has fired.
|