# Docs Reconciliation — Design **Date:** 2026-07-25 **Status:** Implemented Reconcile the documentation against the code after five weeks of undocumented evolution, so that a repeat review returns "ok". --- ## Problem Documentation for this project began as thoughts and plans. The app then changed — features were built differently, some were dropped, and the owner changed his mind about what he needed. Those decisions were recorded ad hoc or not at all. The result is a tree where some docs describe a site that no longer exists, and nothing marks them as historical. Concretely, before this pass: - `docs/working/README.md` advertised `summary.md` as the project's **current state**, while `summary.md` described Leaflet, a `/tracker` feed, a `/map` page, a `/stats` page, and a "Journal · Map · Stats" nav — none of which exist. - `docs/reference/design-system-light.md` documented a light-mode palette in present tense. No light mode is implemented anywhere: `tokens.css` has a single `:root` block and no `prefers-color-scheme` / `data-theme` mechanism. - `CLAUDE.md` — the always-loaded file — asserted a source relationship that does not exist (`css-compiled/` generated from `css/style.css` + `css/tokens.css`). - `README.md`'s server runbook documented every `make remote-*` command without the `-test`/`-prod` suffix that `guard-env` requires, so the documented commands cannot run. - `docker-compose.yml` still defines a `travel-memories` service whose source was deleted in `a80b0a9` ("moved to separate project"), so `make start` fails on any clean checkout. ## Root cause Per [`docs/solutions/conventions/claude-md-content-tiering.md`](../../solutions/conventions/claude-md-content-tiering.md), descriptions drift because the code moves and the prose does not; rules do not drift, because they encode intent rather than state. This pass confirms that finding again: every defect found was a description of code, config, or a command — not one was a rule that had become wrong on its own. The compounding factor is **tense**. The tree mixes two kinds of document with no marker distinguishing them: | Kind | Files | Staleness is | |---|---|---| | Present-tense — "this is how it is" | `CLAUDE.md`, `reference/`, `guides/`, `README.md`, `CONCEPTS.md` | a defect | | Past-tense — "this is what we decided then" | `working/plans/`, `working/specs/`, `working/milestones/`, `summary.md`, `pm-analysis.md` | correct and expected | A completed plan *should* be stale — it is a record. It only becomes a problem when nothing tells a reader it is a record. `milestones/milestone-2.md` opens by describing a Leaflet `/map` page in confident present tense with no date qualifier. ## Approach Two mechanisms, combined: **A — one authoritative supersession ledger.** `docs/reference/superseded-decisions.md` records every reversal in one table: what was planned, where it was planned, what is true now, when it changed, and why. This answers "what did I change my mind about?" in a single place, which is the question a review actually asks. **B — inline notes at the point of staleness.** Every superseded section carries a `> **Superseded …**` blockquote where the stale claim sits, so the claim can never be read un-corrected. This pattern is not invented here — `docs/reference/architecture.md` and `docs/guides/trip-switching.md` already use `> History:` and `> **Changed 2026-07:**` notes. A alone has an indirection problem (a pointer you may not follow). B alone has a completeness problem (no changelog view, and coverage is only as good as the annotation pass). Together each covers the other's gap. ### Scope, split by tense - **Present-tense docs are corrected against the code.** The code is the source of truth. Every factual claim was verified by reading the code, config, or `Makefile` — not inferred. - **Past-tense docs are annotated only, never rewritten.** 41 plans and 25 specs, ~30k lines. Their `✅ Complete` trailing notes are good records; rewriting them would destroy the audit trail and is unbounded work. - **Code-side inconsistencies are logged, not fixed.** Mixing behaviour changes into a documentation diff would make it unreviewable. They go to `docs/working/2026-07-25-doc-drift-recommendations.md` for a separate decision. ### Out of scope - A repeatable drift check (script with an exit code). Deliberately deferred — the owner asked for the one-time reconciliation first. It is the lead recommendation in the recommendations doc. - Fixing the `travel-memories` / `docker-compose.yml` breakage, the unused `shortcode-gallery-plusplus`, and the `italy-2025` demo fixtures. All logged as recommendations. ## Verification Claims were checked against, not assumed from: | Claim area | Verified against | |---|---| | Nav labels | `templates/partials/base.html.twig:27-31` | | Template + partial inventory | `ls templates/`, `ls templates/partials/` | | Asset sources → outputs | `user/themes/intotheeast/package.json` build script | | `css-compiled/` provenance | CSS imports in `js/src/*.js`; `assets.addCss` in `base.html.twig:7-8` | | Design tokens | `css/tokens.css` | | Light mode | absence of `prefers-color-scheme` / `data-theme` and of light hex values in `css/` | | Photo field rules | `user/pages/02.post/post-form.md:35-46` | | `hero_image` removal | `post-form.md:149-151` | | `entry-actions` routes | `user/plugins/entry-actions/entry-actions.php:63-73` | | `make` targets + env guard | `Makefile` (`guard-env:41-43`, `make-env-target:45-46`) | | `travel-memories` removal | `git log -- services/` → `a80b0a9`; `docker compose build` failure | ## The audit baseline moved twice Both times, auditing the convenient state rather than the real one would have produced wrong findings. **The submodule pin lagged.** A fresh worktree checks out the `user/` commit the outer repo pins, not `user/`'s real HEAD. The pin predated the merged location-override work, so auditing it would have reported a feature as unbuilt and missed two new source files. `user/` was moved to its real HEAD (`dd19995`) before auditing, and the gitlink deliberately not committed. **The outer `main` advanced 13 commits mid-audit.** The location-override branch was merged into the outer repo while this pass was running, which independently fixed two of the findings — the single-map-path carve-out (`829325c`) and the plan's `Status:` line (`a517331`). Merging `main` in before opening the PR was what surfaced that; without it this branch would have **reverted** both. `main`'s wording was better than the replacement drafted here and was kept in full. `main` touched none of the other nine corrected documents, so the remaining findings stand unchanged. The general rule: **re-check the baseline before publishing, not only before starting.** A long audit races the work it is auditing.