Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Architecture] Break up 1,200-line methods in analyzer: generate_sorting_plan and GenerativeNamingStrategy._get_cluster_keywords

Open
#726 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Refactor
Clarity
Mostly clear
Activity status
Active
Tech stack
python

Research direction

Start with app/core/analyzer.py and app/core/analyzer_strategies.py, especially generate_sorting_plan and _get_cluster_keywords, then inspect the analyzer and golden-plan tests named in the acceptance criteria. Map the routing phases and their current order before proposing phase boundaries. Done means the functions meet the stated length limit, phases have unit tests, and existing analyzer and golden-plan tests pass.

Written by the indexing model from the issue text.

Description

architecture enhancement ready-for-human

Problem

The planning core is concentrated in a few extremely long functions. Measured with ast, end_lineno - lineno:

Function Location Lines
GenerativeNamingStrategy._get_cluster_keywords app/core/analyzer_strategies.py:2121 1,207
IncrementalAnalyzer.generate_sorting_plan app/core/analyzer.py:684 1,176
HistoryManager._rollback_from_snapshot_internal app/core/history.py:1303 790
_execute_moves_recursive / AsyncMoveEngine.execute / _process_move_item app/core/mover.py:625 / 1593 / 1225 431 / 430 / 359
build_parser app/main.py:1326 348

generate_sorting_plan runs every routing phase inline, in sequence:

  • policy/keyword/learned rules
  • hash-based historical assignment
  • Jev classifier fallback
  • unsupported-file routing
  • doc-to-doc similarity
  • clustering
  • generative naming
  • re-injection of each routed set
  • conflict handling
  • relative-source post-processing

_get_cluster_keywords contains:

  • coherence routing / offline similarity (from ~2131)
  • few-shot retrieval (~2503)
  • a keyword fallback (~2938)
  • a second fallback (~3101)
  • dynamic GBNF grammar generation (~3207)

analyzer_strategies.py (3,363 lines) also mixes in:

  • prompt-redaction utilities (145-215) that wrap path_utils.scrub_user_home_paths
  • the KMeans worker-process main loop (413-665)
  • GGUF worker and logit-bias code (1087-1475)
  • a test helper InMemoryDBMock (224-237)

GenerativeNamingStrategy inherits from RecursiveKMeansStrategy (1476) rather than composing a clusterer with a namer.

Impact

  • These functions can't be unit-tested in pieces, so phase-ordering bugs only show up end-to-end.
  • Every feature (a new routing phase, a new model backend) lands as another block inside the same function, which leads to merge conflicts and long review times.

Proposed approach

  • Model planning as an ordered list of PlanningPhase objects, each implementing apply(ctx: PlanContext) -> PhaseResult and owning its routed-file set: PolicyRulePhase, HistoricalAssignmentPhase, JevPhase, UnsupportedRoutingPhase, SimilarityPhase, ClusteringPhase. generate_sorting_plan becomes a loop plus merge, and the daemon's fast_path_only becomes a phase subset.
  • Split analyzer_strategies.py into a package:
    • strategies/kmeans.py (strategy + worker main)
    • strategies/naming/ (prompt_builder.py for few-shot retrieval and redaction, grammar.py for GBNF, backends/gguf.py, backends/torch.py, fallback_keywords.py)
    • strategies/registry.py
  • Make GenerativeNamingStrategy compose a Clusterer and a FolderNamer instead of subclassing.
  • Move InMemoryDBMock to tests (or rename it to a real in-memory metadata store if production uses it).

Acceptance criteria

  • No function in app/core/analyzer*.py or strategies/ exceeds ~150 lines. Add a function-length check (e.g. ruff PLR0915, or an AST check in validate_architecture.py) with a ratchet.
  • Each planning phase has its own unit tests.
  • Existing analyzer and golden-plan tests pass unchanged.
Dominant language
Python
Stars
1
Forks
0
Avg merge
10h 55m
Merged PRs (30d)
427

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from fderuiter/sortify

All issues in fderuiter/sortify

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.