Skip to content

6. consolidate session feature ownership - #2249

Open
kevinjosethomas wants to merge 6 commits into
refactor/session-coordinationfrom
refactor/session-feature-ownership
Open

6. consolidate session feature ownership#2249
kevinjosethomas wants to merge 6 commits into
refactor/session-coordinationfrom
refactor/session-feature-ownership

Conversation

@kevinjosethomas

@kevinjosethomas kevinjosethomas commented Sep 11, 2026

Copy link
Copy Markdown
Member

Context

This continues the coding-agent cleanup stack by finishing feature ownership after the earlier session extractions. Compaction, refinement and input still had implementations split between core and session, making related behavior difficult to find and change together.

Changes

Consolidates context algorithms, refinement planning and persistence, input actions, autonomy and child request contracts under their session owners. Separates daemon residency policy from the action queue and model search/shell requests from child handling. Public exports and historical import paths remain available through explicit compatibility exports. Validation rules, autonomous argument parsing, persistence, protocol and session behavior are preserved. Adds reusable refactoring conventions and the remaining migration ledger. The CI trigger now accepts stacked PR targets with its existing contributor checks and jobs unchanged.

Validation

Full repository checks and the complete GitHub CI matrix pass at c3311d9. The combined session suite passed 343 tests. Paired Prime Sandboxes exercised installed TUI input, CLI/daemon refinement ordering, real Python execution/interrupt/snapshot/restore, SDK exports and historical declarations against the pinned base. Independent review found no actionable regression. Initial SDK-name and missing-goal-interpreter fixture failures are retained in the evidence; separate corrections passed, including the unchanged goal assertions at the final stack head. Two live-provider compaction cases remain intentionally unexecuted.

The sandbox-tested product pin is c7b0f53; c3311d9 changes only the CI trigger. All sandbox resources were deleted. Current-head Bugbot passes and its compatibility-alias thread was resolved with the required compatibility rationale. Macroscope skipped at its cost cap, no new-head CodeQL check is present, and the automated benchmark report is complete. It flags +0.14 MB compressed artifacts (+1.22%) against then-current main b53c2e9; the other 16 metrics show no clear change under the harness thresholds. This compares the cumulative stack against main, not this follow-up in isolation. No performance improvement is claimed.

ENG-5934, ENG-5938. Stacked on #2194; kernel/runtime ownership follows in #2250.

Note

Consolidate session feature ownership by relocating core modules into session subpackages

  • Moves autonomy, context, compaction, refinement, input, children, and models feature implementations from core/ into their canonical session/ subpackages; core modules become compatibility facades that re-export from the session owners.
  • Adds new session-owned implementations: token/context estimation in token-estimate.ts, usage accumulation helpers in usage.ts, context-tree usage utilities in context-tree.ts, RLM model search in model-search.ts, RLM host-request validators in host-requests.ts, and daemon worker residency policies in residency-policy.ts.
  • Fixes input checkpoint processing in input-checkpoints.ts to wait when the host reports the input pump as busy instead of checking scheduler suspension directly, preventing a CPU spin during blocked bash/compaction/retry work.
  • Adds compatibility tests asserting export-name and object-identity parity between legacy core paths and session-owned modules, plus RLM host-request validation tests and an idle-spin regression test.
  • Risk: the CI workflow in ci.yml removes the main-branch push filter; the core/ facades must stay in sync with session exports or compatibility tests will fail.

Macroscope summarized 3e96f9e.


Note

High Risk
Large refactor of session orchestration, input scheduling, and compaction/refinement boundaries with compatibility facades; incorrect wiring could affect ordering, idle/passivation, or legacy import paths.

Overview
This PR finishes session feature ownership after earlier extractions by moving compaction, refinement, context, input, autonomy, and child contracts into canonical session/ modules while core/ paths become thin re-export facades (including shrinking core/agent-session.ts to forward session/agent-session.ts).

Related splits include ActionStore queue logic vs daemon worker residency/eviction in modes/daemon/workers/residency-policy.ts, refinement planning vs lightweight formatting to break import cycles, and child model search / bash host requests out of the old combined RLM module.

Contributor docs add docs/refactoring.md, an expanded source-organization-plan.md, and updated architecture/source-map guidance. CI now runs on all pull requests (drops the pull_requestmain branch filter) so stacked branches get checks.

A separate fix stops session idle waits from spinning CPU when the input pump is blocked on bash, compaction, or retry work.

Reviewed by Cursor Bugbot for commit 3e96f9e. Bugbot is set up for automated code reviews on this repo. Configure here.

Preserve existing public and historical module exports through explicit compatibility facades. Keep compaction, refinement, and shared context implementations with their session owners.

closes #2190
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

Prime Agent performance — partial

