Skip to content

track runtime content hash for kernel venv staleness - #291

Merged
kevinjosethomas merged 4 commits into
mainfrom
eng-4371
Jul 1, 2026
Merged

track runtime content hash for kernel venv staleness#291
kevinjosethomas merged 4 commits into
mainfrom
eng-4371

Conversation

@kevinjosethomas

@kevinjosethomas kevinjosethomas commented Jun 30, 2026

Copy link
Copy Markdown
Member
  • the kernel venv could keep a stale prime-agent-runtime indefinitely because the staleness check compared a constant against itself, silently breaking mcp skills like linear and notion.
  • the venv now records a content hash of the local runtime source and rebuilds automatically whenever that source changes, instead of relying on manual schema bumps.
  • also asserts mcp support is importable in the readiness probe and bumps the bootstrap schema so existing stale venvs refresh on next run.

Note

Medium Risk
Changes Python kernel bootstrap and can force full venv rebuilds on upgrade or after local runtime edits; incorrect hashing could cause unnecessary rebuilds or miss staleness.

Overview
Fixes kernel venvs keeping an outdated prime-agent-runtime because staleness only compared the fixed package name "prime-agent-runtime" to itself, so local runtime changes never triggered a refresh (breaking MCP-related capabilities).

.bootstrap-version (schema 8) now stores a runtime identity: a sha256: hash over local pyproject.toml and all src/rlm/**/*.py when a checkout is found via resolveRuntimeIdentity / hashRuntimeSource; registry-only installs still use the package name. Readiness checks compare that identity on each ensureKernelPython run and rebuild the venv when it diverges, without relying on manual schema bumps for every runtime edit.

The runtime readiness probe also requires rlm.McpIntegration to import. Tests expect the new schema, dynamic runtime identity, and a rebuild when the recorded hash is stale.

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

Note

Track runtime content hash to detect kernel venv staleness

  • Adds resolveRuntimeIdentity in bootstrap.ts to compute a sha256 hash over rlm/*.py files and pyproject.toml when a local runtime source dir is present, falling back to 'prime-agent-runtime' for registry installs.
  • Threads runtimeIdentity through kernelReady, kernelBaseReady, writeBootstrapVersion, and syncPythonSkills so the .bootstrap-version file records the content hash rather than a fixed package name.
  • Any change to runtime source files (names or contents) now causes the venv to be rebuilt automatically on next kernel startup.
  • Bumps BOOTSTRAP_SCHEMA from 7 to 8 and adds from rlm import McpIntegration to the runtime readiness check.
  • Risk: all existing venvs at schema 7 are immediately considered stale and will be rebuilt on first use.

Macroscope summarized db85a7a.

@linear

linear Bot commented Jun 30, 2026

Copy link
Copy Markdown
ENG-4371 Kernel venv keeps stale prime-agent-runtime; needs generic runtime version check

Summary

The IPython kernel venv (~/.prime/agent/kernel-venv) can keep a stale prime-agent-runtime even after the local source has moved on, because the bootstrap "is this venv current?" check has no notion of runtime content/version. This silently disables features that depend on newer runtime code — most visibly the MCP integrations (Linear, Notion), which fail to import with ImportError: cannot import name 'McpIntegration' from 'rlm' and get registered as unavailable skills.

This is not an auth problem: the failure happens at the skill's very first import line (from rlm import McpIntegration), before any credential / login path runs.

Root cause

In packages/coding-agent/src/core/kernel/bootstrap.ts:

  • The venv-reuse gate is kernelReady() -> bootstrapBaseVersionCurrent(), which compares version.runtime === RUNTIME_REQUIREMENT. Both sides are the literal string "prime-agent-runtime". There is no version or content hash for the runtime, so a venv built from an older (even since-deleted) local source still compares as "current".
  • RUNTIME_READY_CHECK asserts rlm.run, rlm.host_request, harness CRUD, HarnessEntry.reference, etc., but does not assert anything about MCP (from rlm import McpIntegration). So a runtime missing rlm/mcp_base.py entirely still passes the readiness probe.
  • The only lever that currently forces a rebuild is bumping BOOTSTRAP_SCHEMA. It was not bumped when the runtime gained MCP support, so existing venvs were never invalidated.

Observed in the wild: a kernel venv whose prime_agent_runtime direct_url.json pointed at file:///.../.worktrees/eng-4227/prime-agent-runtime (a worktree that no longer exists and predates mcp_base.py). Recorded .bootstrap-version had schema: 7, matching the running schema, so the venv was reused indefinitely.

Impact

  • MCP skills (Linear, Notion) silently unavailable for users whose venv predates MCP support, with a confusing error that looks auth-related.
  • Any future runtime change is invisible to existing venvs unless someone remembers to bump BOOTSTRAP_SCHEMA. Easy to forget; affects end users, not just local dev.

Proposed fix

Make venv staleness detection track the runtime version generically, instead of relying on a static string + manual schema bumps:

  1. Add a runtime version/identity that updates automatically whenever the runtime changes. Options:
    • Record prime_agent_runtime.__version__ (and bump it on every runtime change), or
    • Record a content hash of the installed rlm package, and compare it against the local source on startup.
  2. Store that value in .bootstrap-version and compare it in bootstrapBaseVersionCurrent(); a mismatch triggers reinstall from local source.

This way the venv refreshes for users automatically on any runtime change, without per-feature readiness assertions or remembering to bump the schema. (Adding a specific McpIntegration assertion to RUNTIME_READY_CHECK would fix this one symptom, but the generic version check is the durable fix.)

Workaround

Delete and rebuild the venv: rm -rf ~/.prime/agent/kernel-venv (next IPython run rebuilds from local prime-agent-runtime/).

Review in Linear

Comment thread packages/coding-agent/src/core/kernel/bootstrap.ts

@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 f2c6b78. Configure here.

Comment thread packages/coding-agent/src/core/kernel/bootstrap.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium

function runtimeCandidateDirs(): string[] {

resolveRuntimeSourceDir() returns the first candidate directory containing a pyproject.toml, and runtimeCandidateDirs() lists dist/prime-agent-runtime ahead of the live source checkout. After packages/coding-agent is built once, the dist/prime-agent-runtime snapshot becomes stale relative to the real source tree, but resolveRuntimeIdentity() and bootstrapVenv() still hash and install from that stale copy. The kernel venv then uses outdated runtime code and never rebuilds when the actual local runtime source changes, defeating the staleness tracking this PR adds. Consider preferring the live source checkout when it exists, or documenting why the built copy should take precedence.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/coding-agent/src/core/kernel/bootstrap.ts around line 530:

`resolveRuntimeSourceDir()` returns the first candidate directory containing a `pyproject.toml`, and `runtimeCandidateDirs()` lists `dist/prime-agent-runtime` ahead of the live source checkout. After `packages/coding-agent` is built once, the `dist/prime-agent-runtime` snapshot becomes stale relative to the real source tree, but `resolveRuntimeIdentity()` and `bootstrapVenv()` still hash and install from that stale copy. The kernel venv then uses outdated runtime code and never rebuilds when the actual local runtime source changes, defeating the staleness tracking this PR adds. Consider preferring the live source checkout when it exists, or documenting why the built copy should take precedence.

@kevinjosethomas
kevinjosethomas merged commit fdac4bf into main Jul 1, 2026
3 checks passed
@kevinjosethomas
kevinjosethomas deleted the eng-4371 branch July 8, 2026 00:30
zhengr pushed a commit to zhengr/prime-agent that referenced this pull request Aug 8, 2026
zhengr pushed a commit to zhengr/prime-agent that referenced this pull request Aug 8, 2026
…ai#291)

* track runtime content hash for kernel venv staleness

* include runtime pyproject.toml in venv staleness hash

* fail loudly when local runtime source is unreadable

* document why dist runtime snapshot takes resolution precedence
thomaswillner pushed a commit to thomaswillner/prime-agent that referenced this pull request Aug 29, 2026
…ctions

Codex found four P2s on the correction PR. All verified, all valid.

1. The input of record still told the operator `execution.mode: off` unquoted --
   the exact form this PR establishes the loader refuses. An implementing agent
   following it would reproduce the refusal. Now quoted, with the reason.

2. I over-corrected. Having found that a leftover
   allow_cboe_vix3m_fallback does NOT block startup, I demoted deleting it to
   "housekeeping". Wrong in the other direction: it still leaves
   `startup: GONE data (paper_data_composition_refused)` with entries
   IMPOSSIBLE, so a healthy /readiness is unreachable while it is present.
   Only the REASON was wrong; the step is still required.

3. The operator steps implied that starting the Gateway yields healthy session
   domains. It does not. Observable (c) failed artifact_missing on BOTH
   domains, and those artifacts come from the Hermes publisher, not from
   Gateway uptime. The steps now name three preconditions, not one.

4. Bare `PR PrimeIntellect-ai#291` in prime-agent markdown autolinks to prime-agent's own PrimeIntellect-ai#291,
   which exists and is unrelated -- pointing readers away from the evidence the
   claims rest on. Now explicit cross-repository links.

Findings 2 and 3 are the useful ones: a correction that swings past the truth
is still wrong, and a checklist that names one precondition out of three
promises an outcome it cannot deliver.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5B7QM1QLQuWSBMCxiCzS6
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