epic(legibility): audit — assess current state of every subsystem #387

Closed
opened 2026-05-04 16:01:17 +02:00 by marcel · 1 comment
Owner

Epic context

This is Epic 1 of 5 for the Codebase Legibility Refactor. The refactor prepares the codebase for evaluation by two external developers (one Java backend dev "Anja", one PM-with-CS "Tobias") to determine whether it is humanly maintainable rather than an LLM-only artifact. It also reduces bus-factor for any future maintainer.

This epic produces comparable, structured audit reports for every subsystem so we know exactly what state we're starting from. Nothing in the codebase changes during this epic — outputs are read-only Markdown reports under docs/audits/.

Scope

One audit per subsystem, each following the per-subsystem orient template (TEMPLATE-ORIENT-001):

  • AUDIT-1: frontend/
  • AUDIT-2: backend/ (Java + Flyway tooling)
  • AUDIT-3: ocr-service/ (Python)
  • AUDIT-4: Flyway migrations + DB schema
  • AUDIT-5: infra/ + scripts/ + repo root + docs/ (rest-of-repo)

Plus one rollup:

  • AUDIT-6: Roll up the five subsystem reports into a global readiness scorecard (docs/LEGIBILITY-READINESS.md)

Inputs every child issue depends on

These artifacts were produced in the requirements phase and are the audit's source of truth. They live in this issue's first comment so child issues can link to them.

  1. Project Brief (PROJ-LEGIBILITY-001) — vision, measurable goals, non-goals
  2. Personas — Anja (Backend Dev), Tobias (PM-with-CS), Successor-X (hypothetical)
  3. Legibility Rubric (RUBRIC-LEGIBILITY-001) — 10 categories C1–C10, ~50 checks
  4. Canonical Domain Set — agreed target domains, stack-symmetric across backend and frontend
  5. Boundary decisions D-OQ-1..8 (backend) and D-FE-1..4 (frontend)

I will paste the full text of these inputs into the first comment of this epic immediately after creation, so audit agents have one URL to read.

Acceptance criteria

  • All 6 child issues are closed
  • docs/audits/audit-frontend-report.md exists and follows the orient template (AUDIT-1)
  • docs/audits/audit-backend-report.md exists and follows the orient template (AUDIT-2)
  • docs/audits/audit-ocr-report.md exists and follows the orient template (AUDIT-3)
  • docs/audits/audit-db-report.md exists and follows the orient template (AUDIT-4)
  • docs/audits/audit-rest-report.md exists and follows the orient template (AUDIT-5)
  • docs/LEGIBILITY-READINESS.md exists with per-subsystem 🟢/🟡/🔴 verdicts (AUDIT-6)
  • Every Critical and Major finding across all reports has at least one corresponding follow-up issue or is explicitly closed in CLEANUP epic

Dependency

Blocks: Epic 4 (Refactor) — restructure cannot start until the audit identifies what's where.

Does NOT block: Epic 2 (Documentation) — docs can be written in parallel against the target structure, not the current one.

Definition of Done

This epic closes when AUDIT-6 (rollup scorecard) is closed AND every Critical finding has a corresponding action item somewhere in the legibility milestone.