PR 3e96f9ee compared with main ca67580b.

Overall: 1 regressed · 0 improved · 12 no clear change · 4 unavailable.

Metric Main This PR Change
Cold startup 2,383.1 ms
Warm startup 1,638.7 ms
Installation 25.33 s 25.44 s ≈ +0.11 s (+0.43%)
Compressed release artifacts 11.17 MB 11.26 MB $\textcolor{#aa6a65}{\textsf{↑ +0.09 MB (+0.80\%)}}$
Installed footprint
Idle memory, summed RSS 1,016.90 MB

Python runtime

Metric Main This PR Change
Python kernel startup 121.4 ms 121.7 ms ≈ +0.2 ms (+0.21%)
Python cell round trip 0.464 ms 0.474 ms ≈ +0.011 ms (+2.28%)
Empty bash command 10.3 ms 10.3 ms ≈ -0.05 ms (-0.48%)
Bash git status 15.5 ms 15.4 ms ≈ -0.1 ms (-0.76%)
Bash 32 KiB output 10.6 ms 10.6 ms ≈ -0.05 ms (-0.47%)
35 cells / 9 shell calls 149.9 ms 152.8 ms ≈ +2.9 ms (+1.95%)
Python interrupt to done 1.495 ms 1.418 ms ≈ -0.077 ms (-5.17%)
Python state snapshot 24.8 ms 24.6 ms ≈ -0.3 ms (-1.01%)
Python state restore 343.5 ms 331.3 ms ≈ -12.2 ms (-3.55%)
Python idle RSS 35.43 MB 35.11 MB ≈ -0.32 MB (-0.90%)
Python RSS after pandas workload 97.68 MB 98.42 MB ≈ +0.75 MB (+0.77%)

Sandbox cost: ~$0.1629 — no inference calls.
Run, logs, and downloadable raw results

Methodology and samples

Main resolved at 2026-09-12T06:55:55.904723+00:00. Harness ca67580b.
Linux x64, 4 vCPU, 8 GB RAM, 20 GB disk; region us.
Image: node:24-bookworm@sha256:be23f54a88d34e8824c741b19b91064094f92c1c97b194144bfc8b50d67258e2.
Stock tools, skills, daemon, and Python bootstrap enabled; fresh homes and a fixed Git fixture.
Onboarding is dismissed; the editor starts without a selected model or submitted prompt.
Medians shown. Arrows require a 20% timing/memory change plus absolute floors and IQR.
These practical noise floors are not a statistical significance test.
Cold means stopped Prime processes; OS filesystem caches are not flushed.
No model requests or credentials. Installation excludes build/setup time.
Installer tarballs use loopback; npm/Python downloads use the network with fresh caches.
Artifact size counts release tarballs; footprint after first use includes registry packages.
MB is decimal. Summed RSS can double-count shared pages; PSS is recorded when available.
Provisioning, setup, and build durations are recorded separately in the raw results.
Kernel probes use the installed JSONL runtime, outside the TUI/TypeScript host.
Per trial: 50 Python cells, 5 calls per shell case, and one 35-cell mix (9 git status calls).
Cell/shell values are batch means; other runtime timings are single operations.
State fixture: a 10,000-row × 8-column integer DataFrame and a 10,000-integer list.
Restore runs in a fresh kernel, including pandas imports; kernel startup is excluded.
Kernel RSS covers the isolated Python process; loaded RSS follows the pandas workload.
Costs estimate full sandbox lifetimes at configured rates, including setup and build.
Budget target: $1; not a billing cap. Checks are informational.

Metric Main successful/attempted PR successful/attempted Main spread PR spread
Cold startup 0/10 10/10 IQR 109.3 ms
Warm startup 0/8 9/9 IQR 36.5 ms
Installation 3/3 3/3 range 0.99 s range 0.72 s
Compressed release artifacts 1/1 1/1
Installed footprint 0/0 0/0
Idle memory, summed RSS 0/0 10/10 IQR 48.46 MB
Python kernel startup 10/10 10/10 IQR 4.8 ms IQR 2.2 ms
Python cell round trip 10/10 10/10 IQR 0.021 ms IQR 0.016 ms
Empty bash command 10/10 10/10 IQR 0.6 ms IQR 0.7 ms
Bash git status 10/10 10/10 IQR 0.7 ms IQR 0.6 ms
Bash 32 KiB output 10/10 10/10 IQR 0.4 ms IQR 0.5 ms
35 cells / 9 shell calls 10/10 10/10 IQR 1.4 ms IQR 9.5 ms
Python interrupt to done 10/10 10/10 IQR 0.119 ms IQR 0.132 ms
Python state snapshot 10/10 10/10 IQR 2.8 ms IQR 2.0 ms
Python state restore 10/10 10/10 IQR 21.2 ms IQR 23.7 ms
Python idle RSS 10/10 10/10 IQR 3.20 MB IQR 2.05 MB
Python RSS after pandas workload 10/10 10/10 IQR 2.81 MB IQR 2.33 MB

Failures:

  • pr measure 0: RuntimeError
  • main measure 4: RuntimeError
  • main measure 6: RuntimeError
  • main: CalledProcessError: Command '['/usr/sbin/runuser', '-u', 'benchmark1', '--', 'prime-agent', 'stop', '6f29cd880a1f', '--json']' returned non-zero exit status 1.
  • main cold trial 0: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 1: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 2: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 3: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 4: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 5: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 6: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 7: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 8: TimeoutError: Timed out waiting for the expected terminal state
  • main cold trial 9: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 0: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 1: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 2: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 3: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 5: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 7: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 8: TimeoutError: Timed out waiting for the expected terminal state
  • main warm trial 9: TimeoutError: Timed out waiting for the expected terminal state
  • PR: CalledProcessError: Command '['/usr/sbin/runuser', '-u', 'benchmark1', '--', 'prime-agent', 'stop', '3e051ed70113', '--json']' returned non-zero exit status 1.

@kevinjosethomas kevinjosethomas added no-changelog Internal change with no user-visible changelog entry pkg:coding-agent labels Sep 11, 2026 — with ChatGPT Codex Connector
@kevinjosethomas
kevinjosethomas marked this pull request as ready for review September 12, 2026 00:06
@macroscopeapp

macroscopeapp Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Macroscope skipped reviewing this pull request. Per-review cost limit exceeded (workspace setting).

This review would cost an estimated $50.47, which exceeds your per-review limit of $10.00.

The top 3 files driving up this estimate:

File Diff Size Estimate
packages/coding-agent/src/core/agent-session.ts 124.13KB $6.21
packages/coding-agent/src/session/agent-session.ts 123.25KB $6.16
packages/coding-agent/src/core/refinement/refinement.ts 48.43KB $2.42

Tip

To get this pull request reviewed, you can:

  1. Comment @macroscope-app on this PR to request a manual review (monthly spend limits still apply).
  2. Exclude the file(s) above from review by adding a pattern to your .macroscope/ignore.md — note that creating this file replaces Macroscope's built-in default ignores rather than extending them.
  3. Raise your cost limit in your workspace billing settings.

Turn off this reminder going forward

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c7b0f53. Configure here.

Comment thread packages/coding-agent/src/session/compaction/compaction.ts
Remove only the pull-request base branch filter while preserving the contributor gate and existing jobs. Refs ENG-5934; closes #2249.
@kevinjosethomas
kevinjosethomas added this pull request to stack #2198 September 12, 2026 02:54
@Dmatut7

Dmatut7 commented Sep 12, 2026

Copy link
Copy Markdown

Hi — downstream line here (we run a fork with ~100 reliability commits on your 0.9.x; full context in Discussion #2239). We've been studying this refactor stack in detail because our fixes will need re-homing once it lands. The stack's shape is genuinely helpful for that. Four seams would make the re-home purely additive on our side, if they fit your plans:

  1. A residency predicate on the session coordinator (something like "is this session busy with queued/in-flight work") that we can hook our stall-watchdog exemption into — right now our liveness vouch has to reach into turn internals.
  2. A delivery idempotency key on the agent-message path (sender-minted message id honored across retries) — we built one downstream after production duplicate deliveries; if yours lands with a different shape we'd rather align early.
  3. A retry/stream seam on the supervisor catch-up path (we added bounded retry + gap detection after 708 production "failed to catch up" events).
  4. A kernel liveness contract (an explicit "the kernel is alive but busy" signal distinct from output) — we added an out-of-band heartbeat for this after 144 production watchdog kills of healthy long-running cells.

And one heads-up in return: the stack's current tip still carries the waitForIdle spin defect you fixed in #2151session/input/input-checkpoints.ts uses the narrow predicate again, so a session that is idle-but-externally-busy spins the event loop at 100% CPU. Easy to verify against #2151's test.

Happy to share our implementations of any of the four (each has regression tests). Thanks for doing this split — the god object needed to go.

@kevinjosethomas

Copy link
Copy Markdown
Member Author

hey @Dmatut7! Sorry for the inconvenience here-- we were shipping really fast, but now I'm taking the time to clean up the codebase, especially starting with the agent-session class 😅

I'll take a look at your 4 suggestions and see if we can add to the stack or a future PR. Thanks for reaching out! and would love to hop on a call and learn about your usecases with Prime Agent if you're available :)

Closes #2249. Adapted from the idle-wait regression and fix proposed in #2151.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Internal change with no user-visible changelog entry pkg:coding-agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants