The adversarial review of #1002 produced ~40 design findings that were deliberately deferred from the merge (the review itself rated them non-blocking). The correctness work is done; this tracks the structural cleanup as one campaign so it doesn't dissolve into drive-by refactors.
Categories (per-finding detail in the review artifact / PR threads):
- Over-abstraction (~16): single-implementation Protocol + Default dataclass + build_default factory towers (accepted-note repositories, read-repair capability lattice ~20 Protocols, note-content reconciler chain, ProjectDeleteRepositories, index-file metadata source tower). ~211 Protocol classes remain; the interim collapse waves removed ~15.
- Type honesty (~10):
object-typed protocol properties re-validated with isinstance/str() at consumers; residual cast(AcceptedNoteMutationChange, ...) sites; int | str | None project ids.
- Boundary validation (~6):
dict[str, object] HTTP payloads hand-serialized where Pydantic models exist (directory-delete response, project-delete acceptance, read-repair response).
- Control flow (3): six
repositories or build_default_...() hidden fallbacks in accepted_note_write_runner; move-eligibility rule duplicated between change_planning and the snapshot; 175-line apply_project_index_move_batch without section headers.
- Layering (2): repository→indexing and models→runtime upward imports; runtime/indexing/index three-way split with duplicated module basenames.
- Helper sprawl (2):
_session_scope re-implemented in five services with divergent semantics.
Several are interlocking (fixing the object-typed properties shrinks three others; collapsing the repository towers kills much of the Protocol count) — worth sequencing rather than parallelizing.
🤖 Generated with Claude Code
The adversarial review of #1002 produced ~40 design findings that were deliberately deferred from the merge (the review itself rated them non-blocking). The correctness work is done; this tracks the structural cleanup as one campaign so it doesn't dissolve into drive-by refactors.
Categories (per-finding detail in the review artifact / PR threads):
object-typed protocol properties re-validated with isinstance/str() at consumers; residualcast(AcceptedNoteMutationChange, ...)sites;int | str | Noneproject ids.dict[str, object]HTTP payloads hand-serialized where Pydantic models exist (directory-delete response, project-delete acceptance, read-repair response).repositories or build_default_...()hidden fallbacks in accepted_note_write_runner; move-eligibility rule duplicated between change_planning and the snapshot; 175-line apply_project_index_move_batch without section headers._session_scopere-implemented in five services with divergent semantics.Several are interlocking (fixing the object-typed properties shrinks three others; collapsing the repository towers kills much of the Protocol count) — worth sequencing rather than parallelizing.
🤖 Generated with Claude Code