Repository navigation
feat(session): deterministic junk classifier for chat sessions #1303
Description
Important
Problem — Session curation (#1301) needs a deterministic bucket for every top-level chat session, derived purely from mechanical features. Only scattered title-prefix heuristics exist today (noise-title lists in the recap module and the open-threads skill); there is no single classifier.
Approach — A new pure classification module in the CLI package (a sibling of the session-retention module), taking a session-features object (title, user-message count, user-text chars, assistant-message count, todo count) and returning one of junk-greeting | dead-cast | probe | substantive. Rules calibrated on the 2026-09-20 manual sweep: 63 junk classifications, zero false positives on boundary review (evidence on parent #1301).
Acceptance Criteria
- A greeting-titled session (hello/hi/howdy/test/smoke vocabulary) with < 40 user chars, no todos, ≤ 6 assistant messages classifies
junk-greeting. - A session with zero assistant messages and ≤ 1 user message classifies
dead-cast, regardless of title length. - A session with zero user and zero assistant messages classifies
probe. - A substantive session with a greeting title but > 6 assistant messages classifies
substantive. - A session with pending todos never classifies into a junk bucket.
- The classifier is a pure function of the features object — no DB access, no I/O, no network.
Testing Decisions
New vitest file in the CLI package's test dir, following the pure-core test pattern of the retention/recap modules. Table-driven: one case per acceptance criterion plus the 2026-09-20 sweep calibration cases (greeting titles, one-word reply test, fleet-smoke, live campaign session).
Key Decisions
- Bucket set is closed:
junk-greeting | dead-cast | probe | substantive. Anything unrecognized defaultssubstantive(curation never loses work by default). - Thresholds (40-char, ≤6 assistant turns, vocabulary list) are module constants with named exports — the nightly archiver reads them; no hidden magic numbers.
- DB-row → features mapping lives OUTSIDE the pure module (caller maps rows); keeps the classifier testable without a DB.
Constraints & Invariants
- Deterministic only — no LLM, no network in this path (the Jev middle layer is a future slice).
- Never returns junk for a session it has insufficient features for.
Prior Art
session_retention.ts(CLI package) — the pure-core + ops-preference pattern and threshold conventions.session_recap.ts(extension plugin) — noise-title vocabulary to unify with.- The open-threads skill's noise-title filter — same vocabulary, do not duplicate divergence.
Source
Part of #1301 · spec of record: personal vault specs/spec-20260920-session-curation.md
Activity
aarontrowbridge commentedon Sep 20, 2026
Merged into the #1301 integration branch (amico/issue-1301-session-curation, PR #1307) as 23f37ba — director-verified: 16/16 slice tests, full amico-run suite 1646 passed / 0 failed, typecheck clean, module mechanically import-free (pure). Adjudication of the implementer's advisory: todos→substantive dominance over probe matches the spec (probe is a junk bucket; todos never junk).
feat(session): derived session curation — classifier, auto-archive, o…
fix(app): #1303 — the mirror's per-save prune starved its own reads (…