Code simplification backlog
Goal. Cut lines and complexity from src/commonplace/, scripts/ and tests/ without changing behaviour, by working through the findings below. Posed by the operator on 2026-09-28, after a four-agent read-only review of the package.
Already done. Code with no callers, finished migrations, and code only tests reached were removed in 45d6afba, 765df352 and 4150e388 (about 1,950 lines). This backlog is what remains: duplicated code, test clean-up, and design-level changes.
Closes when every item below is committed or struck through with a one-line reason. The workshop produces commits, not library artifacts. The exception is a design-level item that changes module ownership: that one gets an ADR (or an amendment to the ADR that owns the boundary). Delete the directory when it closes.
Conventions
- Line numbers are as of 4150e388 and will drift. Find the code by the symbol names given.
- The estimates came from reviewers reading the code. Confirm each claim before acting on it. Strike an item that turns out wrong, and say why.
- One commit per item, or a small group of items in the same module.
uv run pytestanduv run ruff check .must pass before each commit. Each commit carries aWorkshop: kb/work/code-simplificationtrailer. - Behaviour stays the same, apart from the bug in item 1, which is fixed deliberately and gets a regression test. Error-message wording may change only when an item says so.
- Mark progress in this file. Strike through a finished item and add its commit hash.
Tier 4 — merge duplicated code
- Staleness check written three times (~110 lines). The shared helper is
freshness/selector.py_changed_inputs_for_baseline. Its UnicodeDecodeError/ValueError and OSError branches have identical bodies, and it buildsChangedInputfour times. Make it the single implementation: review/review_target_selector.pyselect_stale_criteriare-implements the hash comparison; have it call the helper.review/warn_selector.pydoes the same, around itsmissing-baselinehandling; have it call the helper too.- Deduplicate the diff code:
text_diff_from_textand the diff infreshness/status.py. - Deduplicate the JSON output:
_changed_input_payloadand_changed_input_to_json. - Use
dataclasses.replacein_attach_diffs. - Probable bug:
warn_selectorbuilds paths asrepo_root / artifact_path, so acommonplace:library criterion probably always reads as changed. The shared helper resolves paths throughresolve_file_text, which handles those. Write a failing test first. - Its
missing-baselinebranch cannot run: the pair map is built from the baseline view, so every key has a baseline. review/review_db.pyboilerplate (~70 lines).- Replace field-by-field row mapping (
_review_job_from_row, andFreshnessBaselineinload_current_freshness_baselines) withCls(**dict(row)). - Put the job column list, written out twice, into one
_JOB_SELECTconstant, like_PAIR_SELECT. - Drop
create_job's parameters no caller passes:completed_at,failure_reason,telemetry_json. - Fold
create_jobandcreate_review_pairsintocreate_job_with_pairs. - Have
ReviewJobPlanreuseReviewJobRowinstead of repeating its 11 fields. - Remove the
resolve_db_pathandensure_dbwrappers; callstoredirectly. - Replace
ReviewFileSnapshot, a renamedArtifactSnapshot, withArtifactSnapshot. - Inline
_review_pairs_from_rows. - Remove the
DEFAULT_DB_PATHandDB_ENV_VARaliases. - The ack path checks the same things up to three times (~50 lines).
acknowledgement.records_from_selector_payloadand_selected_inputsboth check unique roles and matching reasons.- The expected-revision (CAS) check runs in
ack_pairs, thentransitions.ack_target_inputs, thenbaselines.refresh_review_baseline_from_observation. - The evidence-pair query
SELECT evidence_review_pair_id FROM review_freshness_evidence WHERE target_idappears in three places. ack_target_inputsbuildsSupersededFreshnessBaselineby hand;review_db._superseded_baseline_for_targetalready does this.- Hex-hash validation is duplicated between
acknowledgement._content_hashandtransitions.parse_input_observation. review_target_selector.pyparallel helpers (~30 lines).- Merge
_normalize_type_requestswith_normalize_collection_requests, and_applicable_type_spec_pathwith_applicable_collection_md_path. _partition_criterion_requestsevaluates each predicate twice.- Merge the two
missing-baselineappends. _is_type_definition_contentduplicatesproject_paths.is_type_definition_content.- Six review commands repeat the same boilerplate (~30 lines). They repeat "strip
--model-partition, error if empty, normalize", and five places repeat "resolve db path +ensure_db".prepare_review_dbalready exists; use it everywhere. lib/relocation.py(~90 lines).relocate_noteandrelocate_directoryshare the link-rewrite loop and the dry-run/ProperDocs report printing.rewrite_links_to_moved_filesisrebase_and_rewrite_in_moved_filefor a file that did not move. Merge them, and keep theexists()fallback only for moved files.- "Resolve a path and require it under
kb/" is written three times. rewrite_source_notesand_declared_brief_noderepeat the same frontmatter lookup.- Inline the
resolve_noteandmove_pathwrappers. - Python re-checks what the schemas already enforce (~75 lines).
full_pass.parse_full_pass_reportre-checks enums and closing rules. Haveload_full_pass_reportvalidate against the schema first, asagentic_analysis.load_run_statedoes, then drop the duplicate checks.systems_matrix.validate_comparison: keep only what the schema cannot express (per-axis vocabularies, record resolution, cross-axis rules).full_pass.guard_inputbuildsGuardResultfive times; usedataclasses.replace.GuardResult.to_dictcan beasdict.cli/validate_notes.py(~85 lines).build_single_validation_reportrepeatsbuild_validation_report, which gives the same report for a single path.- The redirects and landings branches in
maindiffer only in the validator called and the subject path; make them one table-driven branch. - The three
diagnostics.extend(...)blocks become one loop. - Fold the
== kb → _TOO_BROAD_MESSAGEcheck (three copies) into_collection_target. lib/validation.pylocal cleanups (~50 lines).- In
ValidationRun.parse_note, write the cache once instead of in three places. - In
validate, assign the result once instead of in bothtryandexcept. inbound_infomaps each key to itself; useif target in inbound. It also repeats the target filtering in_linked_md_targets.- The split of schema errors by severity exists twice (
_validate_artifact,apply_schema_validation). - Drop the
isinstance(schema, dict)re-checks in_schema_error_message. - Compute the exemption wording in
validate_title_and_slugonce. - Use
snapshot.SNAPSHOT_DIRinstead of a hard-codedkb/sources/.snapshots. - Shared helpers copied between modules (~120 lines).
- "Text under one
##heading" has six copies:agentic_records.section,lifecycle_validation._section,quote_verification.ingest_quotes_section,full_pass.resolution_section, and others. Put one helper innote_parser. - "Show a path relative to the repo" has four copies (
_display_path×2,_display_snapshot_path,quote_verification.display_path). Put one inproject_paths. - Git subprocess calls:
agentic_publication._git,project_status._run_git, and inline calls inagentic_analysis. - Atomic write:
agentic_publication.atomic_writeandvalidate_notes.emit_json_report. _required_stringand_repo_relative_fileare copied betweenagentic_analysisandfull_pass.full_pass._capture_filere-implementsagentic_set.is_normalized_relative.agentic_records._analysis_prosehas its own fence tracker.TAG_README_TYPEis defined in bothvalidation.pyandindex_generated.py.x_snapshotandgithub_snapshotrepeat capture writing: dedup, reobserve slug, write, message.
- "Text under one
- Idiom sweeps (~60 lines).
try: relative_to / except ValueErrorused as a membership test becomesPath.is_relative_to. Sites:validation.py×3,type_resolver.py×2,project_paths.py,lifecycle_validation.py.- Absolute-path branches that repeat the repo-relative branch (
repo_root / "/abs"is/abs):validate_notes.pytarget resolution andproject_paths.resolve_note.resolve_notealso callslist_kb_note_pathstwice. note_parser: blanking fenced code gives the same matches as removing it, so drop theblank=Falsepath.
-
Wrappers with one caller (~40 lines). Inline:
canonical_type_identity,note_parser.strip_frontmatter,_quote_citation_rule;run_validation,prepare_publication,baselines.load_expected_baseline_revision;build_generated_section, andcollect_index_pages'sis_rootparameter (derive it from depth).
Also: -
refresh_review_baseline_from_capturesreturnssuperseded_target_id, which no caller uses. -finalization.ACTIVE_REVIEW_JOB_STATUSESis a one-element set. -revisions.allocate_initial_revisionre-runsload_generation_next_revision's query. -freshness/snapshots.pywrites the row→ArtifactSnapshotmapping twice. 13. Smaller items in the agentic modules (~60 lines). -verify_agentic_analysis_run_statenow always hasrun, so read throughrun.read_bytesand drop_text_override,_read_output_bytes,_read_output_text,_parsed_outputand thetry: run.read_bytes … except: passwarm-ups. -load_resultsandagentic_publication._check_incumbentduplicate the review→retained-set check; move one helper intoagentic_set. -_load_running_statere-parses a state thatload_run_statehas already parsed. - Nothing imports the re-exports insystems_matrix.__all__. -_check_setrebuildsretained_set_paths()inline. -init_project:_copy_scaffold_fileand_write_templateshare the same "exists → classify, else write" code.
Tier 5 — tests (~500 lines)
- Shared helpers.
write(path, content)has about 30 copies;tests/commonplace/validation_helpers.pyalready has one.make_note,make_gate,seed_freshness_baseline,db_path_forandbuild_fixtureare copied acrosstests/commonplace/review/andcli/relocation_review_helpers.py. Move them toreview/pair_helpers.pyor aconftest.py.- Byte-identical pairs:
write_type_spec,pair_block,target.
- Parametrize near-identical test pairs. Candidates:
freshness/test_integrity.py,test_quote_verification.py(two pairs),lib/test_agentic_analysis.py,review/test_review_outcome_parser.py,lib/test_type_resolver.py,lib/test_frontmatter.py,lib/test_snapshot.py.
Design-level — decide before starting
- Break the import cycle between
freshness/andreview_db.freshness/*importsFreshnessBaseline,SupersededFreshnessBaselineandload_current_freshness_baselinesfromreview_db, andreview_dbimports freshness, which forces deferred imports. Move baseline loading, upsert and prune intofreshness/baselines.py, leavingreview_dbto store jobs and pairs only. This needs an ADR or ADR amendment, because it changes which module owns baselines. - One result type for a stale review target.
StaleCriterionandStaleTargetdescribe the same thing, so each has its own renderer and the ack path has its own parser for selector output. Merging them absorbs the rest of items 1 and 3. Do this after item 1. - One implementation of snapshot lookup.
validation.SnapshotDirectory/SnapshotFactsoverlaplib/snapshot.py(dedup_existing_snapshot,snapshot_sha256, the http-source check). - Separate diagnostic types for lifecycle validation.
LifecycleDiagnosticandLifecycleValidationResultsrepeatValidationDiagnostic, and the CLI converts every item from one to the other. - Rows of checks in
project_status._actions. Its ~120 lines could become a table of (condition, id, severity, message, command) rows. - Three scripts over the systems matrix.
build_systems_matrix.py,render_systems_table.pyandanalyze_matrix.pyare thin wrappers oversystems_matrix.load_results; they could become one script with subcommands. They are live and are referenced fromkb/agentic-systems/comparisons/README.md. scripts/session-tools.py. Delete it only if nobody runs it by hand; ask the operator.