Disciplines · Reference

Documentation Reorganization Plan

inventory and is owned outside this reorg.

9sections7 minread

On this page

Status: proposed Last updated: 2026-05-08 Owner: docs-platform Tooling: tools/docs/reorg.mjs

Hard constraints#

  • Never touch V1/ at the repo root. That directory holds the V1 feature inventory and is owned outside this reorg. Excluded by hard prefix in tools/docs/reorg.mjs (see FORBIDDEN_PREFIXES).
  • Never touch .claude/worktrees/. CLAUDE.md mandate.
  • Every move uses git mv so history follows the file.
  • Each phase is a single commit: script invocation + moves + link rewrites + verifier passes.
  • Scope changes do not bypass pnpm-lock.yaml, lint, or the stub scanner; if a hook fails, fix the cause, do not skip.

Diagnosis#

Three orthogonal axes are jumbled in docs/: genre (reference, audit, runbook, ADR, proposal, spec), domain (lilith, metis, isis, nyx, ...), and time (evergreen, V1, P2, archived). Concretely:

Symptom Count
Files in docs/oshun/ root, all OSHUN_V1_* prefixed 559
*_AUDIT.md files in docs/oshun/ root (306 V1-prefixed + 1 outlier ASSET_AUDIT.md) 307
Cross-links between those audit files 150
Inbound links to docs/oshun/ from elsewhere in the repo 667
Files under docs/runbooks/ 1004
docs/runbooks/ files prefixed isis- 1001
Top-level domain directories at docs/<domain>/ (lilith=107, yemaya=24, kalika=7, ...) 8
Parallel domain trees: docs/<d>/, docs/domains/<d>/, docs/oshun/domains/<d>/ 3
ADR directories with colliding numbering 2 (docs/adr/, docs/oshun/adr/)

Pristine = each axis lives at exactly one level: genre → release-or-domain → file.

Target structure#

text
docs/
├── README.md                         # Concise nav (replaces 67KB current)
├── CONTRIBUTING.md
│
├── reference/                        # Cross-cutting EVERGREEN
│   ├── architecture.md
│   ├── api-contracts.md
│   ├── coding-standards.md
│   ├── cross-domain-integration.md
│   ├── data-ownership-matrix.md
│   ├── dependency-management.md
│   ├── documentation-structure.md
│   ├── getting-started.md
│   ├── monitoring.md
│   ├── rollback-procedures.md
│   ├── security.md
│   ├── shared-libraries.md
│   ├── testing.md
│   ├── ci-cd.md
│   ├── faq.md
│   ├── inventories/                  # auto-generated artifacts (regen cmd documented)
│   └── runbooks/                     # cross-cutting only (cost, incident, scaling)
│
├── domains/                          # SINGLE source of truth per domain
│   ├── README.md                     # Coverage index
│   ├── _template/                    # The 8 required files (per existing standard)
│   └── <domain>/
│       ├── README.md
│       ├── architecture.md
│       ├── features.md
│       ├── developer-guide.md
│       ├── database.md
│       ├── service-catalog.md
│       ├── user-stories.md
│       ├── api/
│       ├── adr/                      # Domain-scoped ADRs
│       ├── audits/                   # Domain audits (point-in-time)
│       ├── runbooks/                 # Domain ops (isis lands ~1001 files here)
│       ├── proposals/
│       └── extras/                   # One-offs absorbed from docs/<domain>/*
│
├── adr/                              # GLOBAL ADRs only (single numbering)
│
├── proposals/                        # Pre-decision proposals
│
├── releases/                         # Release-cycle artifacts (decay together)
│   ├── v1/
│   │   ├── README.md
│   │   ├── scope/
│   │   ├── specs/
│   │   ├── design/
│   │   ├── runbooks/
│   │   ├── reports/
│   │   ├── domains/                  # V1 inventory snapshot
│   │   └── audits/
│   │       ├── <domain>/             # NISABA, ARETE, METIS, TARA, ...
│   │       └── <surface>/            # MOBILE, WEB, SHELL, CUSTOMER
│   ├── p2/
│   └── _archive/
│
├── guides/
├── compliance/   conventions/   infrastructure/
├── integrations/ migration/     performance/
├── research/     training/

What dissolves#

Source Fate
docs/oshun/ (root) Entirely dissolved. Splits into releases/v1/{audits,specs,scope,design,reports,runbooks,domains}/
docs/oshun/adr/ Renumbered into global docs/adr/ (or a domain adr/ for domain-scoped ADRs)
docs/oshun/domains/ docs/releases/v1/domains/ (V1 snapshot, distinct from live docs/domains/)
docs/oshun/p2/ docs/releases/p2/
docs/oshun/audits/, docs/oshun/admin/ docs/releases/v1/{audits,specs}/
docs/<domain>/ top-level orphans (lilith, yemaya, ...) docs/domains/<domain>/extras/
docs/runbooks/ (1001 isis files) docs/domains/isis/runbooks/; 3 cross-cutting → docs/reference/runbooks/
docs/reports/, docs/analysis/, docs/audits/ Split: V1 → releases/v1/; evergreen inventories → reference/inventories/
67KB docs/README.md Replaced by concise top-level nav

