Skip to content

perf+refactor: DB hot-path index, dedup, classifier split, history bound - #63

Merged
Pher217 merged 6 commits into
mainfrom
claude/2026-06-15-perf-refactor
Jun 15, 2026
Merged

perf+refactor: DB hot-path index, dedup, classifier split, history bound#63
Pher217 merged 6 commits into
mainfrom
claude/2026-06-15-perf-refactor

Conversation

@Pher217

@Pher217 Pher217 commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Second cleanup pass (after #59, now merged). Rebased onto current main; mergeable / conflict-free. Implemented by Sonnet + Kimi k2.7 workers under review; I reviewed every diff, ran tests, committed. Independently reviewed by Codex (gpt-5.5) — no blocker/major behavior-equivalence problems.

6 commits

  1. build: pin ruff + bandit to a minor range — they gate CI as blocking steps; an unpinned floor lets a new release silently turn CI red (the CI-drift root cause). mypy stays unpinned (advisory).
  2. perf: index hot Thread lookup + drop per-turn aggregate; harden observer — index on Thread.external_session_ref (was a seq scan on every observed line/host frame); MAX(sequence)→indexed order_by(-sequence).first(); observer logs failures w/ traceback + backoff; bounds the dedup seen set; logs swallowed HTML→plain fallbacks.
  3. refactor: consolidate duplication — shared apps/core/auth.py::BearerTokenPermission (connectors+gateway), apps/core/html.py::_esc, JsonlScanMixin+_cwd_to_repo for the 4 JSONL adapters. Behavior-identical (Codex-confirmed: settings, flags, compare_digest, Ed25519 short-circuit unchanged).
  4. refactor: extract classifier helpersdetect_major_steps_classify_against_prior+_finished_by_disappearance. Behavior-identical.
  5. perf: bound _build_history to the 200 most recent messages. ⚠️ Deliberate behavior change for long threads (older context dropped); new test added.
  6. style: fix lint surfaced by the pinned ruff in newly-merged feat(hostlink): reconcile PTY session liveness on daemon (re)connect #62/feat: headless Claude relay — drive a session from Telegram with clean structured replies #64 code (F541, unused imports, import sort, redundant Thread as _T).

❗ Dropped from this PR: the telegram/service.py split

I split that 636-line file into modules earlier, but telegram/service.py is the single hottest file in the repo — it collided with every telegram PR merged this session (#58, #60, #62, #64). Keeping the split here is a perpetual rebase treadmill. The split work is preserved on branch perf-refactor-with-telegram-split (Codex-reviewed, all tests green) and can be reapplied in a quiet window once telegram dev settles. This PR keeps the 6 conflict-free, high-value commits.

Test summary (fresh, local, on current main)

  • Backend: ruff clean · bandit exit 0 · migrations clean · git diff --check clean · 575 pass / 3 skip / 1 fail (pre-existing test_chat_surface_thread_excluded_from_fleet).
  • host-agent: ruff clean · 201 pass / 2 fail — both pre-existing from feat(hostlink): reconcile PTY session liveness on daemon (re)connect #62 (test_wsclient.py); my host-agent code is byte-identical to main.

Supervisor notes — proposed items deliberately NOT done

@Pher217
Pher217 force-pushed the claude/2026-06-15-perf-refactor branch from 85eb3b3 to f90df11 Compare June 15, 2026 21:04
Pher217 added 6 commits June 15, 2026 23:07
These two gate CI as blocking steps; with unpinned `>=` floors a new
release silently turns CI red with no code change (which is how the lint/
security steps drifted red on main). Pin to the current known-good minor;
mypy stays unpinned since its CI step is advisory.
- Add a DB index on Thread.external_session_ref — it is filtered on every
  observed line (observe/service.py) and every host WS frame
  (hostlink/consumers.py) and was previously a sequential scan.
- Replace the per-turn MAX(sequence) aggregate with an indexed
  order_by(-sequence).first() in observe/service.py and threads/dispatch.py.
- Observer loop: log scan failures with full traceback + back off after 5
  consecutive errors (was a silent one-line stderr write).
- Bound the per-runtime dedup 'seen' set (was unbounded for process lifetime).
- Log the swallowed exception before each HTML->plain Telegram fallback.

No behavior change. backend 556 pass / 1 pre-existing fail.
…_esc

- New apps/core/ utility package (no models, not in INSTALLED_APPS):
  - BearerTokenPermission base — connectors + gateway permission gates now
    subclass it (settings name + request-flag parameterized). connectors keeps
    its Ed25519 short-circuit, then delegates the legacy bearer path to super().
  - html._esc — shared by observe/formatting and slash/handlers/sessions.
- observe/runtimes: JsonlScanMixin provides the one scan_file_meta shared by the
  four JSONL adapters; _cwd_to_repo() replaces the repeated cwd->repo expression.
  opencode (sqlite) untouched; each adapter keeps its own parse logic.

Behavior-identical refactor. 166 targeted tests + full suite green (556/1 pre-existing).
_build_history loaded every message of a thread into the LLM context on
every turn (unbounded DB read + context growth). Cap at the 200 most recent
allowed-role messages, returned in chronological order. Identical output for
threads with <=200 messages; longer threads keep the most recent window.
Adds a test asserting the bound, ordering, and oldest-dropped behavior.

Behavior change for long threads (older context is dropped) — deliberate.
After rebasing onto main, the pinned ruff flagged issues in freshly-merged
code (#62/#64): F541 f-strings, unused imports, import sorting, and N814
(Thread imported as _T, redundant — module-level Thread already imported).
All mechanical, no behavior change.
@Pher217
Pher217 force-pushed the claude/2026-06-15-perf-refactor branch from f90df11 to 2e69881 Compare June 15, 2026 21:12
@Pher217 Pher217 changed the title perf+refactor: DB hot-path index, dedup, module splits (stacked on #59) perf+refactor: DB hot-path index, dedup, classifier split, history bound Jun 15, 2026
@Pher217
Pher217 merged commit 47b1937 into main Jun 15, 2026
@Pher217
Pher217 deleted the claude/2026-06-15-perf-refactor branch June 15, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant