docs(legibility): migrate CLAUDE.md rules into human docs — DOC-7 #445
Reference in New Issue
Block a user
Delete Branch "feat/issue-401-claude-migration"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #401
⚠️ Merge order constraint: this PR must merge AFTER DOC-2 (#441), DOC-4 (#442), DOC-5 (#443), DOC-6 (#444). Several pointer links point to files that exist on those branches but not yet on
main.What this does
Processes all 7 CLAUDE.md files through the 3-bucket classification from the decision queue:
<!-- TODO: rewrite post-REFACTOR-1 — see Epic 4 -->(not deleted, per decision queue option A)Pointer format (standardised per decision queue D3):
→ See [Target §Section](path#anchor)Dual-audience sections: canonical convention in the human doc; CLAUDE.md keeps a brief LLM reminder line for content that prevents common generation mistakes.
Per-file migration summary
scripts/CLAUDE.mdscripts/README.md✅.devcontainer/CLAUDE.md.devcontainer/README.md✅docs/CLAUDE.mddocs/README.md✅ocr-service/CLAUDE.mdocr-service/README.mdfrom DOC-6)backend/CLAUDE.mdroot CLAUDE.mdfrontend/CLAUDE.mdSecurity-relevant migrations (flagged per Nora's feedback)
@RequirePermission,Permissionenum)docs/ARCHITECTURE.md §Permission systemALLOWED_PDF_HOSTSSSRF warningocr-service/README.md(DOC-6)ocr-service/CLAUDE.mdTRAINING_TOKENoperational noteocr-service/README.md(DOC-6) +docs/DEPLOYMENT.md(DOC-5)CONTRIBUTING.md §Error handlingFixes applied during migration
backend/CLAUDE.mdhad staleerrors.tspath (src/lib/errors.ts) → corrected tofrontend/src/lib/shared/errors.tsbackend/CLAUDE.mdpermissions list was missingANNOTATE_ALLandBLOG_WRITE→ addedscripts/README.mdpreserves the ⚠️ destructive-operation warning onreset-db.shwith same visual emphasis (per Tobias's feedback)Pointer link resolution
All pointer links point to section headings that exist (or will exist when this merges after its dependencies):
docs/ARCHITECTURE.md#layering-rule— in DOC-2 PR docs(legibility): DOC-2 — write docs/ARCHITECTURE.md (#441)docs/ARCHITECTURE.md#permission-system— in DOC-2 PR docs(legibility): DOC-2 — write docs/ARCHITECTURE.md (#441)CONTRIBUTING.md#error-handling— in DOC-4 PR docs(legibility): DOC-4 — write CONTRIBUTING.md with three concrete walkthroughs (#442)CONTRIBUTING.md#frontend-api-client— in DOC-4 PR docs(legibility): DOC-4 — write CONTRIBUTING.md with three concrete walkthroughs (#442)CONTRIBUTING.md#date-handling— in DOC-4 PR docs(legibility): DOC-4 — write CONTRIBUTING.md with three concrete walkthroughs (#442)docs/DEPLOYMENT.md— in DOC-5 PR docs(legibility): DOC-5 — write docs/DEPLOYMENT.md (#443)Files that became pointer-only after migration
scripts/CLAUDE.md— 1-line pointer + reminder.devcontainer/CLAUDE.md— 1-line pointerocr-service/CLAUDE.md— 2-line pointer + remindersdocs/CLAUDE.md— 1-line pointer + ADR reminderNone were deleted (kept for completeness and discoverability).
Test plan
<!-- TODO: rewrite post-REFACTOR-1 -->, not deletedscripts/README.md,.devcontainer/README.md,docs/README.mdcreatedreset-db.shinscripts/README.md🤖 Generated with Claude Code
Review: Markus Keller (Senior Architect)
Verdict: Changes requested
Bucket classifications
Overall the classification is sound. The split between human-relevant conventions (Bucket 1) and LLM-only behavioral instructions (Bucket 2) is applied consistently across all 7 files. Bucket 3 usage is appropriately narrow — only Package Structure gets the TODO tag in both root and backend CLAUDE.md files, which matches the PR description.
One classification concern: the
docs/CLAUDE.mdsection "How to Use" (check specs/ before implementing, write ADR before coding, follow production-compose for deployment, keep TODOs updated) reads as human-workflow guidance, not LLM instruction. It was fully removed with no pointer — only the ADR sequencing rule survived as an LLM reminder. The "check specs/ before implementing" step has clear human relevance and arguably belongs indocs/README.md. Minor — the README does include "Before implementing a feature, checkspecs/" so the substance is preserved.Pointer link resolution
The PR documents all 7 pointer targets and explains the merge-order dependency on DOC-2, DOC-4, DOC-5, DOC-6. I verified the dependent files do not yet exist on
main:docs/ARCHITECTURE.md— absent (DOC-2, #441) ✓ dependency documentedCONTRIBUTING.md— absent (DOC-4, #442) ✓ dependency documenteddocs/DEPLOYMENT.md— absent (DOC-5, #443) ✓ dependency documentedocr-service/README.md— absent (DOC-6, #444) ✓ dependency documentedAll pointer paths use the correct relative path notation (
./docs/ARCHITECTURE.md,../CONTRIBUTING.md, etc.). The.devcontainer/CLAUDE.mdpointer→ See [.devcontainer/README.md](./README.md)correctly resolves to the sibling file.Blocker:
docs/README.mdhas a duplicateinfrastructure/entry in the folder treeThe folder structure tree in the new
docs/README.mdlistsinfrastructure/twice:The second entry should not exist. The original
docs/CLAUDE.mdlistedinfrastructure/once in the tree (with description "Deployment, CI/CD, and ops guides"). The second entry appears to be a stray artifact from the migration rewrite. The tree also omits several real directories/files that exist indocs/:audits/,presentation/,mail.md,TODO-backend.md,TODO-frontend.md. The old CLAUDE.md listed the TODO files explicitly; they were dropped without comment.What's done well
→ See [Target §Section](path#anchor)) is consistent throughout.Review: Felix Brandt (Senior Developer)
Verdict: Approved (with a note)
LLM reminder accuracy
Checked all reminders for accuracy against the actual codebase:
frontend/src/lib/shared/errors.ts— verified to exist at exactly that path. The reminder in both root and backend CLAUDE.md correctly usesfrontend/src/lib/shared/errors.ts. This is the fix documented in the PR description (old path wassrc/lib/errors.ts). ✓$lib/shared/primitives/BackButton.svelte— verified to exist at/frontend/src/lib/shared/primitives/BackButton.svelte. The reminder is accurate. ✓$lib/shared/api.server— the import alias resolves tofrontend/src/lib/shared/api.server.ts, which exists. ✓@RequirePermissionreminder — the reminder says it is required on everyPOST,PUT,PATCH,DELETE. The enum check confirmed all 8 values are listed:READ_ALL,WRITE_ALL,ADMIN,ADMIN_USER,ADMIN_TAG,ADMIN_PERMISSION,ANNOTATE_ALL,BLOG_WRITE. Complete and accurate. ✓API client reminder — "check
!result.response.ok(notresult.error)" is consistent across root CLAUDE.md and frontend/CLAUDE.md. In frontend/CLAUDE.md the reminder also adds "For multipart/form-data (file uploads), bypass the typed client and use rawfetch" — that extra sentence in frontend/CLAUDE.md but absent from root is intentional asymmetry (root has less frontend detail). Fine.Date handling reminder — accurately says append
T12:00:00to prevent UTC off-by-one. ✓OpenAPI generation reminder — "always run
npm run generate:apiinfrontend/" — accurate. ✓Note:
api.serverpath format in reminderThe
frontend/CLAUDE.mdreminder saysAPI client is at $lib/shared/api.server. The actual file isapi.server.ts. When an LLM generates an import, it would writeimport { createApiClient } from '$lib/shared/api.server'(without the.ts), which is correct SvelteKit convention. No change needed — just noting it's intentionally extension-free.Content not migrated / not kept — check
backend/CLAUDE.mdwithout a pointer or reminder. The--spring.profiles.active=devflag is still mentioned in the "How to Run" → "OpenAPI / TypeScript type generation" sub-section, so the essential usage is preserved. The prod vs dev distinction isn't LLM-relevant for code generation. Acceptable as Bucket 1 migrated to DEPLOYMENT.md (DOC-5).ResponseStatusExceptionusage for simple controller validation — was in the old backend Error Handling section, not in the new reminder. This is a minor loss: an LLM that doesn't know this may useDomainExceptionfor parameter validation (which is over-engineered). Low impact — not a blocker.Domain README pointers
Both root CLAUDE.md and frontend/CLAUDE.md point to domain READMEs (
src/lib/person/README.mdetc.) that don't exist yet onmain. These will exist after DOC-6 (#444). The merge-order dependency is documented. No issue.What's done well
src/lib/errors.ts→frontend/src/lib/shared/errors.ts, addingANNOTATE_ALLandBLOG_WRITEto the permission list) are exactly the kind of accuracy improvements this migration should deliver.FormDatacast comment// cast needed — FormData returns FormDataEntryValuewas correctly preserved in the frontend/CLAUDE.md Form Actions example.Review: Nora Steiner (Security)
Verdict: Approved (with one concern)
Security-relevant sections audit
The PR description explicitly tables the security migrations. Here is my verification of each:
@RequirePermission+ Permission enumBoth
backend/CLAUDE.mdand rootCLAUDE.mdhave the LLM reminder: "@RequirePermission(Permission.WRITE_ALL)is required on everyPOST,PUT,PATCH,DELETEendpoint — not optional. Do not mix with Spring Security's@PreAuthorize."The Permission enum in
Permission.javahas 8 values:READ_ALL,WRITE_ALL,ANNOTATE_ALL,BLOG_WRITE,ADMIN,ADMIN_USER,ADMIN_TAG,ADMIN_PERMISSION. The reminder lists all 8. The old backend/CLAUDE.md was missingANNOTATE_ALLandBLOG_WRITE— both are now correctly added. ✓ALLOWED_PDF_HOSTSSSRF warningocr-service/CLAUDE.mdretains this as an LLM reminder: "ALLOWED_PDF_HOSTSmust never be set to*— that opens SSRF." The warning is present and accurate. ✓TRAINING_TOKENThe PR description classifies TRAINING_TOKEN as Bucket 1 (migrated to
ocr-service/README.mdfrom DOC-6 anddocs/DEPLOYMENT.mdfrom DOC-5) with no LLM reminder retained. This is the right call: TRAINING_TOKEN is an operational deployment detail, not a code generation guardrail. An LLM working on the codebase doesn't need to know to set it — that's DevOps. ✓ErrorCode mirror process
The reminder in both root and backend CLAUDE.md reads: "when adding a new
ErrorCode: (1) add toErrorCode.java, (2) mirror infrontend/src/lib/shared/errors.ts, (3) add i18n keys inmessages/{de,en,es}.json." The frontend variant is identical. ✓vscodeuser runs as non-root (.devcontainer)This was in the original
.devcontainer/CLAUDE.mdas a factual statement under Configuration. It is faithfully carried into.devcontainer/README.md. ✓Concern: SSRF reminder has no LLM reminder label
The
ocr-service/CLAUDE.mdhas two separate blocks:The second block is a security-critical instruction but does NOT carry the
**LLM reminder:**prefix that every other LLM instruction in this PR uses. This is a formatting inconsistency: if a human reads the file and applies the convention that "LLM reminder = machine-readable", the SSRF warning appears ambiguous. Recommend prefixing it:Not a blocker for merge since the content is present, but the labeling inconsistency should be fixed.
What's done well
ANNOTATE_ALL,BLOG_WRITE) were caught and added — a genuine security accuracy improvement.@PreAuthorize" warning is retained — that's a real footgun that the reminder correctly calls out.Review: Sara Holt (QA)
Verdict: Changes requested
Per-file migration table verification
Checked each row against the actual diff:
scripts/CLAUDE.mdscripts/README.md.devcontainer/CLAUDE.md.devcontainer/README.mddocs/CLAUDE.mddocs/README.md; ADR-before-architecture reminder keptocr-service/CLAUDE.mdocr-service/README.md(DOC-6); single-node + SSRF reminder keptbackend/CLAUDE.mdroot CLAUDE.mdfrontend/CLAUDE.mdTable matches the actual diff. No mismatches.
Destructive-operation warning on
reset-db.shThe warning is present and is actually stronger in the new
scripts/README.mdthan in the original:Original:
> ⚠️ **Destructive operation** — only for development!New:
> ⚠️ **Destructive operation — only for development!** This wipes ALL data. Not reversible without a backup.The emphasis is retained and the consequence ("Not reversible without a backup") has been added. ✓
Blocker:
docs/README.mdfolder tree is incorrectThe folder tree in
docs/README.mdcontains a duplicateinfrastructure/entry:The second
infrastructure/at the└──position is incorrect — the tree terminates with a directory that was already listed. The originaldocs/CLAUDE.mdhadinfrastructure/listed only once. This appears to be a rewrite artifact where the description "Production compose, CI config, S3 migration" (which belongs to theInfrastructure (infrastructure/)section below) was accidentally promoted into the tree.Additionally, real files and folders that exist on disk are absent from the tree:
TODO-backend.md,TODO-frontend.md,mail.md,audits/,presentation/. The old CLAUDE.md explicitly listed the TODO files. Their omission from the README means a human readingdocs/README.mdwould not know they exist. Minor but worth noting.Test plan checklist
Going through the PR's own test plan:
scripts/README.md,.devcontainer/README.md,docs/README.mdcreated — confirmed (10 changed files)What's done well
reset-db.shgoes beyond the original spec — good catch.Review: Tobias Wendt (DevOps)
Verdict: Approved
scripts/README.md— completeness and accuracyVerified against the original
scripts/CLAUDE.md:reset-db.sh,rebuild-frontend.sh,download-kraken-models.sh,download-paperless.sh,flatten-paperless.sh,generate_data.py,prepare_historical_dict.py,schema.sql,large-data.sql. ✓chmod +xreminder,cd scripts && python generate_data.pyfor the Python script. ✓README.mdinstead ofCLAUDE.md. ✓large-data.sqlDocker import command (docker exec -i archive-db psql -U archive_user -d family_archive_db < scripts/large-data.sql) is present and correct. ✓schema.sql"source of truth" caveat (Flyway migrations are canonical, schema.sql is snapshot only) is preserved. ✓No operational detail was lost.
.devcontainer/README.md— completeness and accuracyVerified against original
.devcontainer/CLAUDE.md:Content is 1:1 with the original, reformatted with proper Markdown table alignment.
docs/README.md— completeness and accuracyContent is substantially correct. The ADR table, ADR format guide, architecture diagram descriptions, infrastructure table, specs section, and style guide link are all present.
One operational issue: the folder tree has a duplicate
infrastructure/entry (last line of the tree). The tree ends with:This is wrong —
infrastructure/is already listed at line 11. The tree's last entry should likely be absent (the tree should end atSTYLEGUIDE.md). A human following this README to understand thedocs/directory structure will be confused by seeing the same directory listed twice. Fix required before merge.Also notable: the tree omits
TODO-backend.mdandTODO-frontend.mdwhich exist on disk and serve as lightweight backlogs. The original CLAUDE.md called these out. If they're intentionally omitted (de-emphasising the TODO files in favour of Gitea issues), that's a valid choice — but it should be deliberate, not accidental.No operational detail lost in migration
The only content that didn't make it into any human doc is the "Model Downloads" section from
ocr-service/CLAUDE.mdthat calls./scripts/download-kraken-models.sh. That instruction is now inscripts/README.mdunder thedownload-kraken-models.shentry. ✓The dev profile behavior (
--spring.profiles.active=devenables OpenAPI) was in the oldbackend/CLAUDE.mdunder a "Profiles" sub-section. The new version compresses it into the OpenAPI generation block ("Start backend with--spring.profiles.active=dev"). All essential operational detail is preserved, just more compact.What's done well
scripts/README.mdis genuinely better than the original CLAUDE.md: cleaner heading hierarchy, proper spacing between sections, and the destructive warning is stronger..devcontainer/README.mdis a faithful and well-formatted copy — zero information loss.CLAUDE.md→README.mdpattern means these files are now discoverable by any developer opening the directory in a file browser or on Gitea, not just by Claude.Blocker fixes (commit
e6854e0e)infrastructure/line at end of folder treedocs/README.mdinfrastructure/appeared twice in the tree**LLM reminder:**prefix toALLOWED_PDF_HOSTSwarningocr-service/CLAUDE.mdResponseStatusExceptionnote for simple controller validationbackend/CLAUDE.mdDomainException👨💻 Felix Brandt — Senior Fullstack Developer
Verdict: ✅ Approved
This PR is purely a documentation migration — no production code is touched. My review focuses on whether the LLM-facing instructions in the CLAUDE.md files are correct, precise, and won't cause me to generate bad code.
What I checked
Findings
backend/CLAUDE.md— Error handling note (restored fix confirmed)The restored
ResponseStatusExceptionnote reads:This is correctly scoped. The caveat "not domain logic" is the critical distinction. Good.
backend/CLAUDE.md— Permission list is now completeANNOTATE_ALLandBLOG_WRITEare present. Previously missing — confirmed fixed.frontend/CLAUDE.md— API client reminder is accurateCorrect and consistent with
CONTRIBUTING.mdtarget. The added note about multipart/form-data bypassing the typed client is a useful addition that wasn't in the root CLAUDE.md version.scripts/README.md— destructive warning preservedThe
reset-db.shsection has:Consistent with Tobias's feedback requirement.
Minor observation (not a blocker):
docs/README.mdlistsSTYLEGUIDE.mdin the folder structure but does not listCONTRIBUTING.md. SinceCONTRIBUTING.mdlives at repo root (not indocs/), this is architecturally correct. No action needed.frontend/CLAUDE.md— Route structure mentionsbriefwechsel/notconversations/This is actually more accurate than the root CLAUDE.md (which still says
conversations/). The frontend file correctly reflects the actual route. The root CLAUDE.md Route Structure section is tagged as<!-- TODO: rewrite post-REFACTOR-1 -->which is the right call.Verdict
All LLM-facing reminders are accurate, the code style instructions are consistent, and the pointer links point to the correct targets (dependent on DOC-2/4/5/6 merging first as documented). The merge order constraint in the PR description is the critical operational note here — this PR must not merge out of order.
No blockers. The migration is executed cleanly.
🏛️ Markus Keller — Senior Application Architect
Verdict: ✅ Approved
A documentation-only PR. My concern is: does the new structure accurately reflect module ownership, does the pointer system hold up architecturally, and are the TODO tags on stale content appropriately scoped?
Layering rules — correctly preserved as LLM reminders
Both root
CLAUDE.mdandbackend/CLAUDE.mdkeep the layering LLM reminder:This is exactly right to keep as an LLM reminder (Bucket-2). It's the most common cross-domain boundary violation I see in generated code. Pointer to
docs/ARCHITECTURE.md §Layering ruleis correct.Package Structure tagged as TODO — good call
The package structure in both root and backend CLAUDE.md is tagged
<!-- TODO: rewrite post-REFACTOR-1 — see Epic 4 -->. This is the right decision: the structure is likely to change during Epic 4, and keeping it in CLAUDE.md while it drifts would cause more harm than good. The TODO tag communicates intent without deleting potentially-still-useful context.docs/README.md — structure is accurate
The folder structure in
docs/README.mdcorrectly listsadr/,architecture/,infrastructure/,specs/sub-folders plus the key documents. The ADR guide correctly states "Do not reuse numbers" and references the sequential naming convention.One observation:
docs/README.mdreferencesdocs/STYLEGUIDE.mdanddocs/GLOSSARY.md (DOC-3). The DOC-3 dependency isn't called out in the PR's merge order constraint (only DOC-2/4/5/6 are listed). IfGLOSSARY.mddoesn't exist onmainat merge time, the link will be a dead link. This is a minor concern since it's in the human-readabledocs/README.md, not in LLM-facing instructions, and is self-correcting once DOC-3 merges.Suggestion (not a blocker): Add DOC-3 (#443 or whichever is the GLOSSARY PR) to the merge order constraint in the PR description for completeness.
OCR service — single-node constraint preserved correctly
ocr-service/CLAUDE.mdkeeps:This architectural constraint is precisely the kind of thing that gets lost when someone "helpfully" removes CLAUDE.md content. Keeping it as an LLM reminder is the right call.
No blockers. Approved.
🔒 Nora "NullX" Steiner — Application Security Engineer
Verdict: ✅ Approved
This is a documentation migration, not a code change. My review focuses on whether security-critical LLM instructions were correctly classified (Bucket-1 vs Bucket-2) and whether the SSRF/permission reminders are present, accurate, and prominently placed.
Security-critical content audit
1. SSRF protection —
ocr-service/CLAUDE.mdThis is correctly preserved as a Bucket-2 LLM reminder. The
*wildcard risk is exactly the kind of thing that gets silently introduced when an LLM "simplifies" environment configuration. The reminder is present, accurate, and has theLLM reminder:prefix — confirmed fixed from the previous blocker.2.
@RequirePermission— both CLAUDE.md filesRoot
CLAUDE.mdandbackend/CLAUDE.mdboth retain:This is the most security-relevant LLM instruction in the codebase. Correctly classified as Bucket-2. Presence in both the root and backend CLAUDE.md is appropriate — redundancy here is a feature, not a smell.
3. Permission enum completeness
ANNOTATE_ALLandBLOG_WRITEare now present in both CLAUDE.md permission lists. This was flagged as a previous blocker and is confirmed fixed. An LLM generating a new endpoint for blog/annotation features will now know to use the correct permission constant.4.
ResponseStatusExceptioncarve-outbackend/CLAUDE.mdcorrectly notes:This is appropriately scoped. The security risk of using
ResponseStatusExceptionfor auth/domain errors (losing structured error codes that the frontend maps to i18n) is mitigated by the explicit "(not domain logic)" qualifier.5. ErrorCode mirror process — both CLAUDE.md files
Root and backend CLAUDE.md keep the full ErrorCode addition workflow including the correct path
frontend/src/lib/shared/errors.ts. The stale path fix (src/lib/errors.ts→frontend/src/lib/shared/errors.ts) is confirmed applied.One observation (not a blocker)
backend/CLAUDE.mdpoints todocs/ARCHITECTURE.md §Permission systemfor the full security documentation. This file is being created in DOC-2 (PR #441). Until that PR merges, the link is dead. This is correctly called out in the merge order constraint and is acceptable.No security regressions. Approved.
🧪 Sara Holt — Senior QA Engineer
Verdict: ✅ Approved
Documentation-only PR. My review covers: does the migration preserve testability-related LLM instructions, are the test-relevant sections correctly classified, and does the PR description give enough information to verify the migration is complete?
Test plan in the PR description
The test plan is a manual checklist:
This is fit for purpose for a documentation PR. There's no automated test coverage for CLAUDE.md content (by nature), and a manual checklist is the appropriate verification method here.
Testing-related content — correctly classified
backend/CLAUDE.md— Testing section preserved (Bucket-2)The testing section in
backend/CLAUDE.mdis kept:@WebMvcTest,@DataJpaTestwith Testcontainers PostgreSQLThis is correctly Bucket-2 (LLM code generation reference). The Testcontainers PostgreSQL requirement and the coverage gate threshold are the kind of facts an LLM needs when generating a new test class.
frontend/CLAUDE.md— Testing section preserved (Bucket-2)The frontend CLAUDE.md retains the testing stack (Vitest, browser mode, Playwright e2e) and the
npm run test:e2ecommands. Correct.One observation (not a blocker)
The
scripts/README.mddocumentsgenerate_data.pyas generating "fake documents, persons, and tags suitable for load testing or UI development." This is useful for QA purposes — I'd eventually want to see this script integrated into a test fixture workflow. But that's a future issue, not a concern for this PR.The migration is verifiable and complete from a QA perspective. Approved.
🚀 Tobias Wendt — DevOps & Platform Engineer
Verdict: ✅ Approved
Documentation-only change. I'm checking: are the infrastructure-relevant LLM instructions preserved, is the devcontainer README accurate, and does the scripts README correctly document the operational scripts?
.devcontainer/README.md— accurate and completeThe devcontainer README is a clean migration of the original content. Key details confirmed correct:
forwardPorts— correctly documentedvscodeuser (not root) — security note preservedThe
Customizationsection showing how to add Python 3.11 feature is a useful practical addition that wasn't in the original CLAUDE.md.scripts/README.md— operationally completeAll 9 scripts documented with purpose, usage, and notes:
reset-db.sh— destructive warning with proper visual emphasis (⚠️blockquote)download-kraken-models.sh— model size noted (~100–500 MB each)large-data.sql— correct docker exec import command documentedOne detail I appreciate: the
schema.sqlentry correctly notes "Flyway migrations inbackend/src/main/resources/db/migration/are the source of truth for schema evolution.schema.sqlis a snapshot for quick reference only." This prevents the common mistake of editingschema.sqlinstead of creating a Flyway migration.Infrastructure pointer in root
CLAUDE.mdRoot CLAUDE.md now reads:
The DEPLOYMENT.md file is created in DOC-5 (PR #443). The merge order constraint handles this. Once all dependencies merge, this pointer will resolve correctly.
OCR single-node constraint — infrastructure perspective
The
ocr-service/CLAUDE.mdreminder about single-node deployment matches the production Compose configuration. Good. An LLM that reads this will not suggest adding replicas or configuring horizontal scaling for the OCR service.No DevOps concerns. Approved.
🎨 Leonie Voss — Senior UX Designer & Accessibility Strategist
Verdict: ✅ Approved
This PR touches documentation only. I'm checking whether the UI/UX and brand conventions in CLAUDE.md files were migrated correctly and whether the LLM reminders for styling are accurate and sufficiently specific.
Styling conventions — correctly preserved in both root and frontend CLAUDE.md
Both
CLAUDE.md(root) andfrontend/CLAUDE.mdretain the brand color table and typography conventions:brand-navy#002850brand-mint#A6DAD8brand-sand#E4E2D7Typography:
font-serif(Merriweather) for body/titles,font-sans(Montserrat) for UI chrome.The card pattern and Back Button pattern are correctly preserved in root
CLAUDE.md. These are Bucket-2 — the right call. An LLM generating a new page without these reminders would create cards that don't match the established visual language.frontend/CLAUDE.md — Styling section retained
The frontend CLAUDE.md keeps:
Good. The card pattern markup example is especially important — without it, LLMs tend to invent their own padding/shadow combinations that break visual consistency.
docs/README.md mentions
STYLEGUIDE.mdThe
docs/README.mdreferencesdocs/STYLEGUIDE.mdcovering "Color palette and typography" and "Accessibility standards (WCAG 2.1 AA)". This is a human-readable doc reference, not an LLM reminder. It's appropriate to reference it here. I'd expect the actual content to be comprehensive when that file is written.One forward-looking note (suggestion, not a blocker)
The root
CLAUDE.mdRoute Structure is tagged<!-- TODO: rewrite post-REFACTOR-1 -->. The current structure already has some inaccuracies (conversations/vs the actualbriefwechsel/route in the frontend). Thefrontend/CLAUDE.mdcorrectly usesbriefwechsel/. This divergence is acceptable given the TODO tag, but whoever addresses REFACTOR-1 should usefrontend/CLAUDE.md's structure as the source of truth for the actual routes.Brand and UX instructions correctly migrated. Approved.
📋 Elicit — Requirements Engineer
Verdict: ✅ Approved
I'm reviewing this from a requirements and traceability perspective: does the migration preserve the information needed to generate correct code, are the TODO-tagged sections clearly scoped, and does the pointer system create the right expectation for how documentation should be maintained going forward?
Scope of issue #401 — migration is complete
The PR description maps each of the 7 CLAUDE.md files to their migration outcome with a clear table. Cross-referencing against the current file state:
scripts/CLAUDE.md→ pointer-only + reminder ✓.devcontainer/CLAUDE.md→ pointer-only ✓docs/CLAUDE.md→ pointer + ADR reminder ✓ocr-service/CLAUDE.md→ pointer + 2 reminders ✓backend/CLAUDE.md→ mixed (substantial Bucket-2 content retained) ✓CLAUDE.md→ mixed (substantial Bucket-2 content retained) ✓frontend/CLAUDE.md→ mixed (substantial Bucket-2 content retained) ✓Scope is fully delivered.
TODO tags — acceptably scoped
The
<!-- TODO: rewrite post-REFACTOR-1 — see Epic 4 -->tags on Package Structure sections are clear:One gap: the TODO doesn't reference a specific Gitea issue number. "Epic 4" is human-readable but not machine-traceable. If someone later searches for issues linked to these TODOs, they won't find them. Suggestion (not a blocker): add
see #<issue_number>alongside "Epic 4" in the TODO tags when that epic issue exists.Pointer standardization — consistent
The pointer format
→ See [Target §Section](path#anchor)is used consistently across all files. This is good for maintainability — when a target section is renamed, the broken link is immediately visible.Dual-audience split is well-executed
The PR correctly identifies which content serves LLMs (kept as reminder) vs humans (moved to human docs with pointer). The classification table in the PR description is the clearest requirements artifact in this PR — it makes the decision rationale explicit and verifiable.
Merge order constraint — well-documented
The constraint "this PR must merge AFTER DOC-2 (#441), DOC-4 (#442), DOC-5 (#443), DOC-6 (#444)" is clearly stated. This is the only procedural risk in the PR, and it's well-documented.
Suggestion (not a blocker): Consider whether DOC-3 (GLOSSARY) also needs to be in the merge order constraint, as
docs/README.mdreferencesGLOSSARY.md.Requirements fully met. Approved.