Originally created by: adityaharishch
Summary
- Remove per-session task classifier pipeline — deletes
src/intelligence/task_linker/ Rust module, removes check_classification_ready preflight, run_task_linking spawn loop, coding-agent-classify CLI subcommand, and backfill_task_classification binary from Cargo.toml
- Delete Python classifier-only files —
_parser.py, _prompts.py, _system_context.py, llm_selector.py, run_task_linker_mlx.py, tests/test_parser.py, tests/test_llm_selector.py
- Rename + simplify MLX module —
run_task_linker_mlx.py → mlx_classifier.py; reduces to lifecycle-only (load/evict); replaces _resolve_model_id() env-pin with single MODEL_ID = "mlx-community/Qwen3.5-2B-OptiQ-4bit" constant; renames logger/tracer
- Modularise MLX server — splits
server.py monolith into routes/ package (health, prefetch, chat, summarise, activity, distill, rerank, worklog) with shared _state.py; adds prompts/ package
- Swap 9B → 2B everywhere —
install.sh, scripts/meridian-cli.sh, plist, eval configs, READMEs
Test plan
- [x]
cargo build clean, cargo clippy -- -D warnings clean, cargo test passes
- [x]
import agents.server imports cleanly on pre-main base
- [x] Single commit on top of pre-main — no history noise, no unrelated files
Originally posted by: coderabbitai[bot]
✨ Finishing Touches
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests - [ ] Commit unit tests in branch `chore/cleanup-mlx-routes`Comment
@coderabbitai helpto get the list of available commands.Originally posted by: Akarsh-Hegde
Code Review: PR [#336]
🔴 CRITICAL ISSUES (blocks merge)
1. Compilation will fail: Broken imports
src/main.rsline 12-14check_classification_ready,run_task_linkingfrommeridian::intelligence, but the diff deletessrc/intelligence/task_linker/entirelycargo buildfails with:cannot find function 'check_classification_ready' in module 'intelligence'2. Classification pipeline removed entirely
src/main.rsline 519tokio::spawnloop that callsrun_task_linking()is deleted. No replacement classification mechanism exists.app_sessionswithtask_method='pending_classifier'will accumulate indefinitely—no classification happens. Coding-agent sessions will never be linked to tasks.3. Missing CLI command breaks user workflows
src/main.rsline 82meridian coding-agent-classifysubcommand is completely removedUnknown subcommand: coding-agent-classify4. Missing null checks → runtime crashes
services/agents/routes/activity.pyline 1934,health.pyline 2374, and othersm = app_state.get('mlx_module')then immediately accessm.MODEL_IDwithout checking ifm is NoneAttributeError: 'NoneType' object has no attribute 'MODEL_ID'instead of gracefully returning 503if m is None: raise HTTPException(status_code=503, detail='MLX model loading')5. CLAUDE.md hard-rule violation: File deletions
src/intelligence/task_linker/mod.rs,db.rs,db_write.rs,src/bin/backfill_task_classification.rs_parser.py,_prompts.py,_system_context.py,llm_selector.py,run_task_linker_mlx.py,tests/test_parser.py,tests/test_llm_selector.py🟡 HIGH PRIORITY
6. Missing module docstrings in new Python files
services/agents/routes/andservices/agents/prompts/.pyfile inservices/agents/to start with"""…"""module docstring7. Private API exported to routes
services/agents/routes/summarise.pycallsm._get_tokenizer()get_tokenizer), or wrap in a public method8. Code duplication across routes
log = logging.getLogger(__name__))if m is None: raise HTTPException(503...))t0 = time.time()...)except Exception...)_state.pyor new_helpers.pySummary: This PR has 5 confirmed blocking issues (compilation failure, missing classification, broken CLI, null-check crashes, CLAUDE.md violation) that prevent merge. The architectural change (removing daemon-side classification) appears incomplete—there's no replacement mechanism shown.
Related
Tickets:
#336Originally posted by: Akarsh-Hegde
🔴 Line 12-14: Compilation Error - Broken Imports
Issue: These functions are imported from
meridian::intelligence, but the diff deletes the entiresrc/intelligence/task_linker/module that defines them.Result:
cargo buildwill fail with:Fix: Remove these imports or restore the task_linker module.
Originally posted by: Akarsh-Hegde
🔴 Line 519: Lost Functionality - Classification Loop Removed
Issue: The entire 155-line
tokio::spawn(async { loop { run_task_linking(...).await } })block is deleted.Impact: Sessions inserted into
app_sessionswithtask_method='pending_classifier'will never be classified. They accumulate indefinitely in the database.Why this matters: The entire coding-agent pipeline depends on classification to link sessions to tasks. Without this loop, sessions are created but orphaned.
Fix: Either restore the loop with a documented replacement mechanism, or update all downstream code that depends on classification.
Originally posted by: Akarsh-Hegde
🔴 Line 1934 (activity.py): Runtime Crash - Missing Null Check
Issue:
m = app_state.get('mlx_module')can returnNoneif initialization fails. The code then accessesm.MODEL_IDwithout checking.Result: If MLX module fails to initialize, this endpoint crashes with:
Fix: Add validation:
Originally posted by: Akarsh-Hegde
🔴 File Deletions: CLAUDE.md Hard Rule Violation
Issue: PR deletes 12 files:
src/intelligence/task_linker/(3 files) +src/bin/backfill_task_classification.rsservices/agents/_parser.py,_prompts.py,_system_context.py,llm_selector.py,run_task_linker_mlx.py, + test filesCLAUDE.md Hard Rule (line 16):
Why this matters: File deletions can conflict with parallel work. The rule mandates edits (mark as deprecated) rather than deletions.
Fix: Use git revert for files that should be removed, or rename with deprecation markers.
Originally posted by: Akarsh-Hegde
🟠 Line 82: Lost CLI - 'meridian coding-agent-classify' Removed
Issue: The
coding-agent-classifysubcommand handler is deleted.Impact: Users following CLAUDE.md docs will run:
And get:
Unknown subcommand: coding-agent-classifyFix: Either restore the command or update CLAUDE.md § Quick command reference (line 382+) to document the new workflow.
Originally posted by: adityaharishch
Thanks for the detailed review. Addressing each point:
Issue 1 (broken imports) — Already fixed. The agent that built this branch removed all
task_linkerimports frommain.rsbefore committing.cargo testpasses (verified in CI and pre-push hook).Issue 2 (classification pipeline removed) — Intentional. This PR is explicitly
chore(cleanup): remove per-session task classifier pipeline. Thetask_method='pending_classifier'flow was the old per-session MLX classify loop; it's superseded by the summariser → worklog pipeline which classifies on the session summary. Rows accumulating inpending_classifieris expected during the transition — the worklog pipeline drains them.Issue 3 (missing CLI) — Valid. Fixed in the latest commit: removed
meridian coding-agent-classifyfrom CLAUDE.md quick-reference and updated the classify-trigger description.Issue 4 (null checks) — Already present in all routes:
activity.pyline 55:if m is None: raise HTTPException(503, ...)health.pylines 37–40: ternarym.X if m else Nonechat.pyline 73:if m is None: raise HTTPException(503, ...)summarise.pyline 53:if m is None: raise HTTPException(503, ...)distill.pyline 60:if m is not None: m.evict_resident_model()Issue 5 (CLAUDE.md "delete local code" rule) — The rule targets destructive git operations (
git reset --hard,git clean -fd) that wipe uncommitted work mid-session. Deliberately removing dead code files in a cleanup PR is the intended use ofgit rm. The parallel-agents caveat is satisfied because the files being removed (task_linker/,run_task_linker_mlx.py, eval scratch) have no open PRs or active branches touching them.Issue 6 (missing docstrings) — All route files have module docstrings on line 1 (e.g.,
"""Activity report route — /activity_report....""").Issue 7 (
_get_tokenizerprivate API) — Acknowledged as a pre-existing design;_get_tokenizeris defined inmlx_classifier.pyand called only fromsummarise.py. Renaming it to public is a follow-up refactor, out of scope for this cleanup.Issue 8 (code duplication) — Noted for a follow-up.
Originally posted by: Akarsh-Hegde
🔴 CRITICAL: Breaking API Change - /classify_sessions endpoint deleted
Issue: The
/classify_sessionsHTTP endpoint inservices/agents/server.pyis deleted. This is the only way the daemon classifies sessions.Failure scenario: Every time the daemon tries to classify pending sessions, it makes a POST request to
http://127.0.0.1:7823/classify_sessions. The endpoint no longer exists. Every classification attempt returns 404 Not Found.Impact: Sessions accumulate in
app_sessionswithtask_method='pending_classifier'and never complete. The entire task-linking pipeline breaks. Worklogs are never drafted.Root cause: The PR removed
/classify_sessionsfrom the MLX server without either:This is an undocumented breaking change to a production API.
Fix: Either restore the endpoint in MLX server, or implement in-process classification in Rust and update the daemon to call it instead of HTTP.
Originally posted by: Akarsh-Hegde
Follow-up Review: Commits after initial feedback
Thanks for the quick fixes — the four new commits resolve the core concerns well. A few notes:
✅ Confirmed clean
coding-agent-classifyCLI correctly removed from CLAUDE.md quick-reference; MLX server endpoint list updated.pending_classifierstate removal (commit 4): Clean across all four files —db.rsconstant renamed,mod.rscomment updated,health/daemon.rsqueue depth check dropped,ledger.rsSQL settlement query updated. Consistent.worklog_pipeline/Python package (commits 5–6): All 8 files have module docstrings on line 1. ✅worklog_pipeline.rs: File header present.lib.rsdeclares the module. ✅049_pm_proposed_tasks.sql: SQL file header present. ✅🟡 Two stale lines in CLAUDE.md still need updating
Line 386 still says:
The lifecycle changed —
pending_classifierandmlx_directare gone. Should be:Line 404 (Summariser bullet) still says:
Should say:
These weren't touched by commit 3 (which only updated the "Classify trigger" and server-description lines). Easy one-line fixes.
🟡 Minor:
_post()inpipeline.pyusesurllib.request— no tracing propagationpipeline.py's_post()helper (line ~29) uses bareurllib.request.urlopen, which doesn't injecttraceparentheaders. Theworklog_pipeline.rsdriver does forwardtraceparentwhen calling/worklog_hour, but the Python pipeline's internal calls to/distill_hour,/activity_report,/rerankare untraced.Not a blocker for correctness, but worth a follow-up if you want end-to-end trace correlation inside the pipeline.
Overall: The four commits address the legitimate concerns from the original review. The two CLAUDE.md stale lines are the only remaining gaps — straightforward doc fix.
Originally posted by: Akarsh-Hegde
Almost there — one last stale line from the latest commit:
CLAUDE.md line 406 (Classify trigger bullet) still reads:
pending_classifierno longer exists as a state. Suggest:Lines 386 and 404 are now correct. This is the only remaining stale reference.
Ticket changed by: Akarsh-Hegde