- Date: 2026-06-18
- Status: Accepted (codifies existing convention; rejects collocation alternatives)
Context
A recurring contributor / maintainer question: why does each Studio tool have its documentation in docs/<tool>/ and its code in apps/web/src/dev-tools/studio/<tool>/? Could the two be collocated under the same folder?
The question is legitimate. Three alternatives exist:
- Separation (current).
docs/<tool>/+apps/web/src/dev-tools/studio/<tool>/. Linked by naming convention. - Collocation A — docs inside code.
apps/web/src/dev-tools/studio/<tool>/{*.tsx, docs/*.md}. One folder per tool, everything inside. - Collocation B — code inside docs.
docs/<tool>/{*.md, code/*.tsx}. Not buildable — Next.js / Vite expect code underapps/orpackages/. Rejected outright.
ADR 0058 (Studio tools documentation pattern) settled the file shape; this ADR settles the location.
Decision
Documentation stays in docs/; code stays in apps/ and packages/. The two are linked by naming convention (docs/<tool>/ ↔ apps/web/src/dev-tools/studio/<tool>/), not by colocation.
Layout
arno/
├── docs/
│ ├── _index.md # top-level navigator
│ ├── glossary.md # cross-tool vocabulary
│ ├── architecture.md # C4 diagrams
│ ├── testing-standard.md # test-layer standard
│ ├── adr/ # decision records
│ ├── kernel/ # shared kernel docs
│ ├── layers/ # 12 .md files
│ ├── nav-bar/ # 12 .md files
│ ├── punta/ # 12 .md files
│ └── ...
├── apps/web/src/dev-tools/studio/
│ ├── _index.md # umbrella + dependency graph
│ ├── README.md # human-facing intro
│ ├── layers/ # .tsx, .css, .test.ts ONLY
│ ├── nav-bar/ # .tsx, .css, .test.ts ONLY
│ ├── punta/ # .tsx, .css, .test.ts ONLY
│ └── ...
└── packages/
└── foundation/ # design tokens, etc.The link
The convention is mechanical: a tool named <tool> has its code under apps/web/src/dev-tools/studio/<tool>/ and its docs under docs/<tool>/. The Studio umbrella (apps/web/src/dev-tools/studio/_index.md) is the single canonical map of which <tool> names exist. CI check (scripts/check-doc-completeness.ts) enforces both directions:
- A tool with code but no docs → CI fails.
- A doc folder with no corresponding code folder → CI fails (unless explicitly marked
<scaffolding>).
Why separation, not collocation
Industry precedent
Every major monorepo we benchmarked follows the same separation:
| Project | Docs location | Code location |
|---|---|---|
| React (Meta) | docs/ (separate react.dev repo for site; in-repo READMEs) | packages/react/ |
| Vue.js | docs/ (separate vuejs/docs repo) | packages/ |
| Next.js | docs/ | packages/next/ |
| Astro | docs/ | packages/astro/ |
| TypeScript | doc/ | src/ |
| Bun | docs/ | src/ |
| Storybook | docs/ (separate site repo) | code/ |
The pattern is overwhelming. Contributors arrive expecting separation; collocation would be the surprise.
Build pipeline simplicity
Next.js scans apps/web/src/**/*.{ts,tsx,js,jsx,mdx} for routes and modules. Markdown files inside the source tree must be excluded from build (or they become accidental routes). Separation avoids the exclusion entirely:
apps/web/src/dev-tools/studio/<tool>/is pure code. Next.js builds it.docs/<tool>/is pure prose. Next.js never touches it.
Lang-check (scripts/check-language.ts), spell-check, and any future doc linter scan docs/**/*.md with a single glob. Collocation would require nested globs (apps/web/src/**/docs/**/*.md) that are harder to maintain and slower to run.
GitHub UI
GitHub's repository browser renders the top-level docs/ folder prominently. A reader landing on the repo sees docs/ next to apps/ and packages/. The intent is legible at a glance.
With collocation, the docs are buried under apps/web/src/dev-tools/studio/<tool>/docs/. A reader must dig four levels to find them. The signal that "this project documents itself" is lost.
Cross-tool comparison
Reviewing the docs surface for consistency is mechanical with separation:
ls docs/ # lists all documented surfaces
diff docs/punta/contract.md docs/dito/contract.md # compare two tools' contracts side-by-sideWith collocation:
find apps/web/src/dev-tools/studio -type d -name docs # finds them but requires globsThe convenience of ls docs/ over find ... is small per use; large over a year.
CI scope
The lang-check workflow runs on pull_request with paths: ['docs/**']. If docs move into the code tree, the path filter must change to paths: ['apps/web/src/dev-tools/studio/**/docs/**']. Functional but uglier. The separation keeps CI rules readable.
Where collocation IS allowed
The separation rule applies to Studio tools and project-wide ARNO docs. Three carve-outs:
- Per-package READMEs. A
packages/foundation/README.mdis allowed and expected — it documents the package's public API and is published with npm if we ever publish. - Inline JSDoc + type comments. These ARE the code. They live in
*.ts/*.tsxfiles and document symbols at definition time. Not subject to this ADR. .claude/agent docs. The agent orchestration system has its own internal docs under.claude/. Those are operational state, not architectural docs. Not subject to this ADR.
Anything outside these three carve-outs follows the separation rule.
Consequences
Positive
- Industry-standard layout. Contributors arrive expecting the shape we ship.
- Clean build pipeline. No exclusion globs needed.
- Trivial cross-tool review.
ls docs/is the surface. - Lang-check / spell-check simple. One glob.
- GitHub UI cooperation. The docs/ folder is prominent.
Negative
- Two folders touched per tool change. Every PR that touches
studio/<tool>/also touchesdocs/<tool>/. Slightly moregit addper PR. - Rename is two
git mvcalls. Mitigated by mechanical script if it becomes painful. - Onboarding question. "Where are the docs?" — answered once per contributor. Trivial.
Risk: docs out of sync with code
The biggest failure mode is code outpacing docs. With separation, a stale doc is in a separate folder and easy to overlook. Mitigation:
- The CI check (
scripts/check-doc-completeness.ts) fails when a tool has code but no docs. - The Danger soft-warning (planned) flags PRs that touch
studio/<tool>/but notdocs/<tool>/. - Each tool's
migration.mdrequires a contract-version bump on contract change, which forces a doc edit.
Alternatives considered
Collocation A — docs inside code (studio/<tool>/{*.tsx, docs/*.md})
Pros: one folder per tool; rename = one git operation; immediate proximity for the developer working inside the code folder.
Cons: breaks Next.js build assumptions; requires path-glob exclusions; loses GitHub UI prominence; loses ls docs/ convenience; loses lang-check single-glob simplicity; diverges from industry default.
Rejected. The "one folder per tool" benefit is real but small. The cumulative cost across build / CI / review / discovery is larger.
Collocation B — code inside docs (docs/<tool>/{*.md, code/*.tsx})
Cons: unbuildable. Next.js / Vite scan apps/ and packages/ for entry points; code under docs/ would be invisible.
Rejected outright.
Symlinks
docs/<tool> → apps/web/src/dev-tools/studio/<tool>/docs/. Or vice versa.
Cons: symlinks break on Windows; git's handling of symlinks across platforms is fragile; IDE search doubles results; pre-commit hooks frequently see symlinks as untracked.
Rejected. Not worth the cross-platform risk.
References
- Industry comparison cited above.
- Related ADRs: 0058 (canonical file set), 0059 (naming chord), 0061 (
layerTypeOfshared dispatch). Rules.md§"Studio tools — documentation pattern" §"Code folders" — the prose form that points here.