docs(legibility): migrate CLAUDE.md rules into human docs; mark migrated content #401

Closed
opened 2026-05-04 16:09:28 +02:00 by marcel · 10 comments
Owner

Context

Part of Epic #394 — Documentation. This is DOC-7: the cleanup pass on existing CLAUDE.md files. Today these files contain a mix of (a) LLM-only behavioral instructions and (b) genuine architectural rules and conventions that humans need too. Anything in category (b) needs to live in a human-readable doc — and the CLAUDE.md needs to point there instead of duplicating.

Per the Legibility Rubric, this addresses C5.3 (Major) and supports C7.

Files to process

  • Root CLAUDE.md
  • frontend/CLAUDE.md
  • backend/CLAUDE.md
  • ocr-service/CLAUDE.md
  • docs/CLAUDE.md
  • scripts/CLAUDE.md
  • .devcontainer/CLAUDE.md

Required pattern

For each CLAUDE.md, classify every section into one of three buckets:

Bucket 1 — Human-relevant rules / conventions / architecture

Examples (from current CLAUDE.md): backend layering rules, frontend styling conventions, entity code style, error handling pattern, date handling, brand colors.

Action: migrate to the appropriate human doc:

  • Architecture rules → docs/ARCHITECTURE.md (DOC-2)
  • Coding conventions → CONTRIBUTING.md (DOC-4)
  • Glossary terms → docs/GLOSSARY.md (DOC-3)
  • Per-domain ownership → per-domain README.md (DOC-6)

Then in the original CLAUDE.md, replace the section with a one-line pointer: *Migrated to docs/ARCHITECTURE.md §3.*

Bucket 2 — LLM-only behavioral instructions

Examples: "always run docker commands on a single line for easy copy-paste", "use TaskCreate to track progress", "never write production code without TDD".

Action: keep in CLAUDE.md as-is. These are legitimately LLM-targeted.

Bucket 3 — Stale / obsolete / contradicted-by-refactor content

Examples (post-refactor): the "Layering Rules (strictly enforced)" section in backend/CLAUDE.md documents the layered package structure that the refactor replaces. After REFACTOR-1, that section needs rewriting to document the domain-based package structure.

Action: delete or rewrite. Note in this issue's PR description what was removed.

Anti-patterns

  • Do NOT delete a CLAUDE.md section without verifying the content has either been migrated OR is genuinely obsolete.
  • Do NOT migrate LLM-only instructions into human docs — they confuse human readers.
  • Do NOT leave duplicated content in both places. If it's in a human doc, the CLAUDE.md should point to it, not repeat it.

Acceptance criteria

  • Every section of every listed CLAUDE.md has been classified into bucket 1/2/3
  • Bucket-1 content has been migrated to the correct human doc
  • Bucket-1 sections in CLAUDE.md are replaced with one-line pointers to the migration target
  • Bucket-3 content is deleted or rewritten to match the post-refactor reality
  • PR description includes a per-file summary: "X sections migrated, Y kept, Z removed/rewritten"
  • Audit re-run (CLEANUP-5) verifies C5.3 PASSES

Dependency

Hard dependency on DOC-1, DOC-2, DOC-3, DOC-4 (the human docs must exist before content can migrate into them) and REFACTOR-1, REFACTOR-2 (because some CLAUDE.md content describes the current layered structure).

This issue is therefore one of the LAST docs issues to land — most likely sequenced after Epic 4.

Definition of Done

All 7 CLAUDE.md files processed; PR merged. Closing comment includes the per-file migration summary.

## Context Part of **Epic #394** — Documentation. This is **DOC-7**: the cleanup pass on existing `CLAUDE.md` files. Today these files contain a mix of (a) LLM-only behavioral instructions and (b) genuine architectural rules and conventions that humans need too. Anything in category (b) needs to live in a human-readable doc — and the CLAUDE.md needs to point there instead of duplicating. Per the Legibility Rubric, this addresses **C5.3 (Major)** and supports C7. ## Files to process - Root `CLAUDE.md` - `frontend/CLAUDE.md` - `backend/CLAUDE.md` - `ocr-service/CLAUDE.md` - `docs/CLAUDE.md` - `scripts/CLAUDE.md` - `.devcontainer/CLAUDE.md` ## Required pattern For each CLAUDE.md, classify every section into one of three buckets: ### Bucket 1 — Human-relevant rules / conventions / architecture Examples (from current CLAUDE.md): backend layering rules, frontend styling conventions, entity code style, error handling pattern, date handling, brand colors. **Action:** migrate to the appropriate human doc: - Architecture rules → `docs/ARCHITECTURE.md` (DOC-2) - Coding conventions → `CONTRIBUTING.md` (DOC-4) - Glossary terms → `docs/GLOSSARY.md` (DOC-3) - Per-domain ownership → per-domain `README.md` (DOC-6) Then in the original CLAUDE.md, replace the section with a one-line pointer: `*Migrated to docs/ARCHITECTURE.md §3.*` ### Bucket 2 — LLM-only behavioral instructions Examples: "always run docker commands on a single line for easy copy-paste", "use TaskCreate to track progress", "never write production code without TDD". **Action:** keep in CLAUDE.md as-is. These are legitimately LLM-targeted. ### Bucket 3 — Stale / obsolete / contradicted-by-refactor content Examples (post-refactor): the "Layering Rules (strictly enforced)" section in `backend/CLAUDE.md` documents the *layered* package structure that the refactor replaces. After REFACTOR-1, that section needs rewriting to document the *domain-based* package structure. **Action:** delete or rewrite. Note in this issue's PR description what was removed. ## Anti-patterns - Do NOT delete a CLAUDE.md section without verifying the content has either been migrated OR is genuinely obsolete. - Do NOT migrate LLM-only instructions into human docs — they confuse human readers. - Do NOT leave duplicated content in both places. If it's in a human doc, the CLAUDE.md should point to it, not repeat it. ## Acceptance criteria - [ ] Every section of every listed CLAUDE.md has been classified into bucket 1/2/3 - [ ] Bucket-1 content has been migrated to the correct human doc - [ ] Bucket-1 sections in CLAUDE.md are replaced with one-line pointers to the migration target - [ ] Bucket-3 content is deleted or rewritten to match the post-refactor reality - [ ] PR description includes a per-file summary: "X sections migrated, Y kept, Z removed/rewritten" - [ ] Audit re-run (CLEANUP-5) verifies C5.3 PASSES ## Dependency **Hard dependency** on DOC-1, DOC-2, DOC-3, DOC-4 (the human docs must exist before content can migrate into them) and **REFACTOR-1, REFACTOR-2** (because some CLAUDE.md content describes the current layered structure). This issue is therefore one of the LAST docs issues to land — most likely sequenced after Epic 4. ## Definition of Done All 7 CLAUDE.md files processed; PR merged. Closing comment includes the per-file migration summary.
marcel added this to the (deleted) milestone 2026-05-04 16:09:28 +02:00
marcel added the P2-mediumdocumentationlegibility labels 2026-05-04 16:09:56 +02:00
Author
Owner

🏗️ Markus Keller — Senior Application Architect