Naming conventions (applied to everything moved)#

  • Directory and file names: lowercase-kebab.md. SCREAMING_SNAKE_CASE is dropped.
  • ADRs: NNNN-short-title.md with single global numbering.
  • Audits: OSHUN_V1_NISABA_STUDY_PLANS_AUDIT.mdreleases/v1/audits/nisaba/study-plans.md.
  • Every directory has a README.md (1-2 paragraphs: what's here, how to find things).

Phase plan#

Each phase is one commit. Run order matters: Phase N assumes Phase N-1 landed.

Phase 0 — Tooling and plan (this commit)#

No file moves. Lands tools/docs/reorg.mjs and this plan. Updates docs/reference/documentation-structure.md (formerly DOCUMENTATION_STRUCTURE_STANDARD.md) to describe the full taxonomy (later phase finishes that rename).

Phase 1 — Domain orphans (source-only)#

Move six hand-maintained top-level docs/<domain>/ dirs into docs/domains/<domain>/extras/: yemaya, iris, metis, hathor, bellona, veritas. ~125 files, almost all markdown. The few ../ links that escape the moved tree are fixed in the same commit.

docs/lilith/ and docs/kalika/ are NOT in this phase. They are mixed-mode (hand + generated) and fully-generated respectively, and need different handling — see Phase 1.5 and Phase 1.6 below.

Rewriter regex. The link rewriter uses (?<![/\w-])docs/<d>(?![\w-]) so it does NOT false-match libs/openapi/docs/<d>/, libs/<d>/core/docs/, /studio/docs/<d>/ URL slugs, or docs/<d>-orchestration/. The naive \b form caused 235+ false positives in a Phase 1 attempt and was discarded.

Phase 1.5 — docs/lilith/ source / generated split#

docs/lilith/ (1106 files) mixes hand-maintained markdown (~440 files across sync/, observability/, schemas/, metaverse/, reports/, code-samples/, examples/, performance/, scripts/, guides/, database/, curricula/, notes/) with generated content (generated/, api-reference/, plus 540 HTML files from TypeDoc / Stoplight).

The split:

  • Hand-maintained *.md and source files → docs/domains/lilith/extras/
  • docs/lilith/generated/, docs/lilith/api-reference/ and any other generator output → either .gitignore + relocate to libs/lilith/sdk/api-docs/ (typical TypeDoc target), or stay tracked under docs/domains/lilith/api-docs/ with a top-of-tree note that the content is generated.

The choice between gitignore and tracked-with-note is Phase 1.5's deliverable; not yet decided.

Phase 1.6 — docs/kalika/ (gitignore the generated tree)#

docs/kalika/ is 100% generated content (6452 HTML, 180 JS, 72 CSS, 36 SVG, 36 .nojekyll) plus 15 markdown sources. All commits to it are authored by Codex (the AI). Generators are explicit:

  • pnpm kalika:api-reference — produces docs/kalika/api-reference/
  • pnpm kalika:tutorial-notebooks — produces docs/kalika/tutorial-notebooks/
  • pnpm kalika:domain-guide:check — verifies hand-maintained domain guide source matches expected output
  • pnpm kalika:migration-guides:check — same for migration guides

Decision: gitignore the generated subtrees so the repo no longer tracks 6800 build artifacts. Add .gitignore entries for:

text
docs/kalika/api-reference/generated/
docs/kalika/tutorial-notebooks/generated/
docs/kalika/**/*.html
docs/kalika/**/*.js
docs/kalika/**/*.css
docs/kalika/**/.nojekyll

Then git rm -r --cached the matching tracked files, leaving them on disk but untracked. CI continues to regenerate them via the existing *:check scripts.

The 15 markdown sources stay tracked. Move them to docs/domains/kalika/ as part of bringing kalika into the standard domain shape — Phase 1.6 lands the gitignore + cleanup; the markdown relocation happens in Phase 6 (V1 inventory + outliers) so it batches with the rest of the kalika-related cleanup.

Phase 2 — Runbooks de-aggregation#

Move docs/runbooks/isis-*.md (1001 files) into docs/domains/isis/runbooks/. Move 3 cross-cutting files (cost-management.md, incident-response.md, scaling.md) to docs/reference/runbooks/.

Before executing: locate any generator script that writes into docs/runbooks/ and update its output target. If the runbooks are regenerated from manifests, the regen command is captured in docs/domains/isis/runbooks/README.md.

Phase 3 — ADR consolidation#

Resolve the docs/adr/docs/oshun/adr/ numbering collision by renumbering oshun/adr/ entries into a single global sequence under docs/adr/. Domain-scoped ADRs (i.e., ADRs whose scope is a single domain rather than the platform) move to docs/domains/<domain>/adr/.

The renumbering map is preserved in docs/adr/_renumbering-map.md so old references can be traced.

Phase 4 — V1 audit corral (the big one, 306 files)#

Bucket docs/oshun/OSHUN_V1_<TOKEN>_*_AUDIT.md by <TOKEN>:

  • Domain tokens (NISABA, ARETE, METIS, TARA, VERITAS, NYX, ...) → docs/releases/v1/audits/<domain>/<subject>.md
  • Surface tokens (MOBILE, WEB, SHELL, CUSTOMER) → docs/releases/v1/audits/<surface>/<subject>.md
  • The remainder (LIBRARY, DOMAIN, ACTIVITY, ASSISTANT, HOME, EXPLORE, PROFILE, ASSESSMENT, ...) → docs/releases/v1/audits/cross-cutting/<token-lowercased>/<subject>.md

Same commit rewrites the 150 internal cross-links and any external inbound links the verifier finds.

Phase 5 — V1 specs / scope / design#

The 248 non-AUDIT OSHUN_V1_*.md files split by content type:

Bucket Examples Target
Scope MVP_SCOPE, ACTION_PLACEMENT_RULES, CARD_AVOIDANCE_RULES docs/releases/v1/scope/
Specs event taxonomies, contract specs, schema definitions docs/releases/v1/specs/
Design BRAND_SYSTEM, MOTION_LANGUAGE, HAPTICS_GUIDELINES, ERGONOMICS_REQUIREMENTS docs/releases/v1/design/
Runbooks LAUNCH_RUNBOOK, ON_CALL_RUNBOOK, BETA_PROGRAM docs/releases/v1/runbooks/
Reports scorecards, gap analyses, integration reports docs/releases/v1/reports/

The phase-5 path map is hand-curated, not regex-derived — content genre cannot be inferred from name alone.

Phase 6 — V1 inventory + P2 + outlier audits#

  • docs/oshun/domains/docs/releases/v1/domains/ Update scripts/docs/generate-oshun-domain-reference.mjs to write to the new location, or retire it if docs/domains/<d>/ is now sufficient.
  • docs/oshun/p2/docs/releases/p2/
  • docs/oshun/audits/ (5 files) and the outlier docs/oshun/ASSET_AUDIT.md (no OSHUN_V1_ prefix) → distributed to docs/releases/v1/audits/<bucket>/
  • docs/oshun/admin/ (14 redesign specs, V1_AWEB_*) → docs/releases/v1/specs/admin/

Phase 7 — Cross-cutting reports / analysis / audits#

Split the top-level docs/reports/, docs/analysis/, docs/audits/:

  • V1-related → docs/releases/v1/reports/
  • Evergreen schema/dependency inventories → docs/reference/inventories/ (each with a one-line regen command in its frontmatter)

Phase 8 — Top-level cleanup and nav#

  • Move docs/architecture.md, docs/api-contracts.md, docs/coding-standards.md, etc. into docs/reference/.
  • Replace 67KB docs/README.md with a concise nav (~200 lines max).
  • Delete now-empty docs/oshun/.
  • Verify zero references to docs/oshun/, docs/runbooks/isis-, or any SCREAMING_SNAKE_CASE doc path remain outside docs/releases/_archive/.

Execution model#

bash
# Plan a phase (no writes):
node tools/docs/reorg.mjs --phase=1 --dry-run

# Execute a phase (git mv + link rewrites):
node tools/docs/reorg.mjs --phase=1 --execute

# Verify post-phase invariants:
node tools/docs/reorg.mjs --phase=1 --verify

# Verify ALL phases up to and including a phase:
node tools/docs/reorg.mjs --through=1 --verify

Safety rails#

  • Forbidden prefixes are checked at the top of every run. V1/, .claude/worktrees/, node_modules/, .git/ are rejected as from or to for any move.
  • Tombstones for high-traffic paths. For ~150 cross-linked V1 audit files, the executor leaves a 1-line redirect at the old path (Moved to /docs/releases/v1/audits/<bucket>/<subject>.md). Tombstones are removed in a follow-up commit two weeks after each phase (calendar reminder, not automated).
  • Verifier fails the build on any banned reference outside docs/releases/_archive/. Banned references are derived from each phase's bannedAfter list.
  • Generated content is identified before its source is moved. Each generator's output target is updated in the same commit as the move.
  • Atomic per-phase commits so review is feasible. Reviewers read the script + the path map; they do not read every file diff.

Open questions#

  • Does scripts/docs/generate-oshun-domain-reference.mjs keep generating docs/oshun/domains/, or is the generator retired in favor of docs/domains/<d>/? Decided in Phase 6.
  • Once V1 ships, is docs/releases/v1/audits/ archived wholesale to docs/releases/_archive/v1/audits/, or kept hot indefinitely? Default: archive 6 months after launch.
  • External links (Slack, Notion, public docs, CI dashboards) outside the repo cannot be rewritten by the script. Inventory them before Phase 4 lands.