Skip to content

E2e isolation: sessions run against a hash-verified plugin snapshot - #7

Merged
danielrmay merged 1 commit into
mainfrom
e2e-isolation
Jun 10, 2026
Merged

danielrmay merged 1 commit into
mainfrom
e2e-isolation

Conversation

@danielrmay

Copy link
Copy Markdown
Owner

Closes #3.

What

E2e sessions are now physically isolated from the plugin repo, with an empirical post-run guarantee:

  • run.sh snapshots the plugin payload once per suite run (rsync of the working tree minus .git/.venv/caches) and every claude invocation gets the snapshot as --plugin-dir — sessions never receive the real repo path. Fanout children (parallel/stress modes) inherit the parent's snapshot via CLAUDITY_E2E_PLUGIN_DIR.
  • At exit, the owning process recomputes the snapshot's sha256 manifest and fails the run if any session mutated the plugin, printing the drifted paths and keeping the snapshot for inspection. __pycache__ sits outside the integrity contract (interpreter byproduct: the vendored scripts compile .pyc into the snapshot at runtime).
  • The repo git status check stays as defense in depth — now delta-based against suite-start state, so developer work-in-progress no longer false-positives; any delta would indicate a path leak.

Consequences documented in TESTING.md/CLAUDE.md: editing plugin content during a background run is now safe (sessions hold the frozen snapshot); editing the harness scripts themselves mid-run still races.

Verification

  • 8 token-free mechanics tests (tests/test_e2e_isolation.py): runtime payload present, junk excluded, edit/add/delete tamper detection with drifted-path reporting, fanout snapshot adoption. Tier 1 total: 254.
  • Free no-match runs through both the sequential and stress/fanout paths (snapshot create → verify → remove, no leftovers).
  • Paid: 10-record (MCP server runs from the snapshot — proven incidentally by the .pyc files the server compiled into the snapshot on the first verified run) and 02-routing (skill injection from the snapshot), both PASS with zero /tmp leftovers.
  • The very first verified run caught a real mutation (the .pyc compilation) before the exclusion existed — the detection mechanism has a live catch on record.

🤖 Generated with Claude Code

Sessions never see the real repo: run.sh snapshots the plugin payload
once per suite (rsync minus .git/.venv/caches), every claude invocation
gets the snapshot as --plugin-dir, and fanout children inherit it via
CLAUDITY_E2E_PLUGIN_DIR. At exit the owning process recomputes the
snapshot's sha256 manifest and FAILS the run if any session mutated the
plugin (drifted paths printed, snapshot kept for inspection).
__pycache__ is outside the integrity contract — the very first verified
run caught the vendored scripts compiling .pyc into the snapshot, which
doubles as proof the MCP server runs from the snapshot, not the repo.

The old detection-only posture upgrades to prevention + proof: the
repo git-status check remains as defense in depth, now delta-based so
developer WIP doesn't false-positive. Mid-run edits to plugin content
no longer invalidate in-flight sessions (harness scripts still run live
from the repo — noted in CLAUDE.md/TESTING.md).

Verified: 8 token-free mechanics tests (tests/test_e2e_isolation.py:
payload presence, junk exclusion, edit/add/delete tamper detection,
fanout adoption), free no-match runs through the sequential and stress
paths, and paid 10-record (MCP from snapshot) + 02-routing (skill
injection from snapshot) passes with zero leftovers.
@danielrmay
danielrmay merged commit 30e3314 into main Jun 10, 2026
2 checks passed
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.

e2e tests should be properly isolated

1 participant