Observations

  • The issue's three-bucket classification model is exactly right. The root CLAUDE.md currently mixes LLM behavioral instructions (e.g. "always write docker commands on a single line") with architectural rules (layering, entity code style, error handling) that belong in human-readable docs. These are genuinely different audiences.
  • The dependency sequencing is critical and correctly called out. DOC-2 (docs/ARCHITECTURE.md) and DOC-4 (CONTRIBUTING.md) do not yet exist as files — currently only COLLABORATING.md and CODESTYLE.md exist at root. The issue says "hard dependency on DOC-1/2/3/4," so the implementer must not create pointer-only CLAUDE.md entries pointing at files that don't exist yet.
  • The backend CLAUDE.md is the most architecturally dense: Package Structure, Layering Rules, Entity Code Style, Services pattern, Error Handling, Security/Permissions — all Bucket 1. Currently this exact content also lives in the root CLAUDE.md almost verbatim (compare lines 66–180 of root CLAUDE.md with sections of backend CLAUDE.md). This is the biggest duplication to resolve.
  • After REFACTOR-1 (domain-based package structure replacing the current layered structure), the Package Structure section in backend CLAUDE.md is actively wrong — it still documents controller/, service/, repository/, etc. as top-level packages. The issue correctly classifies this as Bucket 3. Do not migrate this section — rewrite it to document the post-refactor domain structure.
  • The docs/CLAUDE.md and scripts/CLAUDE.md are primarily human-relevant operational docs (folder structure, script descriptions, ADR format). These are almost entirely Bucket 1 and should largely migrate to their respective README.md files per the issue's DOC-6 pattern.

