11 KiB
Doc Trust Map — which document to believe
Status: Current
Owner: _null
Last reviewed: 2026-08-18
Governs: docs/**
Review trigger: Any doc added, deleted or moved; any change to which doc owns a subject
Fires on: added, deleted, moved
This describes what is actually in this repository, written after everything else was settled. Where it differs from the template it came from, this one is right about this project.
Work items are not in this tree
The sequence of work, the open defects, and the things blocking a release all
live in this repository's issue tracker, not in docs/. Milestones are
batches; issues are deliverables; severity labels are P0, P1, P2 and
release-blocker.
This section exists to stop the next contributor starting a fresh markdown
to-do list. It has already happened here. Before 2026-08-18 this project
kept its work in FUTURE.md, a changelog in HISTORY.md, an agent log in
DEVELOPMENT_LOG.md, and phase checklists in PROJECT.md, STRUCTURE.md and
README.md — six records, beside 205 issues in a tracker that none of them
pointed at. Two of those documents still described the project as being in
"Phase 5" while the code was at 0.9.3, and nothing anywhere said so.
| Question | Answer lives in |
|---|---|
| What are we building, and for whom? | docs/planning/PROJECT_PLAN.md |
| What standards does the code have to meet? | docs/planning/REQUIREMENTS.md — and they need _null's approval to change |
| What is the sequence of work? | milestones in the tracker |
| What is left in this batch? | open issues under that milestone |
| What is broken right now? | issues labelled P0 / P1 / P2 |
| What makes a release wrong? | issues labelled release-blocker |
| What is the next action? | the nextAction field on the project at privacyllc.dev — the newest entry in docs/history/DEVELOPMENT_LOG.md says what it was then |
| What is blocking us? | the tracker, for the work; the blockers table at privacyllc.dev, for the stakeholder-facing version |
| What do I do when a piece of work is finished? | docs/WORK_CYCLE.md |
| What is deployed, and what do I do when it breaks? | docs/OPERATIONS.md |
| What happened, and when? | docs/history/DEVELOPMENT_LOG.md |
| Why is it shaped like this? | docs/history/HISTORY.md — decisions, and what was tried and dropped |
| What were the batches, before the tracker? | docs/history/BATCH_LEDGER.md — archived, must not be updated |
| Did QA pass, and what does the tester think? | docs/qa/ClaudeReport.md |
| What did QA actually reach? | docs/qa/ClaudeQACoverage.md — and here, the answer is nothing yet |
| How is it built? | docs/architecture/README.md |
| How does the CRM integration work? | docs/architecture/zoho-setup.md |
| What should it look like? | docs/design/OVERHAUL_PLAN.md |
| What should it sound like? | docs/design/REDESIGN_REVIEW.md |
| Which script do I run, and can it stop me? | docs/TOOLS.md — the signpost; docs/architecture/README.md has the table |
| What runs before a commit? | .githooks/ |
| How do I write a check that will actually catch something? | docs/architecture/GUARDS.md |
Next action and blockers are recorded at the end of every piece of work, not
when somebody asks. docs/WORK_CYCLE.md holds that procedure and the reason
each step is in it.
Folder layout
| Folder | Contents |
|---|---|
docs/planning/ |
PROJECT_PLAN — the vision. REQUIREMENTS — the engineering standards. Not the schedule; that is the tracker |
docs/qa/ |
ClaudeQAPlan (playbook), ClaudeQACoverage (what each pass reached), ClaudeReport (the verdict) |
docs/architecture/ |
README — boundaries, schema, response shapes, the script table. GUARDS — how to write a check. zoho-setup — the CRM manual |
docs/design/ |
OVERHAUL_PLAN — the visual system. REDESIGN_REVIEW — positioning and tone |
docs/security/ |
SECURITY — threat model and third parties. SECURITY_CHECKLIST — the pre-release list |
docs/history/ |
DEVELOPMENT_LOG (dated, append-only), HISTORY (the narrative), BATCH_LEDGER (archived) |
docs/data/ |
the branding marks privacyllc.dev renders for this project |
docs/ root |
this map; WORK_CYCLE; TOOLS; OPERATIONS |
README.md stays at the repository root; it is the landing page and moving it
breaks that. Everything else lives under docs/.
What this project keeps that the template does not describe
docs/planning/REQUIREMENTS.md— engineering standards with a change policy attached. It is not the plan and not the architecture; it is the set of rules every agent works to, and it predates the template. Kept whole.docs/design/OVERHAUL_PLAN.md— 25 KB, and two documents in one file. Its design brief onward is the live token and layout authority; its earlier migration-phase and agent-plan sections describe a rebuild that finished. Its own front-note says which half is which. Splitting it would have risked losing prose that nothing else records, so it was not split.docs/architecture/zoho-setup.md— written for a non-technical reader. Note the trap in its own header: it documents the OAuth path, and production runs WebToLead.- The agent pipeline — Scarlett, Neo, Private Hudson, Bishop, Ripley — is in
README.md, not in this tree, because it is how work is dispatched rather than a subject anything is authoritative about..learnings/holds four agents' notes and is gitignored.
What the template carries that this project deleted
Recorded so a reader can tell a deliberate absence from an oversight.
| Deleted | Why |
|---|---|
ClaudeQAPlan.md pass I — money flowing backwards |
no money moves through this site. A pass that never applies is noise |
SECURITY_CHECKLIST.md — the authorisation group, and the session-token row |
there is no login, no session, no role and no per-user data anywhere in the product |
SECURITY.md — the (precautionary) bring-your-own-credential paragraph |
a precautionary rule, dropped deliberately. It describes holding credentials on behalf of users; there are no users. PROJECT_PLAN.md records accounts as out of scope, which is what makes it safe to drop |
Every other (precautionary) marker was kept. OPERATIONS.md was kept in full —
this is a deployed service with a live origin, a named host and a database.
Pass H was kept and rewritten rather than deleted. Its authorisation half does not apply; its what a stranger can reach and exhaust half is the most exposed surface this project has.
A fifth severity label exists, and is frozen
P3 sits on 21 closed issues from before this repository adopted the
convention. It is not one of the four names the Command Center queries, so a
defect filed P3 today would be counted by nothing.
It was kept rather than deleted because removing it would erase the severity
record on those 21 issues, and merged into P2 would misstate them. Nothing
new gets it. New defects use P0, P1, P2 or release-blocker.
Source-of-truth ladder
When two sources disagree, believe them in this order:
- Verified code behaviour — read the source. Note that on this project "run the tests" is not available: there are none
- The issue tracker — for anything about state of work
- Specialist docs — authoritative for their own subject only
- History and logs — a record of then, not a description of now
A document that describes work as done is describing what was true when it was written. The tracker is describing now.
The status header
Every document in this tree opens with one, immediately after its H1 — and so
do the documents at the repository root, which scripts/doc-triggers.py reads
alongside this tree. The root is read one level deep only.
Status: Current | Draft | Superseded | Archived
Owner: <who maintains this>
Last reviewed: <YYYY-MM-DD>
Governs: <paths or subject this document is authoritative for>
Review trigger: <the change that should send someone back to this file>
Fires on: <optional — added, deleted, moved, changed>
Exactly those four status words. A document whose status falls outside the
list is reported as having an unknown one rather than being quietly accepted.
Historical is the word this convention used to have and deliberately dropped —
Archived covers it.
Review trigger is the line that matters. "Last reviewed" ages on its own and
a reader cannot tell a current document from an abandoned one by looking at it;
a trigger names the event that should bring somebody back. A header carrying
Status without Review trigger is reported as incomplete — that combination
looks finished and is not.
Governs is a comma-separated list, and an entry may explain itself after the
glob with a spaced dash — docs/data/** — the assets privacyllc.dev renders.
doc-triggers.py cuts the entry there and reads the globs from the left of it.
Use that form and no other. A gloss in parentheses, or after a colon, is not
recognised: the whole entry becomes the glob, matches nothing, and the document
is silently never fired.
Fires on is optional and only for the case where Governs: is much broader
than the trigger. This file is the extreme of that gap — it governs docs/**,
the broadest glob here, while its trigger is one of the narrowest. Omit the line
unless it is genuinely needed; absent means fire on every kind.
scripts/verify.d/30-doc-headers checks all of this on every npm run verify,
which is what stops it being a convention people remember.
Declaring a document deliberately absent
A repository may decide it will not keep one of these documents in git. Say so here, one line per path, anywhere in this file:
Exempt: <the path> — <why, in a few words>
Write the real path only when you mean it. Outside a fenced block, an
Exempt: line naming a real document is not an example — it is a declaration.
Keep illustrations fenced, and use placeholders anyway, as the form above does.
This project exempts nothing. It considered it: the internal history and planning documents were gitignored with the comment "never commit", and exempting them was one of the three options on the table. Instead the Forgejo repository was made private on 2026-08-18 and the documents were committed, because a half-populated doc tree reports to privacyllc.dev as a half-adopted project and the reason for the secrecy was the audience, not the content.
docs/data/ and docs/data/img/ cannot be exempted. A declaration naming
either is refused rather than honoured, because the Command Center renders what
is in them.
One asset is genuinely missing, and that is not an exemption
docs/data/img/banner.webp does not exist. icon.webp and logo.webp do, both
converted from this project's own marks in assets/.
No placeholder was generated, deliberately — a placeholder that looks finished
outlives the issue that would have replaced it. It is filed as a P2 issue
instead, and the project card will render without a banner until somebody draws
one.