## Epic context This is **Epic 1 of 5** for the *Codebase Legibility Refactor*. The refactor prepares the codebase for evaluation by two external developers (one Java backend dev "Anja", one PM-with-CS "Tobias") to determine whether it is humanly maintainable rather than an LLM-only artifact. It also reduces bus-factor for any future maintainer. This epic produces **comparable, structured audit reports** for every subsystem so we know exactly what state we're starting from. **Nothing in the codebase changes during this epic** — outputs are read-only Markdown reports under `docs/audits/`. ## Scope One audit per subsystem, each following the **per-subsystem orient template** (`TEMPLATE-ORIENT-001`): - AUDIT-1: `frontend/` - AUDIT-2: `backend/` (Java + Flyway tooling) - AUDIT-3: `ocr-service/` (Python) - AUDIT-4: Flyway migrations + DB schema - AUDIT-5: `infra/` + `scripts/` + repo root + `docs/` (rest-of-repo) Plus one rollup: - AUDIT-6: Roll up the five subsystem reports into a global readiness scorecard (`docs/LEGIBILITY-READINESS.md`) ## Inputs every child issue depends on These artifacts were produced in the requirements phase and are the audit's source of truth. They live in this issue's first comment so child issues can link to them. 1. **Project Brief** (`PROJ-LEGIBILITY-001`) — vision, measurable goals, non-goals 2. **Personas** — Anja (Backend Dev), Tobias (PM-with-CS), Successor-X (hypothetical) 3. **Legibility Rubric** (`RUBRIC-LEGIBILITY-001`) — 10 categories C1–C10, ~50 checks 4. **Canonical Domain Set** — agreed target domains, stack-symmetric across backend and frontend 5. **Boundary decisions** D-OQ-1..8 (backend) and D-FE-1..4 (frontend) I will paste the full text of these inputs into the first comment of this epic immediately after creation, so audit agents have one URL to read. ## Acceptance criteria - [ ] All 6 child issues are closed - [ ] `docs/audits/audit-frontend-report.md` exists and follows the orient template (AUDIT-1) - [ ] `docs/audits/audit-backend-report.md` exists and follows the orient template (AUDIT-2) - [ ] `docs/audits/audit-ocr-report.md` exists and follows the orient template (AUDIT-3) - [ ] `docs/audits/audit-db-report.md` exists and follows the orient template (AUDIT-4) - [ ] `docs/audits/audit-rest-report.md` exists and follows the orient template (AUDIT-5) - [ ] `docs/LEGIBILITY-READINESS.md` exists with per-subsystem 🟢/🟡/🔴 verdicts (AUDIT-6) - [ ] Every Critical and Major finding across all reports has at least one corresponding follow-up issue or is explicitly closed in CLEANUP epic ## Dependency Blocks: **Epic 4 (Refactor)** — restructure cannot start until the audit identifies what's where. Does NOT block: **Epic 2 (Documentation)** — docs can be written in parallel against the *target* structure, not the current one. ## Definition of Done This epic closes when AUDIT-6 (rollup scorecard) is closed AND every Critical finding has a corresponding action item somewhere in the legibility milestone.
marcel added this to the (deleted) milestone 2026-05-04 16:01:18 +02:00
Author
Owner

Reference inputs for all AUDIT-N child issues

This comment is the source-of-truth reference for every child audit. Audit agents should read this comment before opening their assigned child issue. It contains the full Legibility Rubric and the full Per-Subsystem Orient Template.


1. Project Brief (compact)

Vision. A stranger with a CS background can understand, navigate, and safely extend the Familienarchiv codebase without the original author available.

Measurable target outcomes:

  • O1. A first-time reader can sketch the system's domains and high-level data flow within ≤30 min of opening the repo.
  • O2. A first-time reader can correctly answer ≥8 of 10 "find or place" questions about the codebase with no help.
  • O3. A first-time reader can run the full stack locally from README.md instructions in ≤15 min with no questions asked.
  • O4. Zero TODOs of the form "ask Marcel" or "this is non-obvious" remain in the code or docs after refactor.

Non-goals. Rewriting working code, adopting new frameworks, changing user-facing behavior, pursuing 100% test coverage, adding features.


2. Personas

  • Anja, Backend Dev. CS bachelor, mostly Java backend. Backend comfort 5, frontend 2. Will scan package structure first, then trace one entity from controller → service → repo → DB. Success: closes IDE without saying "this is weird" once.
  • Tobias, PM-with-CS. CS bachelor, now PM, codes for fun. Architecture-thinking 4. Will read root README first, then look for docs/ARCHITECTURE.md and a domain glossary. Success: can describe the system back accurately in 3 minutes after only reading docs.
  • Successor-X, Future Maintainer. Generic competent web dev. Joins cold without the original author. Success: clones → follows README → ships first PR within a day.

3. Canonical Domain Set (stack-symmetric across backend and frontend)

Tier 1 — Genuine bounded contexts (own entities + behavior):
document, person, tag, user, geschichte, notification, ocr

Tier 2 — Derived / read-only domains:
conversation (view layer over Document sender/receiver), activity (view layer over Audit + Notification + Document events)

Cross-cutting (shared/ or common/):
audit, file-storage, import, dashboard, transcription-queue, security, error-handling, config, i18n, plus frontend-only discussion (comment+mention primitives)

Sub-packages:

  • document.transcription, document.annotation, document.comment
  • person.relationship

