198 lines
12 KiB
Markdown
198 lines
12 KiB
Markdown
# 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
|
||
```
|
||
|
||
> Written last, and describing what is **actually here** rather than what the
|
||
> template said should be. Its whole value is being accurate about the others.
|
||
|
||
## 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** at
|
||
[dream.scheller.ltd/null/Privacy-Period-Tracker](https://dream.scheller.ltd/null/Privacy-Period-Tracker), not in
|
||
`docs/`. Milestones are batches — eight of them, `Batch 01 — Foundation` through
|
||
`Batch 08 — Polish` — issues are deliverables, and severity labels are `P0`,
|
||
`P1`, `P2` and `release-blocker`.
|
||
|
||
This section exists to stop the next contributor starting a fresh markdown
|
||
to-do list. A list of things to do in two places is two records that will
|
||
disagree, and nothing will say which one is right.
|
||
|
||
| Question | Answer lives in |
|
||
| --- | --- |
|
||
| What are we building, and for whom? | [`planning/PROJECT_PLAN.md`](planning/PROJECT_PLAN.md) |
|
||
| What exactly does V1 do — prediction rules, screens, copy, compliance? | [`planning/PRODUCT_PLAN.md`](planning/PRODUCT_PLAN.md) |
|
||
| 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 [`history/DEVELOPMENT_LOG.md`](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? | [`WORK_CYCLE.md`](WORK_CYCLE.md) |
|
||
| What happened, and when? | [`history/DEVELOPMENT_LOG.md`](history/DEVELOPMENT_LOG.md) |
|
||
| Why is it built this way, and what was rejected? | [`history/HISTORY.md`](history/HISTORY.md) |
|
||
| Did QA pass, and what does the tester think? | [`qa/ClaudeReport.md`](qa/ClaudeReport.md) |
|
||
| What did QA actually reach? | [`qa/ClaudeQACoverage.md`](qa/ClaudeQACoverage.md) |
|
||
| What is a QA round? | [`qa/ClaudeQAPlan.md`](qa/ClaudeQAPlan.md) |
|
||
| How is it built — modules, boundaries, data shapes, migrations? | [`architecture/README.md`](architecture/README.md) |
|
||
| What should it feel like, and what words does it use? | [`design/README.md`](design/README.md) |
|
||
| What colour, logo or type do I use? | [`design/BRAND_GUIDE.md`](design/BRAND_GUIDE.md) — it outranks [`planning/PRODUCT_PLAN.md`](planning/PRODUCT_PLAN.md) §39 where they differ |
|
||
| What is protected, from whom, and what must never be logged? | [`security/SECURITY.md`](security/SECURITY.md) |
|
||
| What is checked before a Play release? | [`security/SECURITY_CHECKLIST.md`](security/SECURITY_CHECKLIST.md) |
|
||
| Which script do I run, and can it stop me? | [`TOOLS.md`](TOOLS.md) — the signpost; [`architecture/README.md`](architecture/README.md) has the table |
|
||
| What runs before a commit? | [`architecture/githooks/README.md`](architecture/githooks/README.md), and the hooks themselves in `.githooks/` |
|
||
| How do I write a check that will actually catch something? | [`architecture/GUARDS.md`](architecture/GUARDS.md) |
|
||
|
||
**Next action and blockers are recorded at the end of every piece of work, not
|
||
when somebody asks.** [`WORK_CYCLE.md`](WORK_CYCLE.md) holds that procedure and
|
||
the reason each step is in it.
|
||
|
||
## The two planning documents, and which owns what
|
||
|
||
Unusually, this project has two — worth stating plainly, because a reader who
|
||
does not know which is which will pick the wrong one.
|
||
|
||
| | Owns | Length |
|
||
| --- | --- | --- |
|
||
| [`planning/PRODUCT_PLAN.md`](planning/PRODUCT_PLAN.md) | the **V1 specification**: prediction requirements and their acceptance cases, the data model, every screen and its copy, notification modes, monetization, artwork, Play compliance | ~2,500 lines |
|
||
| [`planning/PROJECT_PLAN.md`](planning/PROJECT_PLAN.md) | the **argument**: what this is, who for, what it deliberately is not, the stack and the reason for each choice, what success looks like, known risks | ~110 lines |
|
||
|
||
`PRODUCT_PLAN.md` is the document this project started as — it existed before
|
||
the repository did. Everything else in `docs/` points **into** it rather than
|
||
copying out of it, and that is deliberate: a second copy of a fertility
|
||
disclaimer or a notification string is how two versions of a promise come to
|
||
exist. `architecture/`, `design/` and `qa/` each name the sections of it they
|
||
own.
|
||
|
||
Where the two disagree, `PRODUCT_PLAN.md` is the specification and
|
||
`PROJECT_PLAN.md` is the reasoning — resolve it rather than letting both stand.
|
||
|
||
## Folder layout
|
||
|
||
| Folder | Contents |
|
||
| --- | --- |
|
||
| `docs/planning/` | `PRODUCT_PLAN` — the V1 specification. `PROJECT_PLAN` — the vision. Neither is the schedule; that is the tracker. |
|
||
| `docs/qa/` | `ClaudeQAPlan` (playbook, passes A–H), `ClaudeQACoverage` (what each pass reached), `ClaudeReport` (the verdict) |
|
||
| `docs/architecture/` | modules, boundaries, data shapes, the migration table; `GUARDS.md`; `githooks/README.md` |
|
||
| `docs/design/` | `README.md` — tone, the four rules that settle arguments, and which specification sections own each surface. `BRAND_GUIDE.md` — the owner-supplied visual identity, which outranks `PRODUCT_PLAN.md` §39 on colour. `brand/` — the owner's source art, including the emblem the launcher icon is cut from. `dist/` — the onboarding illustration sources, and `splash.png`, the lockup `docs/data/img/logo.webp` and `banner.webp` are generated from |
|
||
| `docs/security/` | `SECURITY` — threat model, the advertising boundary, logging rules. `SECURITY_CHECKLIST` — the pre-release list |
|
||
| `docs/history/` | `DEVELOPMENT_LOG` (dated, append-only), `HISTORY` (decisions and their reasons), `BATCH_LEDGER` (archived) |
|
||
| `docs/data/` | `README.md` — the rule, and why this folder cannot be exempted. `img/README.md` — the three required names, their dimensions and the 512 KB ceiling. `img/icon.webp`, `img/logo.webp`, `img/banner.webp` — the marks privacyllc.dev renders |
|
||
| `docs/` root | this map; `WORK_CYCLE`; `TOOLS` |
|
||
|
||
`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 deliberately does not have
|
||
|
||
Recorded here because an absence somebody chose and an absence nobody noticed
|
||
look identical from outside, and only one of them is fine.
|
||
|
||
- **docs/OPERATIONS.md — deleted.** Named without backticks, because
|
||
`doc-claims.sh` reads a backticked path as a claim the file is there and this
|
||
one says the opposite. Privacy: Period Tracker is an offline-first Android app
|
||
distributed through Google Play. There is no host, no container, no uptime and
|
||
no restore path of ours. An empty runbook reads as one nobody wrote rather
|
||
than one that never applied.
|
||
- **docs/planning/FUTURE.md — never created**, and named bare for the same
|
||
reason. The Command Center's docs
|
||
report looks for a batch ledger there and reports it **missing** for every
|
||
tracker-first project. That is the expected state; creating the file to turn
|
||
the line green would rebuild the second record
|
||
[`history/BATCH_LEDGER.md`](history/BATCH_LEDGER.md) was archived for.
|
||
- **Most of the template's scripts.** Six were taken; the rest assume a deployed
|
||
Node or Postgres service. [`TOOLS.md`](TOOLS.md) names each one and why.
|
||
`doc-claims.sh` noting a document that mentions a script this project does not
|
||
have is expected, not a failure.
|
||
- **A master copy of the hooks under `docs/architecture/githooks/`.** The
|
||
template keeps one and installs copies; this repository keeps only `.githooks/`,
|
||
because `pre-commit` here is adapted for Gradle and a second copy would drift.
|
||
- **No `Exempt:` declarations.** Every document this convention asks for is
|
||
either present in git or listed above as deliberately deleted.
|
||
|
||
## Source-of-truth ladder
|
||
|
||
When two sources disagree, believe them in this order:
|
||
|
||
1. **Verified code behaviour** — read the source, run `./gradlew test`
|
||
2. **The issue tracker** — for anything about state of work: what is open, what
|
||
closed, when, and by which commit
|
||
3. **Specialist docs** — authoritative for their own subject only
|
||
4. **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:` table in
|
||
[`../README.md`](../README.md) is the one place a claim about what is built is
|
||
allowed to live, and every row of it cites its evidence.
|
||
|
||
## 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.
|
||
|
||
```
|
||
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 checker reads them, and a document whose
|
||
status falls outside the list is reported as having an unknown one rather than
|
||
being quietly accepted.
|
||
|
||
**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. It is also checked: 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`.
|
||
`scripts/doc-triggers.py` cuts the entry there and reads the globs from the left.
|
||
**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 — not reported as skipped either, because it still looks
|
||
like a path.
|
||
|
||
**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, which is what
|
||
almost every document wants.
|
||
|
||
## 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,
|
||
and the checker will report that document as deliberately absent. Keep
|
||
illustrations fenced, and use placeholders anyway, as the form above does.
|
||
|
||
This repository currently declares none. Where a document is genuinely not applicable it
|
||
has been **deleted** and recorded above instead, which is the honest form: an
|
||
exemption says "kept elsewhere", and `OPERATIONS.md` is not kept anywhere.
|
||
|
||
**`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 — an exemption would produce a project card with no icon and nothing
|
||
explaining why. If one of them is ever missing, the mechanism is a filed issue —
|
||
[`data/README.md`](data/README.md) says what to file and why a placeholder is
|
||
worse than a gap — never an exemption.
|