docs: adopt project template, retire the markdown backlog
This repository is the one the template's README describes: 205 issues, zero
milestones, and severity labels spelled "P0 Critical" / "P1 High" / "P2 Medium",
which privacyllc.dev reports as NOT ADOPTED rather than as 87% complete.
Six markdown records described the same work and none pointed at the tracker.
Two of them said the project was in "Phase 5" while the code was at 0.9.3.
Migrated, then deleted in this commit:
FUTURE.md -> docs/history/BATCH_LEDGER.md (Archived). Its open
items were all already filed as issues, so nothing
needed migrating into the tracker
HISTORY.md -> docs/history/DEVELOPMENT_LOG.md, verbatim, 0 lines lost
DEVELOPMENT_LOG.md -> the same file, as a second labelled block. Not
interleaved: the changelog has three duplicated version
headings, so one date order would have implied more
than the record supports
PROJECT.md -> docs/planning/PROJECT_PLAN.md
STRUCTURE.md -> the agent pipeline into README.md; its versioning rules
retired
BUILD_SUMMARY.md -> BATCH_LEDGER.md. Its embedded SQL schema deliberately
NOT carried: it predated the UNIQUE constraint on
leads.email, and server/index.js owns the schema
SCRIPTS.md -> docs/TOOLS.md, corrected for the SSR + prerender build
Moved with history (git detects all four as renames):
OVERHAUL_PLAN.md, review.md, project-requirements.md, docs/zoho-setup.md
Kept because this project earned them: the five-agent pipeline, the design
system in OVERHAUL_PLAN.md (Status: Current, with a front-note saying which half
is history), the positioning argument in REDESIGN_REVIEW.md, and REQUIREMENTS.md
whole, including its change policy.
Deleted from the template because they do not apply, each said out loud in
DOC_TRUST_MAP.md: QA pass I (no money moves), the authorisation checklist group
and the session-token row (no accounts, no sessions), and one PRECAUTIONARY
paragraph in SECURITY.md about holding credentials on behalf of users — there
are none, and PROJECT_PLAN.md records accounts as out of scope. Pass H was kept
and rewritten: its authorisation half does not apply, its what-a-stranger-can-
reach half is the most exposed surface here.
Also removed: main.js, the old static site's hash router, referenced by nothing
and preserved in .drop/; and test-results/.last-run.json, a May Playwright
artifact reading {"status":"failed"} for a suite that does not exist.
The repository was made private on Forgejo before this commit. That is what let
the internal history be committed rather than exempted — null/fruit-fall is
already private and reports normally.
Two defects found on the way in and fixed here: zoho-setup.md told admins to
edit `server/zoho/`, a directory that has never existed in any commit (the
mapping is in server/index.js), and README.md's route list still advertised
/8x8, removed at 0.6.6, while omitting /privacy-policy.
Branding: icon.webp and logo.webp converted from this project's own marks in
assets/. banner.webp is absent and is filed as an issue rather than faked.
Verified: verify.sh 3/3, doc-claims 71 claimed paths all present, backup and a
first-ever restore of the live leads database (2 tables, 3 rows, under 1s).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:19:02 -05:00
# Tools — where the scripts are, and which ones can stop you
```
Status: Current
Owner: _null
Last reviewed: 2026-08-18
Governs: scripts/**, .githooks/**, package.json — the tooling, and which of
it can stop you
Review trigger: Any script added to, removed from or repurposed in scripts/; any
change to which of them gates; any change to the npm scripts
```
> A signpost, deliberately. Every project that adopts this template has a
> `docs/TOOLS.md`, so "read `docs/TOOLS.md` first" is an instruction that works
> without knowing anything about the project — which is the whole reason this
> file exists at a fixed path.
## The list is not here
**[`architecture/README.md`](architecture/README.md)** holds the table of what
ships in `scripts/` and what each one is. That is the one copy.
A second table here would be two records of one fact, and the other one would
never hear that a script was renamed — the failure `DOC_TRUST_MAP.md` exists to
prevent, applied to the tooling instead of the documents. So this file answers
the questions that table does not, and points at it for everything else.
## If this project has fewer scripts than the template lists
That is the intended state, not a broken copy. The template's `scaffold.sh`
writes the documents and deliberately leaves the scripts behind — *"an
unconfigured `release.sh` landing in every new repository is a loaded gun, not a
head start"* — so they are taken one at a time, having been read.
This project took ten of them on 2026-08-18 and declined the rest. What it
declined, and why, is in `docs/history/DEVELOPMENT_LOG.md` under that date. The
short version: no `release.sh` or `deploy.py` until the roll-forward path to
nebula is written down, and no `controls.sh` until there are backups for it to
report on.
## Which ones can stop you
Not in a table, because the honest answer lives in each script's own header and
would go stale here. The rule that matters:
**Exit code `2` is never a pass.** These scripts distinguish "the check ran and
found nothing" from "the check did not run", because those look identical from
the outside and only one of them is evidence. A CI step or a hook that treats a
`2` as success has quietly turned the check off. Each script states its codes at
the top; read them there.
In this repository specifically, `check-env.sh` and `verify.sh` will both exit 2
if you gut their configuration, and `preflight.sh` exits 2 when the site is
simply unreachable — which is the case you most want to tell apart from a pass.
The hooks are the other place work gets stopped. See below.
## Where to start in a fresh clone
```bash
npm install
git config core.hooksPath .githooks # per clone. Not optional. See below
bash scripts/check-env.sh --file .env # what is configured, before anything reads it
bash scripts/secrets.sh --tracked # what is already committed
```
Then [`architecture/GUARDS.md` ](architecture/GUARDS.md ) before you write a check
of your own — how to write one that can actually fail.
## The hooks
2026-08-18 01:22:33 -05:00
Four, in `.githooks/` , because `.git/hooks` is not versioned and a hook living
docs: adopt project template, retire the markdown backlog
This repository is the one the template's README describes: 205 issues, zero
milestones, and severity labels spelled "P0 Critical" / "P1 High" / "P2 Medium",
which privacyllc.dev reports as NOT ADOPTED rather than as 87% complete.
Six markdown records described the same work and none pointed at the tracker.
Two of them said the project was in "Phase 5" while the code was at 0.9.3.
Migrated, then deleted in this commit:
FUTURE.md -> docs/history/BATCH_LEDGER.md (Archived). Its open
items were all already filed as issues, so nothing
needed migrating into the tracker
HISTORY.md -> docs/history/DEVELOPMENT_LOG.md, verbatim, 0 lines lost
DEVELOPMENT_LOG.md -> the same file, as a second labelled block. Not
interleaved: the changelog has three duplicated version
headings, so one date order would have implied more
than the record supports
PROJECT.md -> docs/planning/PROJECT_PLAN.md
STRUCTURE.md -> the agent pipeline into README.md; its versioning rules
retired
BUILD_SUMMARY.md -> BATCH_LEDGER.md. Its embedded SQL schema deliberately
NOT carried: it predated the UNIQUE constraint on
leads.email, and server/index.js owns the schema
SCRIPTS.md -> docs/TOOLS.md, corrected for the SSR + prerender build
Moved with history (git detects all four as renames):
OVERHAUL_PLAN.md, review.md, project-requirements.md, docs/zoho-setup.md
Kept because this project earned them: the five-agent pipeline, the design
system in OVERHAUL_PLAN.md (Status: Current, with a front-note saying which half
is history), the positioning argument in REDESIGN_REVIEW.md, and REQUIREMENTS.md
whole, including its change policy.
Deleted from the template because they do not apply, each said out loud in
DOC_TRUST_MAP.md: QA pass I (no money moves), the authorisation checklist group
and the session-token row (no accounts, no sessions), and one PRECAUTIONARY
paragraph in SECURITY.md about holding credentials on behalf of users — there
are none, and PROJECT_PLAN.md records accounts as out of scope. Pass H was kept
and rewritten: its authorisation half does not apply, its what-a-stranger-can-
reach half is the most exposed surface here.
Also removed: main.js, the old static site's hash router, referenced by nothing
and preserved in .drop/; and test-results/.last-run.json, a May Playwright
artifact reading {"status":"failed"} for a suite that does not exist.
The repository was made private on Forgejo before this commit. That is what let
the internal history be committed rather than exempted — null/fruit-fall is
already private and reports normally.
Two defects found on the way in and fixed here: zoho-setup.md told admins to
edit `server/zoho/`, a directory that has never existed in any commit (the
mapping is in server/index.js), and README.md's route list still advertised
/8x8, removed at 0.6.6, while omitting /privacy-policy.
Branding: icon.webp and logo.webp converted from this project's own marks in
assets/. banner.webp is absent and is filed as an issue rather than faked.
Verified: verify.sh 3/3, doc-claims 71 claimed paths all present, backup and a
first-ever restore of the live leads database (2 tables, 3 rows, under 1s).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:19:02 -05:00
there protects exactly one clone.
| Hook | What it runs here |
| --- | --- |
| `pre-commit` | `scripts/secrets.sh` on the staged diff, then `npm run build` when source is staged |
| `commit-msg` | refuses a message with no conventional type |
| `post-commit` | **pushes to `origin`** |
2026-08-18 01:22:33 -05:00
| `pre-push` | refuses a push that leaves uncommitted or staged edits behind |
`pre-push` is not the template's — it is the useful half of a hook that was
already sitting in this checkout's `.git/hooks` before adoption. Setting
`core.hooksPath` would have silently stopped that one running, which is exactly
the failure this directory exists to prevent, so it was moved here instead. Its
third check went: it refused whenever the branch was ahead of its remote, which
is the precondition for pushing at all, so it fired on every real push and told
you to re-run with `--no-verify` . A guard that can never pass teaches people to
bypass the ones beside it.
docs: adopt project template, retire the markdown backlog
This repository is the one the template's README describes: 205 issues, zero
milestones, and severity labels spelled "P0 Critical" / "P1 High" / "P2 Medium",
which privacyllc.dev reports as NOT ADOPTED rather than as 87% complete.
Six markdown records described the same work and none pointed at the tracker.
Two of them said the project was in "Phase 5" while the code was at 0.9.3.
Migrated, then deleted in this commit:
FUTURE.md -> docs/history/BATCH_LEDGER.md (Archived). Its open
items were all already filed as issues, so nothing
needed migrating into the tracker
HISTORY.md -> docs/history/DEVELOPMENT_LOG.md, verbatim, 0 lines lost
DEVELOPMENT_LOG.md -> the same file, as a second labelled block. Not
interleaved: the changelog has three duplicated version
headings, so one date order would have implied more
than the record supports
PROJECT.md -> docs/planning/PROJECT_PLAN.md
STRUCTURE.md -> the agent pipeline into README.md; its versioning rules
retired
BUILD_SUMMARY.md -> BATCH_LEDGER.md. Its embedded SQL schema deliberately
NOT carried: it predated the UNIQUE constraint on
leads.email, and server/index.js owns the schema
SCRIPTS.md -> docs/TOOLS.md, corrected for the SSR + prerender build
Moved with history (git detects all four as renames):
OVERHAUL_PLAN.md, review.md, project-requirements.md, docs/zoho-setup.md
Kept because this project earned them: the five-agent pipeline, the design
system in OVERHAUL_PLAN.md (Status: Current, with a front-note saying which half
is history), the positioning argument in REDESIGN_REVIEW.md, and REQUIREMENTS.md
whole, including its change policy.
Deleted from the template because they do not apply, each said out loud in
DOC_TRUST_MAP.md: QA pass I (no money moves), the authorisation checklist group
and the session-token row (no accounts, no sessions), and one PRECAUTIONARY
paragraph in SECURITY.md about holding credentials on behalf of users — there
are none, and PROJECT_PLAN.md records accounts as out of scope. Pass H was kept
and rewritten: its authorisation half does not apply, its what-a-stranger-can-
reach half is the most exposed surface here.
Also removed: main.js, the old static site's hash router, referenced by nothing
and preserved in .drop/; and test-results/.last-run.json, a May Playwright
artifact reading {"status":"failed"} for a suite that does not exist.
The repository was made private on Forgejo before this commit. That is what let
the internal history be committed rather than exempted — null/fruit-fall is
already private and reports normally.
Two defects found on the way in and fixed here: zoho-setup.md told admins to
edit `server/zoho/`, a directory that has never existed in any commit (the
mapping is in server/index.js), and README.md's route list still advertised
/8x8, removed at 0.6.6, while omitting /privacy-policy.
Branding: icon.webp and logo.webp converted from this project's own marks in
assets/. banner.webp is absent and is filed as an issue rather than faked.
Verified: verify.sh 3/3, doc-claims 71 claimed paths all present, backup and a
first-ever restore of the live leads database (2 tables, 3 rows, under 1s).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:19:02 -05:00
`git config core.hooksPath .githooks` is per clone, so every checkout runs it
once. An uninstalled hook fails silently, which is the same class of problem the
hooks exist to prevent.
**Two things worth knowing before you rely on them.**
`pre-commit` is **not** the template's version. That one runs `npx tsc --noEmit`
and `npx vitest run` ; this project has neither TypeScript nor a test runner, so
installing it unchanged would have refused every commit. It runs the secret scan
— which is the reason the hook earns its place here at all, given the Zoho form
tokens that reached four commits before anyone noticed — and then `npm run build`
when `src/` , `server/` , `index.html` , `vite.config.js` or `package.json` is
staged. **That is a build, not a test.** It catches a broken import and will not
catch a broken behaviour.
`post-commit` pushes, and that is the intent — but it has a consequence worth
holding on to: whatever documentation was not in that commit is now behind the
code by one push. That is the mechanical reason `docs/WORK_CYCLE.md` asks for doc
edits in the same commit rather than in a tidy-up afterwards. With this hook
installed, *"I will document it next commit"* means the site has already
published the version without it.
Escape hatches, both loud on purpose: `SKIP_GUARDS=1 git commit …` and
`SKIP_PUSH=1 git commit …` .
## This project's npm scripts
Run from the repository root.
| Command | What it does |
| --- | --- |
| `npm install` | dependencies |
| `npm run dev` | Vite and the Express API together, via `concurrently` . Frontend on 5173, API on 3001 |
| `npm run build` | **three steps** : the client bundle, then an SSR bundle from `src/entry-server.jsx` , then `scripts/prerender.js` , which writes static HTML for every route. This is the only real gate this project has |
| `npm run build:client` | the client bundle alone. Does **not** prerender — do not use it to produce a release |
| `npm run preview` | serve the built client |
| `npm start` / `npm run server` | the Express server alone, serving `dist/` |
| `npm run docker:build` / `docker:run` | build and run the image locally |
| `npm run docker:compose:up` / `:down` / `:logs` | the compose stack |
| `npm run docker:push` | build, tag and push `queue-north-website:dev` to the Forgejo registry |
| `npm run docker:test` | build the image and smoke-test it on 3001 |
**There is no `npm test` , and that is not an omission in this table.** There is
no test runner in the project. `docs/qa/ClaudeQACoverage.md` carries it as a
standing gap.
A liveness check by hand, when you want one without the script:
```bash
curl -s https://qn.isnull.dev/api/health # {"status":"ok","db":"ok","timestamp":"…"}
```
## Adding a script
Put it in `scripts/` , give it a header saying what it does and **which incident
motivated it**, state its exit codes, and add a row to
`architecture/README.md` 's table — this file's `Review trigger` fires on exactly
that.
The bar, from the scripts that are already here: **done by hand three times, or
once with a consequence.** A script written before either of those has no failure
to describe in its header, which is the part that stops the next person deleting
it.