[Architecture] Break up 1,200-line methods in analyzer: generate_sorting_plan and GenerativeNamingStrategy._get_cluster_keywords
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
- Domain
- backend, developer-experience, testing
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
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
PlanningPhaseobjects, each implementingapply(ctx: PlanContext) -> PhaseResultand owning its routed-file set:PolicyRulePhase,HistoricalAssignmentPhase,JevPhase,UnsupportedRoutingPhase,SimilarityPhase,ClusteringPhase.generate_sorting_planbecomes a loop plus merge, and the daemon'sfast_path_onlybecomes a phase subset. - Split
analyzer_strategies.pyinto a package:strategies/kmeans.py(strategy + worker main)strategies/naming/(prompt_builder.pyfor few-shot retrieval and redaction,grammar.pyfor GBNF,backends/gguf.py,backends/torch.py,fallback_keywords.py)strategies/registry.py
- Make
GenerativeNamingStrategycompose aClustererand aFolderNamerinstead of subclassing. - Move
InMemoryDBMockto tests (or rename it to a real in-memory metadata store if production uses it).
Acceptance criteria
- No function in
app/core/analyzer*.pyorstrategies/exceeds ~150 lines. Add a function-length check (e.g. ruffPLR0915, or an AST check invalidate_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
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from fderuiter/sortify
-
bug ready-for-agent
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
priority:urgent security severity:critical
Difficulty 2/5 1-3 hours Newbie friendliness 57/100
Maintainers usually reply within 1 day
-
architecture enhancement ready-for-agent
Difficulty 5/5 Over a week Newbie friendliness 35/100
fderuiter/sortify#783 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement ready-for-human
Difficulty 4/5 3-5 days Newbie friendliness 48/100
fderuiter/sortify#740 · 1 comment ·
Maintainers usually reply within 1 day
-
architecture enhancement ready-for-human
Difficulty 5/5 Over a week Newbie friendliness 25/100
fderuiter/sortify#723 · 1 comment ·
Maintainers usually reply within 1 day
All issues in fderuiter/sortify
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 68/100
Maintainers usually reply within 4 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
ClockGU/clockwork-backend#169 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
aws-samples/sample-per-model-bedrock#616 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
chnm/teachinghistory-hugo#47 ·
-
good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
pandas-dev/pandas-stubs#2047 · 2 comments ·
Maintainers usually reply within 1 day