Documentation Process
This document describes how jinflow documentation is authored, verified, maintained, and kept in sync with the codebase. The documentation system is infrastructure — it has the same status as compilers, validators, and test suites.
Principles
Section titled “Principles”-
Code is the source of truth. Documentation describes what code does, not what we wish it did. If the docs say a command exists and it doesn’t, the docs are wrong.
-
Every claim is verifiable. CLI commands can be checked against
cli.pysubparsers. Explorer pages can be checked against route directories. Signal types can be checked againstVALID_TYPES. This is why we have a drift detector. -
Aspirational content is labeled. Design documents that describe unimplemented features carry
status: aspirationalin their frontmatter. This prevents readers from assuming a feature exists when it doesn’t. -
One authoritative location, synced copies. User guides live in
docs/guide/(EN, DE, FR). The Explorer embeds copies atexplorer/src/lib/data/guides/. The flow is alwaysdocs/guide/ → explorer/. Never the reverse. -
Growth-phase awareness. The product ships features faster than docs can follow. The drift detector and re-verification process exist because of this reality, not despite it.
Document Taxonomy
Section titled “Document Taxonomy”By Audience
Section titled “By Audience”| Layer | Location | Audience | Verified by |
|---|---|---|---|
| User guides | docs/guide/{en,de,fr}/ | End users, analysts | Drift detector + manual audit |
| Cheatsheet | docs/cheatsheet.md | Operators, power users | Drift detector (CLI commands) |
| Architecture docs | docs/architecture/ | Engineers, contributors | Manual audit + frontmatter stamps |
| Design docs | docs/design/ | Engineers, architects | Manual audit + frontmatter stamps |
| Operations | docs/operations/ | Operators, DevOps | Manual audit |
| Root files | README.md, CHANGELOG.md | Everyone | Manual audit |
By Trust Level (Frontmatter)
Section titled “By Trust Level (Frontmatter)”Every document in docs/architecture/ and docs/design/ carries YAML frontmatter:
---status: trusted | partial | outdated | aspirationallast_verified: 2026-03-22superseded_by: other_doc.md # optional, for outdated docs---| Status | Meaning | Action |
|---|---|---|
trusted | All claims verified against source code | Safe to reference and publish |
partial | Core content accurate, but gaps or incomplete features | Note the gaps when referencing |
outdated | Was once accurate, code has moved on | Update or mark superseded |
aspirational | Describes a design that was never (or barely) implemented | Do not present as current capability |
User guides (docs/guide/) do not carry frontmatter — they are always expected to be current and are verified by the drift detector.
File Locations and Sync Flow
Section titled “File Locations and Sync Flow”docs/guide/ setup.md ← authoritative EN make.md explorer.md tenants.md instruments.md collaboration.md deploy.md ai.md notes.md finding-explainer.md de/ ← German translations (same filenames) fr/ ← French translations (same filenames) │ ▼ sync (copy)explorer/src/lib/data/guides/ en/ ← embedded copy for Explorer "About" page de/ fr/Sync rule: After editing any guide in docs/guide/, copy it to the corresponding explorer/src/lib/data/guides/ location. For DE/FR, apply the same structural changes (new sections, removed sections, command fixes) — the translated prose stays as-is, but code blocks, command names, and technical terms must match.
Translation workflow: English is always written first. DE/FR translations are updated manually. The scripts/translate_guides.py script can assist, but human review is required. Technical terms (command names, YAML field names, directory paths) are never translated.
The Drift Detector
Section titled “The Drift Detector”scripts/docsdrift.py is an automated check that compares code against documentation across four dimensions:
What It Checks
Section titled “What It Checks”| Dimension | Code Source | Doc Source | How |
|---|---|---|---|
| CLI commands | jinflow/cli.py add_parser() calls | docs/cheatsheet.md ### headers | Regex extraction, set comparison |
| Explorer pages | explorer/src/routes/[tenant]/ +page.svelte files | docs/guide/explorer.md Pages table | Filesystem walk, table parsing |
| Signal types | scripts/signalcheck.py VALID_TYPES | docs/guide/instruments.md Types line | Regex extraction, set comparison |
| Frontmatter | n/a | docs/architecture/*.md, docs/design/*.md | Check first 200 bytes for status: |
Running It
Section titled “Running It”python3 scripts/docsdrift.py # full reportpython3 scripts/docsdrift.py --quiet # only show drift (exit 1 if found)Exit code: 0 = no drift, 1 = drift detected. Suitable for CI gating.
Output Example (clean)
Section titled “Output Example (clean)”============================================================DOCUMENTATION DRIFT REPORT============================================================
CLI commands in code: 30CLI commands in cheatsheet: 30 All CLI commands documented. ✓
Explorer routes in code: 18Explorer pages in guide: 18 All Explorer pages documented. ✓
Signal types in code: 13Signal types in guide: 13 All signal types documented. ✓
Frontmatter stamps: 73 stamped, 0 missing All design/architecture docs stamped. ✓
------------------------------------------------------------No drift detected. Docs are in sync with code. ✓Output Example (drift)
Section titled “Output Example (drift)”CLI commands in code: 31CLI commands in cheatsheet: 30
UNDOCUMENTED CLI commands (1): + diff
DRIFT DETECTED: 1 issue(s) found.Extending the Detector
Section titled “Extending the Detector”When a new verifiable dimension is added to the product (e.g., new instrument types, new contract files), add a corresponding extraction function to docsdrift.py. The pattern is always:
- Extract the canonical set from code (regex on source file)
- Extract the documented set from the relevant markdown (parse the table or list)
- Compare:
undocumented = code - docs,phantom = docs - code
Configuration Constants
Section titled “Configuration Constants”The detector has a few hardcoded mappings that need updating when the product changes:
PAGE_NAME_TO_ROUTE— maps human-readable page names (from explorer.md) to filesystem route directoriesSUB_PAGES— routes that are sub-pages of a parent (not standalone nav items), excluded from comparisonROUTE_ALIASES— when the filesystem path differs from the canonical name in docs (e.g.,system/pipeline→pipeline)- Parent command groups (
afs,pack,cloud) — discarded from CLI comparison since they’re groups, not standalone commands
The Audit Process
Section titled “The Audit Process”A documentation audit is a manual, thorough verification of all markdown documents against source code. It produces docs/documentation_audit.md — a living report with per-file status, coverage, and specific findings.
When to Audit
Section titled “When to Audit”- Before a documentation push — when preparing user-facing docs for publication
- After a major feature sprint — when many files changed and drift is likely
- Periodically — the
last_verifieddates in frontmatter indicate staleness
How to Audit
Section titled “How to Audit”The audit runs in iterations. Each iteration focuses on a priority tier:
| Priority | Documents | Why first |
|---|---|---|
| 1 | User guides (docs/guide/) | These become the published docs |
| 2 | Operations (docs/operations/) | Commands, setup, builds |
| 3 | Root files (README.md, cheatsheets) | First thing people read |
| 4 | Architecture (docs/architecture/) | Reference material |
| 5 | Design (docs/design/) | Highest aspirational risk |
For each document, the auditor:
- Reads the document and identifies every verifiable claim (CLI commands, file paths, YAML fields, Explorer routes, dbt model names, environment variables)
- Checks each claim against source code — grep for function names, verify file existence, read argparse definitions
- Classifies the document as trusted/partial/outdated/aspirational
- Records findings in
docs/documentation_audit.mdwith specific evidence - Fixes P0 issues immediately (wrong command names, non-existent features presented as real)
Audit Report Structure
Section titled “Audit Report Structure”docs/documentation_audit.md contains:
- Iteration changelog (when each pass was done and what it covered)
- Per-file status blocks with
status,coverage,source_of_truth,last_verified - Summary statistics (trusted/partial/outdated/aspirational counts)
- Critical issues table (P0/P1/P2 with document, issue, and fix status)
- Recommendations for the next iteration
Re-verification
Section titled “Re-verification”After fixes are applied, a re-verification pass confirms:
- All reported issues are actually fixed
- No new issues were introduced by the fixes
- Sync between docs/guide/ and explorer/guides/ is intact
- DE/FR translations have the same structural fixes
Adding New Documentation
Section titled “Adding New Documentation”New User Guide Page
Section titled “New User Guide Page”- Write
docs/guide/new_topic.mdin English - Create DE/FR translations at
docs/guide/de/new_topic.mdanddocs/guide/fr/new_topic.md - Copy all three to
explorer/src/lib/data/guides/{en,de,fr}/new_topic.md - Add the page to
docs/index.mdif it’s a top-level guide - Run
python3 scripts/docsdrift.pyto verify no drift was introduced
New Architecture or Design Doc
Section titled “New Architecture or Design Doc”- Write the document with frontmatter at the top:
---status: trusted # or aspirational if it's a proposallast_verified: 2026-03-22---
- If it supersedes an older document, update the old doc’s frontmatter:
And add a supersession notice below the frontmatter:---status: outdatedlast_verified: 2026-03-22superseded_by: new_doc.md---
Superseded by New Doc. Kept for historical reference.
New CLI Command
Section titled “New CLI Command”- Implement the command in
jinflow/cli.pywithsubparsers.add_parser() - Add a
### jinflow <command>section todocs/cheatsheet.md - Run
python3 scripts/docsdrift.py— it will catch the gap if you forget
New Explorer Page
Section titled “New Explorer Page”- Create the route at
explorer/src/routes/[tenant]/new-page/+page.svelte - Add a row to the Pages table in
docs/guide/explorer.md - Add the same row to
docs/guide/de/explorer.mdanddocs/guide/fr/explorer.md - Sync to
explorer/src/lib/data/guides/{en,de,fr}/explorer.md - If the page’s first letter collides with an existing shortcut, update the keyboard shortcuts table
- Update
PAGE_NAME_TO_ROUTEinscripts/docsdrift.pyif the human name differs from the route directory - Run
python3 scripts/docsdrift.py
New Signal Type
Section titled “New Signal Type”- Add the type to
VALID_TYPESinscripts/signalcheck.py - Add it to the Types: line in
docs/guide/instruments.md - Add it to the same line in
docs/guide/de/instruments.mdanddocs/guide/fr/instruments.md - Sync to
explorer/src/lib/data/guides/{en,de,fr}/instruments.md - Run
python3 scripts/docsdrift.py
Integration Points
Section titled “Integration Points”Release Pipeline
Section titled “Release Pipeline”The drift detector can be wired into the release pipeline:
# In scripts/release.sh or justfilepython3 scripts/docsdrift.py --quiet || echo "WARNING: documentation drift detected"This does not block the release (docs shouldn’t gate shipping), but it surfaces the drift at the moment it matters most — right before users see the new version.
CI (GitHub Actions)
Section titled “CI (GitHub Actions)”- name: Documentation drift check run: python3 scripts/docsdrift.py --quiet continue-on-error: true # warn, don't blockPost-Release Workflow
Section titled “Post-Release Workflow”After just release:
python3 scripts/docsdrift.py— check for new drift- Fix any undocumented commands/pages/types
- Update
last_verifieddates on re-checked docs - Commit: “Sync docs with vX.Y.Z release”
Inventory
Section titled “Inventory”As of 2026-03-22, the documentation corpus contains:
| Category | Count | Location |
|---|---|---|
| User guides (EN) | 10 | docs/guide/ |
| User guides (DE) | 10 | docs/guide/de/ |
| User guides (FR) | 10 | docs/guide/fr/ |
| Explorer guides (EN/DE/FR) | 30 | explorer/src/lib/data/guides/ |
| Architecture docs | 32 | docs/architecture/ |
| Design docs | 41 | docs/design/ |
| Operations docs | 7 | docs/operations/ |
| Cheatsheets | 5 | docs/cheatsheet*.md |
| Root files | 3 | README.md, CHANGELOG.md |
| Audit report | 1 | docs/documentation_audit.md |
| Total | ~149 |
Status distribution (architecture + design docs):
| Status | Count | % |
|---|---|---|
| trusted | 35 | 48% |
| partial | 19 | 26% |
| aspirational | 15 | 21% |
| outdated | 4 | 5% |
History
Section titled “History”The documentation process was established on 2026-03-21 through a systematic audit of all ~80 unique markdown documents in the repository. The audit was conducted in iterations:
| Iteration | Date | Scope | Key Actions |
|---|---|---|---|
| 1 | 2026-03-21 | User guides, operations | 5 P0 bug fixes (wrong env var, wrong commands, phantom CLI features) |
| 2 | 2026-03-21 | All guides + architecture/design | Added Reports instrument, 3 missing Explorer pages, 73 frontmatter stamps, guide sync |
| 3 | 2026-03-21 | Operations, root files, cheatsheet | Rewrote user-guide.md, cheatsheet cleanup (remove 3 phantom + add 7 real commands), README fix, superseded docs |
| Re-verify | 2026-03-21 | All changed files | Found and fixed 4 remaining issues (hand_written type, afs subcommands, KLS filename, guide sync) |
| Drift detector | 2026-03-22 | Tooling | Built scripts/docsdrift.py — automated 4-dimension drift detection |
The process was designed for a product in heavy growth phase, where features ship faster than docs can follow. The drift detector and iterative audit model exist to make this sustainable.