Privacy-Period-Tracker/docs/DOC_TRUST_MAP.md

12 KiB
Raw Blame History

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, 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
What exactly does V1 do — prediction rules, screens, copy, compliance? 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 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
What happened, and when? history/DEVELOPMENT_LOG.md
Why is it built this way, and what was rejected? history/HISTORY.md
Did QA pass, and what does the tester think? qa/ClaudeReport.md
What did QA actually reach? qa/ClaudeQACoverage.md
What is a QA round? qa/ClaudeQAPlan.md
How is it built — modules, boundaries, data shapes, migrations? architecture/README.md
Which constants are claims about bodies, and on what evidence? architecture/SCIENCE.md
What should it feel like, and what words does it use? design/README.md
What colour, logo or type do I use? design/BRAND_GUIDE.md — it outranks planning/PRODUCT_PLAN.md §39 where they differ
What is protected, from whom, and what must never be logged? security/SECURITY.md
What is checked before a Play release? security/SECURITY_CHECKLIST.md
Which script do I run, and can it stop me? TOOLS.md — the signpost; architecture/README.md has the table
What runs before a commit? architecture/githooks/README.md, and the hooks themselves in .githooks/
How do I write a check that will actually catch something? architecture/GUARDS.md

Next action and blockers are recorded at the end of every piece of work, not when somebody asks. 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 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 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 AH), ClaudeQACoverage (what each pass reached), ClaudeReport (the verdict)
docs/architecture/ modules, boundaries, data shapes, the migration table; SCIENCE.md — the physiology constants and their citations; 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 and the Play listing exports. dist/ — the onboarding illustration sources, and splash.webp, the lockup docs/data/img/logo.webp and banner.webp are generated from. screenshots/ — captured app screenshots, for the product page on privacyllc.dev and the Play listing
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 was archived for.
  • Most of the template's scripts. Six were taken; the rest assume a deployed Node or Postgres service. 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 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 dashdocs/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 says what to file and why a placeholder is worse than a gap — never an exemption.