Boundary decisions ratified:

  • D-OQ-2: Transcription is part of document (sub-package)
  • D-OQ-3: Comment is part of document (sub-package); editor primitives in frontend shared/discussion/
  • D-OQ-4: Annotation is part of document (sub-package)
  • D-OQ-5: OCR is its own domain (ocr/)
  • D-OQ-6: Notification is its own domain (notification/)
  • D-OQ-7: Relationship is part of person (sub-package)
  • D-OQ-8: Audit, MassImport, Dashboard, FileService all stay in shared/
  • D-FE-1: PersonTypeahead/MultiSelect → person/ (cross-domain consumption is normal)
  • D-FE-2: TagInput/TagChipList → tag/
  • D-FE-3: Comment/Mention editors → shared/discussion/
  • D-FE-4: Dashboard widgets → shared/dashboard/

shared/ admission criteria: an item enters shared/ only if it (a) has no entity, (b) has no user-facing CRUD, and (c) is consumed by ≥2 domains or is genuinely framework infrastructure.


4. Legibility Rubric (RUBRIC-LEGIBILITY-001)

Each rubric item is one legibility check. PASS only if the measurable threshold is met. Anything else is FAIL with severity (Critical / Major / Minor / Cosmetic).

C1 — First Contact

ID Check Threshold Severity if fail
C1.1 Root README.md exists, is human-targeted, explains product purpose in ≤3 sentences Stranger describes purpose after first paragraph Critical
C1.2 README lists 5 components (frontend, backend, OCR, DB, infra) with one-line descriptions All 5 named Major
C1.3 docs/ARCHITECTURE.md contains a high-level diagram of components + data flow Tobias can reproduce the diagram Major
C1.4 README links to: how to run locally, how to contribute, where issues live All 3 links present and correct Major
C1.5 Repo root is free of stray scratch files / undocumented .agent/, .old/ folders No unexplained top-level items Minor

C2 — Local Bootstrap

ID Check Threshold Severity if fail
C2.1 Single command (or short numbered sequence) brings the full stack up Stranger reaches working app in ≤15 min Critical
C2.2 Required prerequisites (Java 21, Node 24, Docker, etc.) are listed with versions All prerequisites named with versions Major
C2.3 Default credentials for local dev are documented First-login works without grepping code Major
C2.4 Common failure modes documented with fixes ≥3 known issues with fixes, or "no known issues" verified Minor
C2.5 Per-subsystem README exists for any independently-runnable subsystem One README per runnable subsystem Major

C3 — Domain Clarity

ID Check Threshold Severity if fail
C3.1 Business domains are explicitly stated in documentation Tobias can name all domains from docs alone Critical
C3.2 Each domain has a one-paragraph definition (owns / does NOT own) Per-domain definitions exist Major
C3.3 Glossary disambiguates overloaded terms (Person ≠ AppUser, etc.) Critical distinctions explicit Critical
C3.4 Backend package structure is domain-based (per-domain controller+service+repo+entity+dto co-located) Stranger opens document/ and finds all Document code Critical
C3.5 Frontend lib/ is domain-based; names are stack-symmetric with backend Same domain set; matching names Critical
C3.6 shared/ (or common/) contains only genuinely cross-cutting code Each shared/ member has a clear cross-cutting justification Major

C4 — Findability

ID Check Threshold Severity if fail
C4.1 Given a domain name, stranger locates every file related to it in ≤2 min Walk-through test passes per domain Critical
C4.2 Given a user-visible feature, stranger locates controller + service + page + component in ≤5 min Walk-through test passes for 3 random features Major
C4.3 File names match the concept they implement (no Helper, Utils, Manager without modifier) Zero offending names, or each justified Minor
C4.4 API routes are predictable from the domain Mapping is mechanical, no surprises Major

C5 — Conventions

ID Check Threshold Severity if fail
C5.1 Conventions doc explains: how to add a new domain, endpoint, frontend page All 3 walkthroughs documented Major
C5.2 One way to do common things (errors, validation, DTO shape, API client) — not three ≤1 inconsistent pattern per category Major
C5.3 Existing CLAUDE.md "rules" sections are mirrored in human-readable docs Every CLAUDE.md rule has human-doc equivalent OR is moved Major
C5.4 Naming conventions for files/classes/components are stated and followed Convention exists; ≥95% of files follow it Minor

C6 — Layering & Boundaries

ID Check Threshold Severity if fail
C6.1 Backend: no controller injects a repository directly Zero violations (grep-able) Critical
C6.2 Backend: no service depends on another domain's repository Zero violations (grep-able) Critical
C6.3 Frontend: domain components don't import from sibling domain components Zero unjustified cross-domain imports Major
C6.4 Cross-cutting code (auth, errors, logging) is in shared/, not duplicated per domain No copy-paste of cross-cutting concerns Major

C7 — Documentation Quality

ID Check Threshold Severity if fail
C7.1 Each domain package has a short README.md (what it owns, what it does not) One README per domain Major
C7.2 Non-obvious decisions have inline why-comments (not what-comments) Zero surprising blocks lack a why-comment Major
C7.3 No comments of the form "this is non-obvious," "ask Marcel," "Claude generated this," "TODO: figure out" Zero matches via grep Major
C7.4 API contracts are documented (OpenAPI; type generation steps) OpenAPI accessible; regen instructions in frontend README Major
C7.5 Database schema has per-table comment OR a domain-grouped overview Stranger identifies what each table is for without running app Minor

C8 — Test Trustworthiness

ID Check Threshold Severity if fail
C8.1 Critical-path service tests would FAIL if the service were broken (mutation spot-check) 5 of 5 sampled tests detect their mutation Critical
C8.2 Frontend has at least one e2e flow per critical user journey All critical journeys covered Major
C8.3 Tests are readable: stranger predicts what each test verifies from its name ≥90% of test names are descriptive Minor
C8.4 Tests don't depend on prior test ordering Tests pass when run in random order Major

C9 — Operability

ID Check Threshold Severity if fail
C9.1 Stranger can identify what services run in production and how they're deployed Documented in docs/DEPLOYMENT.md Major
C9.2 Configuration knobs (env vars, profiles) are listed in one place per subsystem Per-subsystem env reference exists Major
C9.3 Database migrations follow a naming convention; non-trivial ones are explained Convention stated; non-trivial migrations have comment header Minor
C9.4 Logs and observability hooks are documented Document points to log locations Minor

C10 — Code Quality Sanity (AI-smell check)

ID Check Threshold Severity if fail
C10.1 No unused/dead code (orphan classes, never-imported modules, _old/.backup files) Sample audit ≤2 dead items per subsystem Major
C10.2 No premature abstractions (interfaces with one impl that no test substitutes; trivial wrappers) Sample audit ≤1 unjustified abstraction per domain Minor
C10.3 No magic numbers/strings without a constant or comment Egregious cases flagged Minor
C10.4 No half-finished features (commented-out blocks, if (false) branches, unreachable code) Zero matches Major
C10.5 No defensive null-checks or try/catch wrappers for impossible cases ≤1 unjustified case per domain Minor

Severity decision rules

  • Critical — blocks Anja or Tobias from forming a correct mental model OR blocks Successor-X from running the system locally OR introduces a security/data-loss risk
  • Major — significant friction; workaround exists but is non-obvious; would prompt a "why is this like this?" question
  • Minor — noticeable but doesn't block evaluation
  • Cosmetic — polish, low impact

5. Per-Subsystem Orient Template (TEMPLATE-ORIENT-001)

Every audit produces a Markdown report with these 10 sections in this order. Do not omit sections. If a section doesn't apply, write "N/A — reason".

§ Section Content
1 Subsystem profile One paragraph: what this subsystem is, what it owns, top-level structure as a tree (max 3 levels deep).
2 Inventory Tables of components (controllers/services/components/etc.) — only if relevant — with apparent domain assignment using the canonical set.
3 Rubric scorecard One row per applicable rubric check. Columns: Check ID · Result (PASS/FAIL) · Severity · Evidence (file:line) · Recommendation.
4 Subsystem health summary Aggregate table: PASS / FAIL-Critical / FAIL-Major / FAIL-Minor / FAIL-Cosmetic counts per category C1–C10, plus overall health 🟢/🟡/🔴.
5 Domain mapping gaps Items in this subsystem that don't map cleanly to the canonical domain set. Each: item, plausible homes, blocker question.
6 Cross-cutting candidates Items that should move to shared/. Justification per item against the admission criteria (no entity, no CRUD, ≥2 consumers, or framework infra).
7 Dead/suspicious code register C10 findings. One row per finding: file:line, smell type, suggested action.
8 Documentation gaps What's missing for this subsystem to pass C7: per-domain README, inline why-comments, API contracts.
9 Prerequisites for big-bang refactor What MUST be true before this subsystem is touched in REFACTOR-1/REFACTOR-2. Typical entries: "all tests in service X must be mutation-validated first."
10 Top 5 prioritized recommendations Five highest-leverage actions for this subsystem, in priority order. Each ≤2 sentences.

Health thresholds: 🟢 if 0 Critical AND ≥80% pass; 🟡 if 0 Critical AND ≥50% pass; 🔴 otherwise.

Output format: Markdown, no HTML, tables in pipe syntax, code references as path/file.ts:42.

Quality gate: the report is "good" when Anja or Tobias could read it cold and decide whether to take this subsystem AND every Critical/Major finding maps to at least one Recommendation in §10.


This is the complete reference. Each child audit issue points to this comment for inputs.

# Reference inputs for all AUDIT-N child issues This comment is the source-of-truth reference for every child audit. Audit agents should read this comment before opening their assigned child issue. It contains the full **Legibility Rubric** and the full **Per-Subsystem Orient Template**. --- ## 1. Project Brief (compact) **Vision.** A stranger with a CS background can understand, navigate, and safely extend the Familienarchiv codebase without the original author available. **Measurable target outcomes:** - **O1.** A first-time reader can sketch the system's domains and high-level data flow within ≤30 min of opening the repo. - **O2.** A first-time reader can correctly answer ≥8 of 10 "find or place" questions about the codebase with no help. - **O3.** A first-time reader can run the full stack locally from `README.md` instructions in ≤15 min with no questions asked. - **O4.** Zero TODOs of the form "ask Marcel" or "this is non-obvious" remain in the code or docs after refactor. **Non-goals.** Rewriting working code, adopting new frameworks, changing user-facing behavior, pursuing 100% test coverage, adding features. --- ## 2. Personas - **Anja, Backend Dev.** CS bachelor, mostly Java backend. Backend comfort 5, frontend 2. Will scan package structure first, then trace one entity from controller → service → repo → DB. Success: closes IDE without saying "this is weird" once. - **Tobias, PM-with-CS.** CS bachelor, now PM, codes for fun. Architecture-thinking 4. Will read root README first, then look for `docs/ARCHITECTURE.md` and a domain glossary. Success: can describe the system back accurately in 3 minutes after only reading docs. - **Successor-X, Future Maintainer.** Generic competent web dev. Joins cold without the original author. Success: clones → follows README → ships first PR within a day. --- ## 3. Canonical Domain Set (stack-symmetric across backend and frontend) **Tier 1 — Genuine bounded contexts (own entities + behavior):** `document`, `person`, `tag`, `user`, `geschichte`, `notification`, `ocr` **Tier 2 — Derived / read-only domains:** `conversation` (view layer over Document sender/receiver), `activity` (view layer over Audit + Notification + Document events) **Cross-cutting (`shared/` or `common/`):** `audit`, `file-storage`, `import`, `dashboard`, `transcription-queue`, `security`, `error-handling`, `config`, `i18n`, plus frontend-only `discussion` (comment+mention primitives) **Sub-packages:** - `document.transcription`, `document.annotation`, `document.comment` - `person.relationship` **Boundary decisions ratified:** - D-OQ-2: Transcription is part of `document` (sub-package) - D-OQ-3: Comment is part of `document` (sub-package); editor primitives in frontend `shared/discussion/` - D-OQ-4: Annotation is part of `document` (sub-package) - D-OQ-5: OCR is its own domain (`ocr/`) - D-OQ-6: Notification is its own domain (`notification/`) - D-OQ-7: Relationship is part of `person` (sub-package) - D-OQ-8: Audit, MassImport, Dashboard, FileService all stay in `shared/` - D-FE-1: PersonTypeahead/MultiSelect → `person/` (cross-domain consumption is normal) - D-FE-2: TagInput/TagChipList → `tag/` - D-FE-3: Comment/Mention editors → `shared/discussion/` - D-FE-4: Dashboard widgets → `shared/dashboard/` **`shared/` admission criteria:** an item enters `shared/` only if it (a) has no entity, (b) has no user-facing CRUD, and (c) is consumed by ≥2 domains *or* is genuinely framework infrastructure. --- ## 4. Legibility Rubric (`RUBRIC-LEGIBILITY-001`) Each rubric item is one **legibility check**. PASS only if the measurable threshold is met. Anything else is FAIL with severity (Critical / Major / Minor / Cosmetic). ### C1 — First Contact | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C1.1 | Root `README.md` exists, is human-targeted, explains product purpose in ≤3 sentences | Stranger describes purpose after first paragraph | Critical | | C1.2 | README lists 5 components (frontend, backend, OCR, DB, infra) with one-line descriptions | All 5 named | Major | | C1.3 | `docs/ARCHITECTURE.md` contains a high-level diagram of components + data flow | Tobias can reproduce the diagram | Major | | C1.4 | README links to: how to run locally, how to contribute, where issues live | All 3 links present and correct | Major | | C1.5 | Repo root is free of stray scratch files / undocumented `.agent/`, `.old/` folders | No unexplained top-level items | Minor | ### C2 — Local Bootstrap | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C2.1 | Single command (or short numbered sequence) brings the full stack up | Stranger reaches working app in ≤15 min | Critical | | C2.2 | Required prerequisites (Java 21, Node 24, Docker, etc.) are listed with versions | All prerequisites named with versions | Major | | C2.3 | Default credentials for local dev are documented | First-login works without grepping code | Major | | C2.4 | Common failure modes documented with fixes | ≥3 known issues with fixes, or "no known issues" verified | Minor | | C2.5 | Per-subsystem README exists for any independently-runnable subsystem | One README per runnable subsystem | Major | ### C3 — Domain Clarity | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C3.1 | Business domains are explicitly stated in documentation | Tobias can name all domains from docs alone | Critical | | C3.2 | Each domain has a one-paragraph definition (owns / does NOT own) | Per-domain definitions exist | Major | | C3.3 | Glossary disambiguates overloaded terms (Person ≠ AppUser, etc.) | Critical distinctions explicit | Critical | | C3.4 | Backend package structure is domain-based (per-domain controller+service+repo+entity+dto co-located) | Stranger opens `document/` and finds all Document code | Critical | | C3.5 | Frontend `lib/` is domain-based; names are stack-symmetric with backend | Same domain set; matching names | Critical | | C3.6 | `shared/` (or `common/`) contains only genuinely cross-cutting code | Each `shared/` member has a clear cross-cutting justification | Major | ### C4 — Findability | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C4.1 | Given a domain name, stranger locates every file related to it in ≤2 min | Walk-through test passes per domain | Critical | | C4.2 | Given a user-visible feature, stranger locates controller + service + page + component in ≤5 min | Walk-through test passes for 3 random features | Major | | C4.3 | File names match the concept they implement (no `Helper`, `Utils`, `Manager` without modifier) | Zero offending names, or each justified | Minor | | C4.4 | API routes are predictable from the domain | Mapping is mechanical, no surprises | Major | ### C5 — Conventions | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C5.1 | Conventions doc explains: how to add a new domain, endpoint, frontend page | All 3 walkthroughs documented | Major | | C5.2 | One way to do common things (errors, validation, DTO shape, API client) — not three | ≤1 inconsistent pattern per category | Major | | C5.3 | Existing CLAUDE.md "rules" sections are mirrored in human-readable docs | Every CLAUDE.md rule has human-doc equivalent OR is moved | Major | | C5.4 | Naming conventions for files/classes/components are stated and followed | Convention exists; ≥95% of files follow it | Minor | ### C6 — Layering & Boundaries | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C6.1 | Backend: no controller injects a repository directly | Zero violations (grep-able) | Critical | | C6.2 | Backend: no service depends on another domain's repository | Zero violations (grep-able) | Critical | | C6.3 | Frontend: domain components don't import from sibling domain components | Zero unjustified cross-domain imports | Major | | C6.4 | Cross-cutting code (auth, errors, logging) is in `shared/`, not duplicated per domain | No copy-paste of cross-cutting concerns | Major | ### C7 — Documentation Quality | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C7.1 | Each domain package has a short `README.md` (what it owns, what it does not) | One README per domain | Major | | C7.2 | Non-obvious decisions have inline why-comments (not what-comments) | Zero surprising blocks lack a why-comment | Major | | C7.3 | No comments of the form "this is non-obvious," "ask Marcel," "Claude generated this," "TODO: figure out" | Zero matches via grep | Major | | C7.4 | API contracts are documented (OpenAPI; type generation steps) | OpenAPI accessible; regen instructions in frontend README | Major | | C7.5 | Database schema has per-table comment OR a domain-grouped overview | Stranger identifies what each table is for without running app | Minor | ### C8 — Test Trustworthiness | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C8.1 | Critical-path service tests would FAIL if the service were broken (mutation spot-check) | 5 of 5 sampled tests detect their mutation | Critical | | C8.2 | Frontend has at least one e2e flow per critical user journey | All critical journeys covered | Major | | C8.3 | Tests are readable: stranger predicts what each test verifies from its name | ≥90% of test names are descriptive | Minor | | C8.4 | Tests don't depend on prior test ordering | Tests pass when run in random order | Major | ### C9 — Operability | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C9.1 | Stranger can identify what services run in production and how they're deployed | Documented in `docs/DEPLOYMENT.md` | Major | | C9.2 | Configuration knobs (env vars, profiles) are listed in one place per subsystem | Per-subsystem env reference exists | Major | | C9.3 | Database migrations follow a naming convention; non-trivial ones are explained | Convention stated; non-trivial migrations have comment header | Minor | | C9.4 | Logs and observability hooks are documented | Document points to log locations | Minor | ### C10 — Code Quality Sanity (AI-smell check) | ID | Check | Threshold | Severity if fail | |---|---|---|---| | C10.1 | No unused/dead code (orphan classes, never-imported modules, `_old`/`.backup` files) | Sample audit ≤2 dead items per subsystem | Major | | C10.2 | No premature abstractions (interfaces with one impl that no test substitutes; trivial wrappers) | Sample audit ≤1 unjustified abstraction per domain | Minor | | C10.3 | No magic numbers/strings without a constant or comment | Egregious cases flagged | Minor | | C10.4 | No half-finished features (commented-out blocks, `if (false)` branches, unreachable code) | Zero matches | Major | | C10.5 | No defensive null-checks or try/catch wrappers for impossible cases | ≤1 unjustified case per domain | Minor | ### Severity decision rules - **Critical** — blocks Anja or Tobias from forming a correct mental model OR blocks Successor-X from running the system locally OR introduces a security/data-loss risk - **Major** — significant friction; workaround exists but is non-obvious; would prompt a "why is this like this?" question - **Minor** — noticeable but doesn't block evaluation - **Cosmetic** — polish, low impact --- ## 5. Per-Subsystem Orient Template (`TEMPLATE-ORIENT-001`) Every audit produces a Markdown report with these 10 sections in this order. **Do not omit sections.** If a section doesn't apply, write "N/A — reason". | § | Section | Content | |---|---|---| | 1 | **Subsystem profile** | One paragraph: what this subsystem is, what it owns, top-level structure as a tree (max 3 levels deep). | | 2 | **Inventory** | Tables of components (controllers/services/components/etc.) — only if relevant — with apparent domain assignment using the canonical set. | | 3 | **Rubric scorecard** | One row per applicable rubric check. Columns: `Check ID · Result (PASS/FAIL) · Severity · Evidence (file:line) · Recommendation`. | | 4 | **Subsystem health summary** | Aggregate table: PASS / FAIL-Critical / FAIL-Major / FAIL-Minor / FAIL-Cosmetic counts per category C1–C10, plus overall health 🟢/🟡/🔴. | | 5 | **Domain mapping gaps** | Items in this subsystem that don't map cleanly to the canonical domain set. Each: item, plausible homes, blocker question. | | 6 | **Cross-cutting candidates** | Items that should move to `shared/`. Justification per item against the admission criteria (no entity, no CRUD, ≥2 consumers, or framework infra). | | 7 | **Dead/suspicious code register** | C10 findings. One row per finding: file:line, smell type, suggested action. | | 8 | **Documentation gaps** | What's missing for this subsystem to pass C7: per-domain README, inline why-comments, API contracts. | | 9 | **Prerequisites for big-bang refactor** | What MUST be true before this subsystem is touched in REFACTOR-1/REFACTOR-2. Typical entries: "all tests in service X must be mutation-validated first." | | 10 | **Top 5 prioritized recommendations** | Five highest-leverage actions for this subsystem, in priority order. Each ≤2 sentences. | **Health thresholds:** 🟢 if 0 Critical AND ≥80% pass; 🟡 if 0 Critical AND ≥50% pass; 🔴 otherwise. **Output format:** Markdown, no HTML, tables in pipe syntax, code references as `path/file.ts:42`. **Quality gate:** the report is "good" when Anja or Tobias could read it cold and decide whether to take this subsystem AND every Critical/Major finding maps to at least one Recommendation in §10. --- This is the complete reference. Each child audit issue points to this comment for inputs.
marcel added the auditepiclegibility labels 2026-05-04 16:05:32 +02:00
Sign in to join this conversation.
No Label audit epic legibility
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#387