Recommendations

  • Define the migration targets before touching CLAUDE.md files. Map each section explicitly: "This section → docs/ARCHITECTURE.md §3." Do this mapping as a PR description table, not as ad-hoc edits. The issue's acceptance criteria require this anyway.
  • For the root CLAUDE.md: The Stack section, Backend Architecture section, Frontend Architecture section, and most of the API Client Pattern section are Bucket 1. The Common Commands section is borderline — it's useful to both humans and LLMs. Keep a copy in both the human doc and CLAUDE.md if the command set is stable, or make CLAUDE.md point to the README.md sections.
  • For backend CLAUDE.md: Hold the Layering Rules section until REFACTOR-1 lands. Do not migrate outdated content into docs/ARCHITECTURE.md — you'd be migrating a description of a structure that no longer exists post-refactor.
  • Pointer format in CLAUDE.md: The issue proposes *Migrated to docs/ARCHITECTURE.md §3.* — this is good. Make the section header a link too, so the LLM can navigate: *See [docs/ARCHITECTURE.md §Backend Package Structure](../docs/ARCHITECTURE.md#backend-package-structure).*
## 🏗️ Markus Keller — Senior Application Architect ### Observations - The issue's three-bucket classification model is exactly right. The root CLAUDE.md currently mixes LLM behavioral instructions (e.g. "always write docker commands on a single line") with architectural rules (layering, entity code style, error handling) that belong in human-readable docs. These are genuinely different audiences. - The **dependency sequencing is critical and correctly called out**. DOC-2 (`docs/ARCHITECTURE.md`) and DOC-4 (`CONTRIBUTING.md`) do not yet exist as files — currently only `COLLABORATING.md` and `CODESTYLE.md` exist at root. The issue says "hard dependency on DOC-1/2/3/4," so the implementer must not create pointer-only CLAUDE.md entries pointing at files that don't exist yet. - The backend CLAUDE.md is the most architecturally dense: Package Structure, Layering Rules, Entity Code Style, Services pattern, Error Handling, Security/Permissions — all Bucket 1. Currently this exact content also lives in the **root** CLAUDE.md almost verbatim (compare lines 66–180 of root CLAUDE.md with sections of backend CLAUDE.md). This is the biggest duplication to resolve. - After REFACTOR-1 (domain-based package structure replacing the current layered structure), the Package Structure section in backend CLAUDE.md **is actively wrong** — it still documents `controller/`, `service/`, `repository/`, etc. as top-level packages. The issue correctly classifies this as Bucket 3. Do not migrate this section — rewrite it to document the post-refactor domain structure. - The `docs/CLAUDE.md` and `scripts/CLAUDE.md` are primarily human-relevant operational docs (folder structure, script descriptions, ADR format). These are almost entirely Bucket 1 and should largely migrate to their respective `README.md` files per the issue's DOC-6 pattern. ### Recommendations - **Define the migration targets before touching CLAUDE.md files.** Map each section explicitly: "This section → `docs/ARCHITECTURE.md §3`." Do this mapping as a PR description table, not as ad-hoc edits. The issue's acceptance criteria require this anyway. - **For the root CLAUDE.md:** The Stack section, Backend Architecture section, Frontend Architecture section, and most of the API Client Pattern section are Bucket 1. The Common Commands section is borderline — it's useful to both humans and LLMs. Keep a copy in both the human doc and CLAUDE.md if the command set is stable, or make CLAUDE.md point to the `README.md` sections. - **For backend CLAUDE.md:** Hold the Layering Rules section until REFACTOR-1 lands. Do not migrate outdated content into `docs/ARCHITECTURE.md` — you'd be migrating a description of a structure that no longer exists post-refactor. - **Pointer format in CLAUDE.md:** The issue proposes `*Migrated to docs/ARCHITECTURE.md §3.*` — this is good. Make the section header a link too, so the LLM can navigate: `*See [docs/ARCHITECTURE.md §Backend Package Structure](../docs/ARCHITECTURE.md#backend-package-structure).*`
Author
Owner

👨‍💻 Felix Brandt — Senior Fullstack Developer

Observations

  • The three CLAUDE.md files I'd prioritize for review: root (354 lines), backend (179 lines), frontend (197 lines). Together they're 730 lines. The ocr-service (154 lines), docs (97 lines), scripts (144 lines), and devcontainer (96 lines) are smaller and mostly operational — they'll go faster.
  • The root CLAUDE.md currently duplicates backend architecture content almost word-for-word with backend/CLAUDE.md. For example, the "Package Structure", "Layering Rules", "Entity Code Style", "Services", "Error Handling", and "Security" sections appear in both files. This is the clearest Bucket 1 content — it's architectural convention that human contributors need.
  • The root CLAUDE.md's "Common Commands" block (./mvnw spring-boot:run, npm run dev, etc.) is LLM-useful but also human-useful. I'd classify it as Bucket 2 (keep in CLAUDE.md) and also put it in the respective domain README files so humans find it. Duplication here is acceptable — commands are stable and low-maintenance to keep in sync.
  • frontend/CLAUDE.md has a clean structure already: API Client Pattern, Form Actions Pattern, Date Handling, UI Component Library, Styling Conventions. Most of this is Bucket 1 and overlaps with CODESTYLE.md. Specifically the "API Client Pattern" and "Date Handling" sections are developer conventions that belong in the frontend README or CODESTYLE.
  • The scripts/CLAUDE.md is almost entirely Bucket 1 — it documents what each script does and how to run it. This belongs in a scripts/README.md (DOC-6 pattern). The CLAUDE.md can then be reduced to: "Scripts are in scripts/. See scripts/README.md for usage."

Recommendations

  • Start with the easiest wins: scripts/CLAUDE.md and docs/CLAUDE.md are almost pure Bucket 1 operational content. Create scripts/README.md and verify docs/README.md (or the existing docs/CLAUDE.md can just become a pointer). This builds confidence in the classification pattern before tackling the denser files.
  • For frontend/CLAUDE.md: The "Key UI Components" table (PersonTypeahead, PersonMultiSelect, etc.) is exactly the kind of component inventory a human contributor needs. It belongs in the frontend README, not in CLAUDE.md. The "Vite Proxy" and "i18n" sections are similarly human-relevant.
  • Anti-pattern to watch: Don't accidentally reclassify "reminder prompts" as human docs. The phrase "Always check via response.ok, NOT result.error" in the API Client section is written specifically to prevent LLMs from making a common mistake — that's Bucket 2. The underlying convention (use openapi-fetch, check response.ok) is Bucket 1. Separate the reminder from the rule.
## 👨‍💻 Felix Brandt — Senior Fullstack Developer ### Observations - The three CLAUDE.md files I'd prioritize for review: root (354 lines), backend (179 lines), frontend (197 lines). Together they're 730 lines. The ocr-service (154 lines), docs (97 lines), scripts (144 lines), and devcontainer (96 lines) are smaller and mostly operational — they'll go faster. - The root CLAUDE.md currently duplicates backend architecture content almost word-for-word with `backend/CLAUDE.md`. For example, the "Package Structure", "Layering Rules", "Entity Code Style", "Services", "Error Handling", and "Security" sections appear in *both* files. This is the clearest Bucket 1 content — it's architectural convention that human contributors need. - The root CLAUDE.md's "Common Commands" block (`./mvnw spring-boot:run`, `npm run dev`, etc.) is LLM-useful but also human-useful. I'd classify it as Bucket 2 (keep in CLAUDE.md) and also put it in the respective domain README files so humans find it. Duplication here is acceptable — commands are stable and low-maintenance to keep in sync. - `frontend/CLAUDE.md` has a clean structure already: API Client Pattern, Form Actions Pattern, Date Handling, UI Component Library, Styling Conventions. Most of this is Bucket 1 and overlaps with `CODESTYLE.md`. Specifically the "API Client Pattern" and "Date Handling" sections are developer conventions that belong in the frontend README or CODESTYLE. - The `scripts/CLAUDE.md` is almost entirely Bucket 1 — it documents what each script does and how to run it. This belongs in a `scripts/README.md` (DOC-6 pattern). The CLAUDE.md can then be reduced to: "Scripts are in `scripts/`. See `scripts/README.md` for usage." ### Recommendations - Start with the easiest wins: `scripts/CLAUDE.md` and `docs/CLAUDE.md` are almost pure Bucket 1 operational content. Create `scripts/README.md` and verify `docs/README.md` (or the existing `docs/CLAUDE.md` can just become a pointer). This builds confidence in the classification pattern before tackling the denser files. - For `frontend/CLAUDE.md`: The "Key UI Components" table (PersonTypeahead, PersonMultiSelect, etc.) is exactly the kind of component inventory a human contributor needs. It belongs in the frontend README, not in CLAUDE.md. The "Vite Proxy" and "i18n" sections are similarly human-relevant. - **Anti-pattern to watch:** Don't accidentally reclassify "reminder prompts" as human docs. The phrase "Always check via response.ok, NOT result.error" in the API Client section is written specifically to prevent LLMs from making a common mistake — that's Bucket 2. The underlying *convention* (use openapi-fetch, check response.ok) is Bucket 1. Separate the reminder from the rule.
Author
Owner

🔒 Nora Steiner (NullX) — Application Security Engineer

Observations

  • This issue is a documentation refactor, not a code change. There are no direct security vulnerabilities introduced. However, there is one meaningful security risk in the migration process: security-relevant LLM behavioral instructions must not be mistakenly classified as Bucket 2 "keep as-is" when they actually need to land in human-readable security docs.
  • Specifically: the root CLAUDE.md's Security/Permissions section (@RequirePermission, DomainException.forbidden(), parameterized JPQL queries) documents the security model. This is Bucket 1 — it describes conventions that human contributors must follow during code review. If it stays only in CLAUDE.md and not in docs/ARCHITECTURE.md or CODESTYLE.md, a human reviewer won't find it.
  • The backend/CLAUDE.md security section lists available permissions (READ_ALL, WRITE_ALL, ADMIN, etc.) — this is a human reference for permission scoping during feature work. It belongs in docs/ARCHITECTURE.md §Security or a dedicated docs/security-guide.md. Note that docs/security-guide.md already exists. Check whether this content would duplicate or complement it.
  • The ocr-service/CLAUDE.md documents security-relevant environment variables: TRAINING_TOKEN, ALLOWED_PDF_HOSTS. These are operational security controls. A human deploying the service needs to know about them. They belong in ocr-service/README.md (or the existing Docker Compose documentation), not just in an LLM instruction file.
  • Risk of the migration: if a security convention is reclassified as Bucket 3 (stale/obsolete) during refactoring, and removed from CLAUDE.md without migrating it to a human doc, that convention disappears entirely from the project's documented security posture. The issue's anti-pattern list covers this ("Do NOT delete a CLAUDE.md section without verifying...") — good.

Recommendations

  • Cross-check the migration target for all security-relevant sections against docs/security-guide.md before deciding on the target doc. Prefer consolidating into the existing security guide rather than scattering across multiple files.
  • When classifying the Permissions section in backend CLAUDE.md: the @RequirePermission usage example is both a developer guide (Bucket 1 → CODESTYLE.md or ARCHITECTURE.md) and an LLM reminder (Bucket 2 — keep a brief pointer). A one-line LLM hint + a pointer to the full security model is the right split.
  • The PR description's per-file migration summary (required by acceptance criteria) should explicitly flag any security sections that were classified — reviewers need to verify those classifications are correct.
## 🔒 Nora Steiner (NullX) — Application Security Engineer ### Observations - This issue is a documentation refactor, not a code change. There are no direct security vulnerabilities introduced. However, there is one meaningful security risk in the migration process: **security-relevant LLM behavioral instructions must not be mistakenly classified as Bucket 2 "keep as-is" when they actually need to land in human-readable security docs.** - Specifically: the root CLAUDE.md's Security/Permissions section (`@RequirePermission`, `DomainException.forbidden()`, parameterized JPQL queries) documents the security model. This is Bucket 1 — it describes conventions that human contributors must follow during code review. If it stays only in CLAUDE.md and not in `docs/ARCHITECTURE.md` or `CODESTYLE.md`, a human reviewer won't find it. - The `backend/CLAUDE.md` security section lists available permissions (`READ_ALL`, `WRITE_ALL`, `ADMIN`, etc.) — this is a human reference for permission scoping during feature work. It belongs in `docs/ARCHITECTURE.md §Security` or a dedicated `docs/security-guide.md`. Note that `docs/security-guide.md` already exists. Check whether this content would duplicate or complement it. - The `ocr-service/CLAUDE.md` documents security-relevant environment variables: `TRAINING_TOKEN`, `ALLOWED_PDF_HOSTS`. These are operational security controls. A human deploying the service needs to know about them. They belong in `ocr-service/README.md` (or the existing Docker Compose documentation), not just in an LLM instruction file. - Risk of the migration: if a security convention is reclassified as Bucket 3 (stale/obsolete) during refactoring, and removed from CLAUDE.md without migrating it to a human doc, that convention disappears entirely from the project's documented security posture. The issue's anti-pattern list covers this ("Do NOT delete a CLAUDE.md section without verifying...") — good. ### Recommendations - Cross-check the migration target for all security-relevant sections against `docs/security-guide.md` before deciding on the target doc. Prefer consolidating into the existing security guide rather than scattering across multiple files. - When classifying the Permissions section in backend CLAUDE.md: the `@RequirePermission` usage example is both a developer guide (Bucket 1 → CODESTYLE.md or ARCHITECTURE.md) and an LLM reminder (Bucket 2 — keep a brief pointer). A one-line LLM hint + a pointer to the full security model is the right split. - The PR description's per-file migration summary (required by acceptance criteria) should explicitly flag any security sections that were classified — reviewers need to verify those classifications are correct.
Author
Owner

🧪 Sara Holt — QA Engineer & Test Strategist

Observations

  • This issue has no test deliverable in the traditional sense — there are no new tests to write for a documentation refactor. The verification mechanism is the CLEANUP-5 audit re-run mentioned in the acceptance criteria, which will check C5.3 (the Legibility Rubric metric this addresses). That audit is the acceptance gate.

  • The acceptance criteria are well-formed and verifiable:

    • "Every section of every listed CLAUDE.md has been classified into bucket 1/2/3" — verifiable by reviewing the PR description table
    • "Bucket-1 content has been migrated to the correct human doc" — verifiable by checking target files exist and contain the content
    • "Bucket-1 sections in CLAUDE.md are replaced with one-line pointers" — verifiable by diff
    • "PR description includes a per-file summary" — verifiable by reading the PR
    • "CLEANUP-5 audit re-run verifies C5.3 PASSES" — the hard gate
  • One gap in the acceptance criteria: there's no explicit check that pointer links resolve correctly. A CLAUDE.md pointer like *Migrated to docs/ARCHITECTURE.md §3.* can be written and merged even if the target section heading doesn't match. This is a common failure mode in doc migrations.

  • The dependency on DOC-1 through DOC-4 and REFACTOR-1/2 means this issue cannot be tested in isolation. The CLEANUP-5 audit presumably runs against the full state of the docs after all predecessors land.

Recommendations

  • Add one more acceptance criterion: "All pointer links in CLAUDE.md files resolve to existing headings in the target docs." This can be verified with a simple shell script or a grep pass after the migration. Broken links are invisible during review but confusing to future contributors.
  • For the PR review: the per-file migration summary table should have a column for "pointer text added to CLAUDE.md" so reviewers can do a direct mapping check without opening every file.
  • The CLEANUP-5 audit re-run is the right acceptance gate — but make sure the audit criteria for C5.3 are documented somewhere reviewable before this issue lands, so there's no ambiguity about what "PASSES" means when the PR is reviewed.
## 🧪 Sara Holt — QA Engineer & Test Strategist ### Observations - This issue has no test deliverable in the traditional sense — there are no new tests to write for a documentation refactor. The verification mechanism is the **CLEANUP-5 audit re-run** mentioned in the acceptance criteria, which will check C5.3 (the Legibility Rubric metric this addresses). That audit is the acceptance gate. - The acceptance criteria are well-formed and verifiable: - "Every section of every listed CLAUDE.md has been classified into bucket 1/2/3" — verifiable by reviewing the PR description table - "Bucket-1 content has been migrated to the correct human doc" — verifiable by checking target files exist and contain the content - "Bucket-1 sections in CLAUDE.md are replaced with one-line pointers" — verifiable by diff - "PR description includes a per-file summary" — verifiable by reading the PR - "CLEANUP-5 audit re-run verifies C5.3 PASSES" — the hard gate - One gap in the acceptance criteria: there's no explicit check that **pointer links resolve correctly**. A CLAUDE.md pointer like `*Migrated to docs/ARCHITECTURE.md §3.*` can be written and merged even if the target section heading doesn't match. This is a common failure mode in doc migrations. - The dependency on DOC-1 through DOC-4 and REFACTOR-1/2 means this issue cannot be tested in isolation. The CLEANUP-5 audit presumably runs against the full state of the docs after all predecessors land. ### Recommendations - Add one more acceptance criterion: **"All pointer links in CLAUDE.md files resolve to existing headings in the target docs."** This can be verified with a simple shell script or a grep pass after the migration. Broken links are invisible during review but confusing to future contributors. - For the PR review: the per-file migration summary table should have a column for "pointer text added to CLAUDE.md" so reviewers can do a direct mapping check without opening every file. - The CLEANUP-5 audit re-run is the right acceptance gate — but make sure the audit criteria for C5.3 are documented somewhere reviewable *before* this issue lands, so there's no ambiguity about what "PASSES" means when the PR is reviewed.
Author
Owner

🎨 Leonie Voss — UX Designer & Accessibility Strategist

Observations

  • This is a documentation architecture issue, not a UI feature. I have no accessibility or interaction pattern concerns with the code changes themselves.
  • From a developer experience perspective (which is the UX I care about here): the end state of CLAUDE.md files should be scannable in under 30 seconds. A 354-line root CLAUDE.md with mixed LLM-behavioral and architectural content is not scannable — the migration will improve this. Good.
  • One UX concern with the proposed pointer format: *Migrated to docs/ARCHITECTURE.md §3.* — this is italic text with no link. A developer reading the CLAUDE.md in a terminal or in a raw file view (not a rendered Markdown viewer) gets a file path but no clickable anchor. This is a minor friction point but worth noting.
  • The docs/CLAUDE.md currently documents the specs folder, ADR format, architecture diagrams, and infrastructure runbooks. This is entirely human-relevant. After migration, the docs/ folder's CLAUDE.md can potentially be deleted entirely if its content migrates to a docs/README.md. A CLAUDE.md with only pointer lines and no actual LLM guidance provides no value.

Recommendations

  • Use Markdown links in pointers, not just file paths: *Migrated → [docs/ARCHITECTURE.md §Backend Package Structure](../docs/ARCHITECTURE.md#backend-package-structure)* — renders as a clickable link in Gitea, navigable in most editors.
  • After migration, if a CLAUDE.md file is reduced to only pointer lines with no Bucket 2 (LLM-behavioral) content remaining, consider whether that file serves any purpose. An LLM that encounters only "everything here has moved elsewhere" instructions will just follow the links — the file adds no behavioral guidance. Flag these for potential deletion.
  • docs/CLAUDE.md and scripts/CLAUDE.md likely fall into this "potentially deletable after migration" category. Worth a note in the PR description if that turns out to be the case.
## 🎨 Leonie Voss — UX Designer & Accessibility Strategist ### Observations - This is a documentation architecture issue, not a UI feature. I have no accessibility or interaction pattern concerns with the code changes themselves. - From a **developer experience** perspective (which is the UX I care about here): the end state of CLAUDE.md files should be scannable in under 30 seconds. A 354-line root CLAUDE.md with mixed LLM-behavioral and architectural content is not scannable — the migration will improve this. Good. - One UX concern with the proposed pointer format: `*Migrated to docs/ARCHITECTURE.md §3.*` — this is italic text with no link. A developer reading the CLAUDE.md in a terminal or in a raw file view (not a rendered Markdown viewer) gets a file path but no clickable anchor. This is a minor friction point but worth noting. - The `docs/CLAUDE.md` currently documents the specs folder, ADR format, architecture diagrams, and infrastructure runbooks. This is entirely human-relevant. After migration, the `docs/` folder's CLAUDE.md can potentially be deleted entirely if its content migrates to a `docs/README.md`. A CLAUDE.md with only pointer lines and no actual LLM guidance provides no value. ### Recommendations - Use Markdown links in pointers, not just file paths: `*Migrated → [docs/ARCHITECTURE.md §Backend Package Structure](../docs/ARCHITECTURE.md#backend-package-structure)*` — renders as a clickable link in Gitea, navigable in most editors. - After migration, if a CLAUDE.md file is reduced to only pointer lines with no Bucket 2 (LLM-behavioral) content remaining, consider whether that file serves any purpose. An LLM that encounters only "everything here has moved elsewhere" instructions will just follow the links — the file adds no behavioral guidance. Flag these for potential deletion. - `docs/CLAUDE.md` and `scripts/CLAUDE.md` likely fall into this "potentially deletable after migration" category. Worth a note in the PR description if that turns out to be the case.
Author
Owner

⚙️ Tobias Wendt — DevOps & Platform Engineer

Observations

  • No infrastructure changes required by this issue. The migration touches only documentation files — no CI pipeline changes, no Docker Compose changes, no environment variables.
  • The ocr-service/CLAUDE.md documents the environment variables table (KRAKEN_MODEL_PATH, TRAINING_TOKEN, ALLOWED_PDF_HOSTS, batch size configs, etc.). This is operational documentation that a human deploying or configuring the service needs. It is currently only in CLAUDE.md. It belongs in ocr-service/README.md (DOC-6).
  • The .devcontainer/CLAUDE.md (96 lines) documents the dev container configuration: Java 21 + Node 24 features, VS Code extensions, port forwarding, known limitations. This is entirely human-relevant. It belongs in a devcontainer README.md or directly in devcontainer.json as comments. The CLAUDE.md for the devcontainer is the clearest case of a file that is 100% Bucket 1 and could be replaced with a pointer after migration.
  • One operational gap the issue should surface: the scripts/CLAUDE.md documents scripts including reset-db.sh (described as "Destructive operation — only for development!"). This kind of safety warning must not be lost in migration — if it moves to scripts/README.md, it needs to be equally prominent there.

Recommendations

  • For ocr-service/CLAUDE.md: all environment variable documentation is Bucket 1 → ocr-service/README.md. The ocr-service README already exists and already covers some of this. Merge, don't duplicate.
  • For .devcontainer/CLAUDE.md: classify everything as Bucket 1. After migration, this file can be reduced to a single pointer line or deleted.
  • Verify that the scripts/CLAUDE.md migration preserves the destructive-operation warnings with the same visual emphasis (emoji or bold text) in the target scripts/README.md. A plain text migration that loses the warning prominence is a ops risk.
  • No new infrastructure work required here. This is purely a doc reorganization. The CLEANUP-5 audit (not CI) is the verification gate.
## ⚙️ Tobias Wendt — DevOps & Platform Engineer ### Observations - No infrastructure changes required by this issue. The migration touches only documentation files — no CI pipeline changes, no Docker Compose changes, no environment variables. - The `ocr-service/CLAUDE.md` documents the environment variables table (`KRAKEN_MODEL_PATH`, `TRAINING_TOKEN`, `ALLOWED_PDF_HOSTS`, batch size configs, etc.). This is operational documentation that a human deploying or configuring the service needs. It is currently only in CLAUDE.md. It belongs in `ocr-service/README.md` (DOC-6). - The `.devcontainer/CLAUDE.md` (96 lines) documents the dev container configuration: Java 21 + Node 24 features, VS Code extensions, port forwarding, known limitations. This is entirely human-relevant. It belongs in a devcontainer `README.md` or directly in `devcontainer.json` as comments. The CLAUDE.md for the devcontainer is the clearest case of a file that is 100% Bucket 1 and could be replaced with a pointer after migration. - One operational gap the issue should surface: the `scripts/CLAUDE.md` documents scripts including `reset-db.sh` (described as "Destructive operation — only for development!"). This kind of safety warning **must not be lost in migration** — if it moves to `scripts/README.md`, it needs to be equally prominent there. ### Recommendations - For `ocr-service/CLAUDE.md`: all environment variable documentation is Bucket 1 → `ocr-service/README.md`. The ocr-service README already exists and already covers some of this. Merge, don't duplicate. - For `.devcontainer/CLAUDE.md`: classify everything as Bucket 1. After migration, this file can be reduced to a single pointer line or deleted. - Verify that the `scripts/CLAUDE.md` migration preserves the destructive-operation warnings with the same visual emphasis (emoji or bold text) in the target `scripts/README.md`. A plain text migration that loses the warning prominence is a ops risk. - No new infrastructure work required here. This is purely a doc reorganization. The CLEANUP-5 audit (not CI) is the verification gate.
Author
Owner

📋 Elicit — Requirements Engineer

Observations

  • The issue is well-specified. It has a clear bucket classification model, explicit migration targets, an anti-pattern list, and measurable acceptance criteria. This is better than average for a documentation chore.

  • One ambiguity in the classification boundary: The issue distinguishes Bucket 1 (human-relevant rules) from Bucket 2 (LLM-only behavioral instructions), but some content is genuinely both. For example, the API client pattern ("use !result.response.ok for error checking, not if (result.error)") is:

    • A developer convention humans need during code review (Bucket 1)
    • A LLM reminder that prevents a common generation mistake (Bucket 2)

    The issue's current framing implies a section must go into one bucket. A clearer rule: classify by primary audience. If the rule exists mainly because an LLM would get it wrong without the reminder, it's Bucket 2. If the rule exists because a human might get it wrong during review, it's Bucket 1. In practice many sections have both audiences — the migration should not delete LLM-targeted reminders just because the underlying convention also belongs in a human doc.

  • The "Bucket 3 — Stale/Obsolete" classification has a dependency risk: the backend CLAUDE.md documents the current layered package structure (controller/, service/, repository/), which will be wrong after REFACTOR-1. But REFACTOR-1 hasn't landed yet. If this DOC-7 issue is implemented before REFACTOR-1, the Bucket 3 content should be tagged for post-REFACTOR-1 rewrite, not deleted yet. The issue notes this sequencing ("most likely sequenced after Epic 4") — but it's worth making this a hard acceptance-criteria gate, not just a note.

  • The acceptance criteria require a "per-file summary" in the PR description. This is a good traceability mechanism, but the format isn't specified. Recommend requiring a table: File | Sections migrated | Sections kept | Sections deleted/rewritten | Migration targets.

Recommendations

  • Add an explicit acceptance criterion: "No Bucket-3 content from backend CLAUDE.md is deleted until REFACTOR-1 has been verified merged." Currently the sequencing dependency is described in prose but not enforced as a gate.
  • Clarify the "dual-audience" classification in the issue or in the implementing PR: when a section serves both LLMs and humans, the canonical content goes to the human doc; CLAUDE.md retains a brief reminder with a pointer. This is implicitly what the issue intends but isn't stated explicitly.
  • The per-file PR summary should use a structured table format (see above) so reviewers can verify coverage at a glance rather than reading prose.
## 📋 Elicit — Requirements Engineer ### Observations - The issue is well-specified. It has a clear bucket classification model, explicit migration targets, an anti-pattern list, and measurable acceptance criteria. This is better than average for a documentation chore. - **One ambiguity in the classification boundary:** The issue distinguishes Bucket 1 (human-relevant rules) from Bucket 2 (LLM-only behavioral instructions), but some content is **genuinely both**. For example, the API client pattern ("use `!result.response.ok` for error checking, not `if (result.error)`") is: - A developer convention humans need during code review (Bucket 1) - A LLM reminder that prevents a common generation mistake (Bucket 2) The issue's current framing implies a section must go into one bucket. A clearer rule: classify by *primary audience*. If the rule exists mainly because an LLM would get it wrong without the reminder, it's Bucket 2. If the rule exists because a human might get it wrong during review, it's Bucket 1. In practice many sections have both audiences — the migration should not delete LLM-targeted reminders just because the underlying convention also belongs in a human doc. - The "Bucket 3 — Stale/Obsolete" classification has a dependency risk: the backend CLAUDE.md documents the current layered package structure (`controller/`, `service/`, `repository/`), which will be wrong after REFACTOR-1. But REFACTOR-1 hasn't landed yet. If this DOC-7 issue is implemented before REFACTOR-1, the Bucket 3 content should be **tagged for post-REFACTOR-1 rewrite**, not deleted yet. The issue notes this sequencing ("most likely sequenced after Epic 4") — but it's worth making this a hard acceptance-criteria gate, not just a note. - The acceptance criteria require a "per-file summary" in the PR description. This is a good traceability mechanism, but the format isn't specified. Recommend requiring a table: `File | Sections migrated | Sections kept | Sections deleted/rewritten | Migration targets`. ### Recommendations - Add an explicit acceptance criterion: **"No Bucket-3 content from backend CLAUDE.md is deleted until REFACTOR-1 has been verified merged."** Currently the sequencing dependency is described in prose but not enforced as a gate. - Clarify the "dual-audience" classification in the issue or in the implementing PR: when a section serves both LLMs and humans, the canonical content goes to the human doc; CLAUDE.md retains a brief reminder with a pointer. This is implicitly what the issue intends but isn't stated explicitly. - The per-file PR summary should use a structured table format (see above) so reviewers can verify coverage at a glance rather than reading prose.
Author
Owner

🗳️ Decision Queue — Action Required

3 decisions need your input before implementation starts.

Architecture / Sequencing

  • Bucket-3 deletion gate for backend CLAUDE.md — The backend CLAUDE.md's Package Structure and Layering Rules sections are stale (they document the current layered structure, which REFACTOR-1 replaces). The issue says this is Bucket 3, but REFACTOR-1 hasn't landed yet. Options: (A) skip all Bucket-3 deletions from backend CLAUDE.md in this PR and do a follow-up after REFACTOR-1; (B) tag Bucket-3 sections with a <!-- TODO: rewrite post-REFACTOR-1 --> comment and remove from migration scope. Either way, an explicit acceptance criterion gate should be added. (Raised by: Elicit, Markus)

Documentation

  • Dual-audience content classification — Some sections serve both LLMs and humans (e.g. the API Client Pattern's !result.response.ok reminder in frontend/CLAUDE.md). The issue's bucket model implies a section goes into exactly one bucket. Do you want to formalize: "classify by primary audience; dual-audience content gets canonical text in the human doc + a brief pointer-reminder in CLAUDE.md"? Or is the intent that dual-audience content just stays in Bucket 2 (CLAUDE.md) and only clearly human-only architectural rules migrate? (Raised by: Elicit, Felix)

  • Pointer link format — The issue proposes *Migrated to docs/ARCHITECTURE.md §3.* as the replacement text. Leonie flags that this is plain italic text with no clickable link, which is harder to navigate. Do you want to standardize on Markdown links (*See [docs/ARCHITECTURE.md §Section](../docs/ARCHITECTURE.md#section)*) or is the simpler text-only format intentional for some reason (e.g. terminal-readability for LLMs)? This choice should be consistent across all 7 files. (Raised by: Leonie)

## 🗳️ Decision Queue — Action Required _3 decisions need your input before implementation starts._ ### Architecture / Sequencing - **Bucket-3 deletion gate for backend CLAUDE.md** — The backend CLAUDE.md's Package Structure and Layering Rules sections are stale (they document the current layered structure, which REFACTOR-1 replaces). The issue says this is Bucket 3, but REFACTOR-1 hasn't landed yet. Options: (A) skip all Bucket-3 deletions from backend CLAUDE.md in this PR and do a follow-up after REFACTOR-1; (B) tag Bucket-3 sections with a `<!-- TODO: rewrite post-REFACTOR-1 -->` comment and remove from migration scope. Either way, an explicit acceptance criterion gate should be added. _(Raised by: Elicit, Markus)_ ### Documentation - **Dual-audience content classification** — Some sections serve both LLMs and humans (e.g. the API Client Pattern's `!result.response.ok` reminder in `frontend/CLAUDE.md`). The issue's bucket model implies a section goes into exactly one bucket. Do you want to formalize: "classify by primary audience; dual-audience content gets canonical text in the human doc + a brief pointer-reminder in CLAUDE.md"? Or is the intent that dual-audience content just stays in Bucket 2 (CLAUDE.md) and only clearly human-only architectural rules migrate? _(Raised by: Elicit, Felix)_ - **Pointer link format** — The issue proposes `*Migrated to docs/ARCHITECTURE.md §3.*` as the replacement text. Leonie flags that this is plain italic text with no clickable link, which is harder to navigate. Do you want to standardize on Markdown links (`*See [docs/ARCHITECTURE.md §Section](../docs/ARCHITECTURE.md#section)*`) or is the simpler text-only format intentional for some reason (e.g. terminal-readability for LLMs)? This choice should be consistent across all 7 files. _(Raised by: Leonie)_
Author
Owner

Decision Queue — Resolved

The 3 decisions raised in #401#issuecomment-6299:

1. Bucket-3 deletion gate for backend CLAUDE.md → skip Bucket-3 deletions until REFACTOR-1 merges (Option A)

Markus and Elicit converge on this: backend CLAUDE.md's Package Structure and Layering Rules sections describe the current layered structure that REFACTOR-1 replaces. If DOC-7 deletes them now, the project loses its only authoritative description of the current structure before REFACTOR-1 has produced its replacement.

Resolution:

  • DOC-7's PR processes Buckets 1 and 2 fully (migrate human-relevant content; keep LLM-only as-is).
  • Bucket-3 sections that describe the package structure are tagged but not deleted: replace with <!-- TODO: rewrite post-REFACTOR-1 — see Epic 4 -->.
  • Add explicit AC: "No backend/CLAUDE.md package-structure content is deleted until REFACTOR-1 is merged. Tagged-TODO is acceptable; deletion is not."
  • A second cleanup pass (CLEANUP-something or a follow-up issue under DOC-7) handles the actual rewrite when REFACTOR-1 lands.

This adds DOC-7's hard dependency on REFACTOR-1 for completion, but not for the PR itself — the PR can ship most of the work and leave a tagged TODO.

2. Dual-audience content classification → canonical to human doc + brief pointer-reminder in CLAUDE.md (formalize Elicit's framing)

Elicit and Felix both surfaced this. Some content (e.g. "use !result.response.ok, not if (result.error)") serves both audiences:

  • The convention ("check response.ok before reading data") is a human-readable rule → goes in CONTRIBUTING.md (#398).
  • The reminder ("don't reach for result.error — that breaks when the spec has no error responses defined") is an LLM-targeted note that prevents a common generation mistake → stays in CLAUDE.md.

Formalized rule (per epic-level D3 + this issue's framing):

For dual-audience sections:

  1. Move the canonical convention to the appropriate human doc (CONTRIBUTING.md / ARCHITECTURE.md / domain README / GLOSSARY.md).
  2. Replace the CLAUDE.md section with a pointer + LLM-targeted reminder:
    ## API Client Pattern
    → See [CONTRIBUTING.md §Frontend API Client](../CONTRIBUTING.md#frontend-api-client)
    
    **LLM reminder:** check `!result.response.ok` (not `result.error`); cast errors as `result.error as unknown as { code?: string }`.
    

The reminder lines stay in CLAUDE.md when they exist mainly to prevent LLM mistakes. The canonical text lives in the human doc.

This is consistent with the epic-level Decision Queue D3 "pointer-comment policy" — DOC-7 just adds the optional reminder line for LLM-helpful content.

Standardize on the linked form across all CLAUDE.md migrations:

## <Section name>
→ See [<target-doc> §<heading>](<relative-path>#<anchor>)

Example:

## Layering Rules
→ See [CONTRIBUTING.md §Walkthrough — Add a new domain](../CONTRIBUTING.md#walkthrough-add-a-new-domain)

Plain text loses no terminal-readability worth keeping (the LLM can still parse the link target), but renders as a clickable link in Gitea, VS Code Markdown preview, and most editors. No reason to use the unlinked form.


📌 Additional persona feedback to fold into implementation

  • Markus: map every section to a target before touching files — present the mapping as a PR description table, not as ad-hoc edits. Required by AC anyway.

  • Markus: root CLAUDE.md and backend CLAUDE.md duplicate architectural content almost word-for-word. Resolve the duplication by migrating to the canonical human doc once and leaving pointers in both CLAUDE.md files.

  • Markus: docs/CLAUDE.md and scripts/CLAUDE.md are almost entirely Bucket 1. After migration they may collapse to pointer-only files — flag for potential deletion (per Leonie's recommendation).

  • Felix: start easiest firstscripts/CLAUDE.md and docs/CLAUDE.md are mostly pure Bucket 1 operational content. Builds confidence in the classification pattern before tackling root + backend + frontend (the dense ones).

  • Felix: frontend/CLAUDE.md "Key UI Components" table (PersonTypeahead, PersonMultiSelect, TagInput) belongs in the relevant frontend domain READMEs (#400) — split it: PersonTypeahead → lib/person/README.md, TagInput → lib/tag/README.md. Don't keep a generic "components" table in CLAUDE.md.

  • Nora: cross-check all security-sensitive sections against docs/security-guide.md before deciding migration target. Prefer consolidating into the existing security guide rather than scattering. Specifically: backend CLAUDE.md's Security/Permissions section, ocr-service/CLAUDE.md's TRAINING_TOKEN/ALLOWED_PDF_HOSTS, root CLAUDE.md's Security/Permissions reference.

  • Nora: flag every security-relevant migration in the per-file PR summary table — reviewer must verify those classifications.

  • Sara: add AC: "All pointer links in CLAUDE.md files resolve to existing headings." Verifiable with a markdown link checker (markdown-link-check or grep + custom script). Broken pointer links are invisible during review but confusing to future readers.

  • Sara: PR description's per-file summary should include a "pointer text added to CLAUDE.md" column for direct mapping verification.

  • Leonie: flag Tobias's point — .devcontainer/CLAUDE.md is 100% Bucket 1; after migration it can be reduced to a pointer line OR deleted entirely. Same for docs/CLAUDE.md. Make this an explicit decision per file.

  • Tobias: preserve destructive-operation warnings with the same visual emphasis when migrating scripts/CLAUDE.mdscripts/README.md. The "Destructive — only for development!" callout on reset-db.sh must survive the migration.

  • Tobias: ocr-service/CLAUDE.md → check ocr-service/README.md (DOC-6 / #400) — already exists and already covers some of this. Merge, don't duplicate.

  • Elicit: structured per-file migration table format:

    File Sections migrated Sections kept Sections tagged-TODO / rewritten Migration targets

    Required in PR description.

  • Elicit: explicit AC sequencing — DOC-7's PR ships fully when DOC-2 (#396), DOC-4 (#398), DOC-5 (#399), DOC-6 (#400) are all merged. Do not merge DOC-7 before its migration targets exist.


🔗 Sequencing summary (so future-you doesn't re-derive it)

DOC-7 is the last doc PR. Its dependencies:

  • Hard: DOC-2 (#396) + DOC-4 (#398) + DOC-5 (#399) + DOC-6 (#400) all merged (= migration targets exist).
  • Soft (for completion, not for ship): REFACTOR-1 merged (= Bucket-3 backend package-structure rewrite is unblocked).

Suggested order: DOC-3 → DOC-1 → DOC-2 → DOC-4 → DOC-5 → DOC-6 (stub phase with refactor) → REFACTOR-1 → REFACTOR-2 → DOC-6 (complete) → DOC-7 (this issue) → CLEANUP-5 audit re-run.

Status: Ready when its dependencies land. Authoring can start as soon as DOC-2, DOC-4, DOC-5 are merged (Bucket-1 migrations have somewhere to go).

## ✅ Decision Queue — Resolved The 3 decisions raised in [#401#issuecomment-6299](http://heim-nas:3005/marcel/familienarchiv/issues/401#issuecomment-6299): ### 1. Bucket-3 deletion gate for backend CLAUDE.md → **skip Bucket-3 deletions until REFACTOR-1 merges (Option A)** Markus and Elicit converge on this: backend CLAUDE.md's Package Structure and Layering Rules sections describe the *current* layered structure that REFACTOR-1 replaces. If DOC-7 deletes them now, the project loses its only authoritative description of the current structure before REFACTOR-1 has produced its replacement. **Resolution:** - DOC-7's PR processes Buckets 1 and 2 fully (migrate human-relevant content; keep LLM-only as-is). - Bucket-3 sections that describe the package structure are **tagged but not deleted**: replace with `<!-- TODO: rewrite post-REFACTOR-1 — see Epic 4 -->`. - Add explicit AC: **"No backend/CLAUDE.md package-structure content is deleted until REFACTOR-1 is merged. Tagged-TODO is acceptable; deletion is not."** - A second cleanup pass (CLEANUP-something or a follow-up issue under DOC-7) handles the actual rewrite when REFACTOR-1 lands. This adds DOC-7's hard dependency on REFACTOR-1 for **completion**, but not for the PR itself — the PR can ship most of the work and leave a tagged TODO. ### 2. Dual-audience content classification → **canonical to human doc + brief pointer-reminder in CLAUDE.md (formalize Elicit's framing)** Elicit and Felix both surfaced this. Some content (e.g. "_use `!result.response.ok`, not `if (result.error)`_") serves both audiences: - The **convention** ("check response.ok before reading data") is a human-readable rule → goes in CONTRIBUTING.md (#398). - The **reminder** ("don't reach for `result.error` — that breaks when the spec has no error responses defined") is an LLM-targeted note that prevents a common generation mistake → stays in CLAUDE.md. **Formalized rule (per epic-level D3 + this issue's framing):** For dual-audience sections: 1. Move the **canonical convention** to the appropriate human doc (CONTRIBUTING.md / ARCHITECTURE.md / domain README / GLOSSARY.md). 2. Replace the CLAUDE.md section with a **pointer + LLM-targeted reminder**: ```markdown ## API Client Pattern → See [CONTRIBUTING.md §Frontend API Client](../CONTRIBUTING.md#frontend-api-client) **LLM reminder:** check `!result.response.ok` (not `result.error`); cast errors as `result.error as unknown as { code?: string }`. ``` The reminder lines stay in CLAUDE.md when they exist mainly to prevent LLM mistakes. The canonical text lives in the human doc. This is consistent with the **epic-level Decision Queue D3** "pointer-comment policy" — DOC-7 just adds the optional reminder line for LLM-helpful content. ### 3. Pointer link format → **Markdown links, not plain text (per Leonie)** Standardize on the linked form across all CLAUDE.md migrations: ```markdown ## <Section name> → See [<target-doc> §<heading>](<relative-path>#<anchor>) ``` Example: ```markdown ## Layering Rules → See [CONTRIBUTING.md §Walkthrough — Add a new domain](../CONTRIBUTING.md#walkthrough-add-a-new-domain) ``` Plain text loses no terminal-readability worth keeping (the LLM can still parse the link target), but renders as a clickable link in Gitea, VS Code Markdown preview, and most editors. **No reason to use the unlinked form.** --- ## 📌 Additional persona feedback to fold into implementation - **Markus:** map every section to a target **before touching files** — present the mapping as a PR description table, not as ad-hoc edits. Required by AC anyway. - **Markus:** root CLAUDE.md and backend CLAUDE.md duplicate architectural content almost word-for-word. Resolve the duplication by migrating to the canonical human doc once and leaving pointers in **both** CLAUDE.md files. - **Markus:** `docs/CLAUDE.md` and `scripts/CLAUDE.md` are almost entirely Bucket 1. After migration they may collapse to pointer-only files — flag for potential deletion (per Leonie's recommendation). - **Felix:** **start easiest first** — `scripts/CLAUDE.md` and `docs/CLAUDE.md` are mostly pure Bucket 1 operational content. Builds confidence in the classification pattern before tackling root + backend + frontend (the dense ones). - **Felix:** `frontend/CLAUDE.md` "Key UI Components" table (PersonTypeahead, PersonMultiSelect, TagInput) belongs in the relevant frontend domain READMEs (#400) — split it: PersonTypeahead → `lib/person/README.md`, TagInput → `lib/tag/README.md`. Don't keep a generic "components" table in CLAUDE.md. - **Nora:** **cross-check all security-sensitive sections against `docs/security-guide.md`** before deciding migration target. Prefer consolidating into the existing security guide rather than scattering. Specifically: backend CLAUDE.md's Security/Permissions section, ocr-service/CLAUDE.md's TRAINING_TOKEN/ALLOWED_PDF_HOSTS, root CLAUDE.md's Security/Permissions reference. - **Nora:** flag every security-relevant migration in the per-file PR summary table — reviewer must verify those classifications. - **Sara:** **add AC: "All pointer links in CLAUDE.md files resolve to existing headings."** Verifiable with a markdown link checker (`markdown-link-check` or grep + custom script). Broken pointer links are invisible during review but confusing to future readers. - **Sara:** PR description's per-file summary should include a "_pointer text added to CLAUDE.md_" column for direct mapping verification. - **Leonie:** flag Tobias's point — `.devcontainer/CLAUDE.md` is 100% Bucket 1; after migration it can be reduced to a pointer line OR deleted entirely. Same for `docs/CLAUDE.md`. Make this an explicit decision per file. - **Tobias:** preserve **destructive-operation warnings** with the same visual emphasis when migrating `scripts/CLAUDE.md` → `scripts/README.md`. The "_Destructive — only for development!_" callout on `reset-db.sh` must survive the migration. - **Tobias:** `ocr-service/CLAUDE.md` → check `ocr-service/README.md` (DOC-6 / #400) — already exists and already covers some of this. **Merge, don't duplicate.** - **Elicit:** structured per-file migration table format: | File | Sections migrated | Sections kept | Sections tagged-TODO / rewritten | Migration targets | |---|---|---|---|---| Required in PR description. - **Elicit:** explicit AC sequencing — DOC-7's PR ships fully when DOC-2 (#396), DOC-4 (#398), DOC-5 (#399), DOC-6 (#400) are all merged. **Do not merge DOC-7 before its migration targets exist.** --- ## 🔗 Sequencing summary (so future-you doesn't re-derive it) DOC-7 is the **last** doc PR. Its dependencies: - **Hard:** DOC-2 (#396) + DOC-4 (#398) + DOC-5 (#399) + DOC-6 (#400) all merged (= migration targets exist). - **Soft (for completion, not for ship):** REFACTOR-1 merged (= Bucket-3 backend package-structure rewrite is unblocked). Suggested order: DOC-3 → DOC-1 → DOC-2 → DOC-4 → DOC-5 → DOC-6 (stub phase with refactor) → REFACTOR-1 → REFACTOR-2 → DOC-6 (complete) → **DOC-7 (this issue)** → CLEANUP-5 audit re-run. **Status:** Ready when its dependencies land. Authoring can start as soon as DOC-2, DOC-4, DOC-5 are merged (Bucket-1 migrations have somewhere to go).
Author
Owner

DOC-7 implemented — PR #445

All 7 CLAUDE.md files processed. Branch: feat/issue-401-claude-migration.

Per-file summary

File Migrated Kept (Bucket-2) Tagged TODO New file
scripts/CLAUDE.md All 9 script docs scripts/README.md
.devcontainer/CLAUDE.md Config, usage, limitations .devcontainer/README.md
docs/CLAUDE.md Folder structure, ADR guide, specs ADR reminder docs/README.md
ocr-service/CLAUDE.md All (to ocr-service/README.md DOC-6) Single-node + SSRF reminders
backend/CLAUDE.md Layering Rules, Error Handling, Security → human docs Key Entities, Entity Code Style, Services, OCR, How to Run, Testing Package Structure
root CLAUDE.md Stack, Layering, Error Handling, Security, OpenAPI, API Client, Date Handling, UI Components, Infrastructure, Dev Container Common Commands, Domain Model, Entity Code Style, Form Actions, Styling, Route Structure Package Structure
frontend/CLAUDE.md API Client, Date Handling → CONTRIBUTING.md; Key UI Components → domain READMEs Project Structure, Form Actions, Styling, How to Run, Vite Proxy, i18n

Fixes applied during migration

  • backend/CLAUDE.md stale errors.ts path fixed → frontend/src/lib/shared/errors.ts
  • Permission enum updated to include ANNOTATE_ALL and BLOG_WRITE
  • ⚠️ Destructive-operation warning on reset-db.sh preserved in scripts/README.md (per Tobias)

Merge order

PR #445 must merge after DOC-2 (#441), DOC-4 (#442), DOC-5 (#443), DOC-6 (#444) — pointer links target files introduced by those PRs.

## ✅ DOC-7 implemented — PR #445 All 7 CLAUDE.md files processed. Branch: `feat/issue-401-claude-migration`. ### Per-file summary | File | Migrated | Kept (Bucket-2) | Tagged TODO | New file | |---|---|---|---|---| | `scripts/CLAUDE.md` | All 9 script docs | — | — | `scripts/README.md` | | `.devcontainer/CLAUDE.md` | Config, usage, limitations | — | — | `.devcontainer/README.md` | | `docs/CLAUDE.md` | Folder structure, ADR guide, specs | ADR reminder | — | `docs/README.md` | | `ocr-service/CLAUDE.md` | All (to `ocr-service/README.md` DOC-6) | Single-node + SSRF reminders | — | — | | `backend/CLAUDE.md` | Layering Rules, Error Handling, Security → human docs | Key Entities, Entity Code Style, Services, OCR, How to Run, Testing | Package Structure | — | | `root CLAUDE.md` | Stack, Layering, Error Handling, Security, OpenAPI, API Client, Date Handling, UI Components, Infrastructure, Dev Container | Common Commands, Domain Model, Entity Code Style, Form Actions, Styling, Route Structure | Package Structure | — | | `frontend/CLAUDE.md` | API Client, Date Handling → CONTRIBUTING.md; Key UI Components → domain READMEs | Project Structure, Form Actions, Styling, How to Run, Vite Proxy, i18n | — | — | ### Fixes applied during migration - `backend/CLAUDE.md` stale `errors.ts` path fixed → `frontend/src/lib/shared/errors.ts` - Permission enum updated to include `ANNOTATE_ALL` and `BLOG_WRITE` - ⚠️ Destructive-operation warning on `reset-db.sh` preserved in `scripts/README.md` (per Tobias) ### Merge order PR #445 **must merge after** DOC-2 (#441), DOC-4 (#442), DOC-5 (#443), DOC-6 (#444) — pointer links target files introduced by those PRs.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#401