Ephemeral Workspace¶
SuperQode uses ephemeral workspaces to ensure your code is never modified without consent. This page explains how workspace isolation works and why it's critical for safe QE.
The Workspace Guarantee¶
Core Guarantee
Your original code is ALWAYS preserved. SuperQode tests in an isolated sandbox and reverts all changes after each session.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ QE SESSION LIFECYCLE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ 1. SNAPSHOT Original code preserved โ
โ โ โ
โ 2. QE SANDBOX Agents freely modify, inject tests, โ
โ โ run experiments, break things โ
โ โ โ
โ 3. REPORT Document what was done, what was found โ
โ โ โ
โ 4. REVERT All changes removed, original restored โ
โ โ โ
โ 5. ARTIFACTS Patches, tests, reports preserved โ
โ (in .superqode/qe-artifacts/) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Why Ephemeral Workspaces?¶
1. Safety¶
Agents can test destructively without risk:
- Inject test code
- Modify configurations
- Stress systems
- Break things intentionally
All without affecting your actual codebase.
2. Freedom¶
In the sandbox, agents can:
- Perform destructive testing
- Simulate malicious inputs
- Run load tests
- Explore edge cases aggressively
3. Reproducibility¶
The original state is always known:
- Every session starts from a clean state
- Results are reproducible
- No accumulated drift
4. Trust¶
You can trust SuperQode because:
- Default behavior is read-only
- Changes require explicit consent
- Revert is automatic and guaranteed
Workspace Isolation Methods¶
SuperQode supports multiple isolation methods:
1. Git Worktree Isolation (Optional)¶
Uses Git worktrees for lightweight isolation when enabled with --worktree:
# SuperQode creates a worktree internally
git worktree add ~/.superqode/working/<repo>/qe/<session-id> HEAD
# QE runs in the worktree
# Original repository is untouched
# After QE, worktree is cleaned up
git worktree remove ~/.superqode/working/<repo>/qe/<session-id>
Advantages: - Fast setup - Low disk usage (uses Git's COW) - Perfect isolation for Git repositories
Usage: Enable with superqe run . --worktree in Git repositories. Note: Worktree isolation writes to .git/worktrees. Use it only if you are comfortable with git metadata changes.
2. Directory Snapshot¶
For non-Git projects, creates a directory copy:
# SuperQode snapshots the directory
cp -r . .superqode/sandbox
# QE runs in the sandbox
# Original directory is untouched
# After QE, sandbox is removed
rm -rf .superqode/sandbox
Advantages: - Works with any project - Simple and reliable
Snapshot System¶
What Gets Snapshotted¶
| Item | Snapshotted | Notes |
|---|---|---|
| Source code files | โ | All tracked files |
| Configuration files | โ | .env, config files |
| Test files | โ | Existing tests |
| Dependencies | โ | node_modules, venv |
| Build artifacts | โ | dist, build |
| Git history | โ | Full history preserved |
Snapshot Metadata¶
Each snapshot includes:
{
"snapshot_id": "snap-20240118-143022",
"created_at": "2024-01-18T14:30:22Z",
"method": "git_worktree",
"base_commit": "abc123def",
"files_count": 142,
"total_size_bytes": 2458624
}
Change Tracking¶
During QE, all changes are tracked:
File Changes¶
{
"file_path": "src/api/users.py",
"change_type": "modified",
"original_hash": "sha256:abc...",
"modified_hash": "sha256:def...",
"diff_lines": 15,
"timestamp": "2024-01-18T14:32:45Z"
}
Change Types¶
| Type | Description |
|---|---|
created | New file added |
modified | Existing file changed |
deleted | File removed |
renamed | File moved/renamed |
Git Guard¶
During QE sessions, dangerous Git operations are blocked:
Blocked Operations¶
| Operation | Status | Reason |
|---|---|---|
git commit | Blocked | Prevents accidental commits |
git push | Blocked | Prevents pushing test changes |
git checkout | Blocked | Prevents branch switching |
git reset --hard | Blocked | Prevents destructive resets |
Allowed Operations¶
| Operation | Status | Purpose |
|---|---|---|
git status | Allowed | View changes |
git diff | Allowed | Inspect modifications |
git log | Allowed | View history |
git show | Allowed | View commits |
Git Guard Configuration¶
# superqode.yaml
qe:
git_guard:
enabled: true
allow_status: true
allow_diff: true
block_commit: true
block_push: true
Revert Mechanism¶
Automatic Revert¶
After every QE session:
- Change Detection: All modifications identified
- Artifact Extraction: Patches and tests saved
- State Restoration: Original files restored
- Verification: Hash comparison confirms restore
Manual Revert¶
If needed, manually trigger revert:
Revert Verification¶
SuperQode verifies the revert succeeded:
โ Revert Complete
Files restored: 12
Original hash: sha256:abc123...
Current hash: sha256:abc123...
Status: Verified
Artifact Preservation¶
While changes are reverted, artifacts are preserved:
Artifact Location¶
.superqode/qe-artifacts/
โโโ manifest.json
โโโ qr/
โ โโโ qr-<date>-<session>.md
โ โโโ qr-<date>-<session>.json
โโโ patches/
โ โโโ ... # Suggested patch files (when available)
โโโ generated-tests/
โ โโโ ... # Generated tests (when available)
โโโ logs/
โ โโโ ... # Execution logs / work logs (if enabled)
โโโ evidence/
โโโ ... # Screenshots, traces, captured outputs
Patch Format¶
Patches are in unified diff format:
--- a/src/api/users.py
+++ b/src/api/users.py
@@ -42,7 +42,7 @@ def search_users(query: str):
- sql = f"SELECT * FROM users WHERE name LIKE '%{query}%'"
+ sql = "SELECT * FROM users WHERE name LIKE ?"
+ params = (f"%{query}%",)
cursor.execute(sql, params)
Applying Patches¶
After review, apply patches manually:
# Preview the patch
cat .superqode/qe-artifacts/patches/fix-sql-injection.patch
# Apply the patch
git apply .superqode/qe-artifacts/patches/fix-sql-injection.patch
# Or use SuperQode
superqode suggestions apply fix-sql-injection
Session Recovery¶
If a session is interrupted:
Automatic Recovery¶
SuperQode detects incomplete sessions:
WARNING: Incomplete QE session detected
Session: qe-session-20240118-143022
Status: interrupted
Options:
1. Resume session
2. Revert and discard
3. View changes before deciding
Choice: _
Manual Recovery¶
# List sessions
superqe status --all
# Recover specific session
superqe recover qe-session-20240118-143022
# Force clean (discard session)
superqe clean --force
Workspace Configuration¶
Default Settings¶
# superqode.yaml
qe:
workspace:
method: auto # auto, git_worktree, snapshot
location: .superqode/sandbox
preserve_artifacts: true
cleanup_on_success: true
cleanup_on_failure: false
Method Selection¶
| Method | When Used |
|---|---|
auto | Snapshot isolation unless worktree is explicitly enabled |
git_worktree | Use worktree isolation (Git repos only) |
snapshot | Non-Git directory |
Custom Location¶
Best Practices¶
1. Use Git Repositories¶
Git worktree isolation is the most efficient:
2. Configure Ignores¶
Exclude large files from snapshots:
3. Clean Up Artifacts¶
Periodically clean old artifacts:
4. Verify Reverts¶
After critical sessions, verify the revert:
Troubleshooting¶
Session didn't revert properly
Snapshot taking too long
Exclude large directories:
Git worktree conflicts
Advanced Workspace Features¶
Git Worktree Manager¶
Detailed worktree-based isolation for Git repositories.
Benefits¶
- Preserves build caches:
node_modules/,target/,__pycache__/shared between worktrees - Fast setup: Git handles copying efficiently (copy-on-write)
- Multiple parallel sessions: Create multiple worktrees for parallel QE
- Commit testing: Test specific commits without affecting working tree
- Native Git integration: Works seamlessly with Git workflows
Worktree Location¶
Worktrees stored in: ~/.superqode/working/{repo-name}/qe/{session-id}
- Isolated from main repository
- Session-specific directories
- Automatic cleanup after QE
Creating Worktrees¶
from superqode.workspace import GitWorktreeManager
manager = GitWorktreeManager(project_root)
worktree = await manager.create_qe_worktree(
session_id="qe-20250115",
base_ref="HEAD",
copy_uncommitted=True,
keep_gitignored=True
)
Worktree Options¶
base_ref: Git ref (commit, branch, tag) to base worktree oncopy_uncommitted: Copy uncommitted changes to worktreekeep_gitignored: Preserve gitignored files (build caches)
Removing Worktrees¶
Automatically cleaned up after QE session completion.
Git Snapshot Manager¶
Git-based snapshots for robust file state tracking.
How It Works¶
Uses Git's object database to store file states:
- Efficient storage: Git's delta compression
- Atomic operations: All-or-nothing snapshot creation
- Full history: Track snapshot lineage
- Diffing capabilities: Compare any two snapshots
Creating Snapshots¶
from superqode.workspace import GitSnapshotManager
manager = GitSnapshotManager(project_root)
snapshot_id = await manager.create_snapshot(
message="Before QE session",
files=None # None = all tracked files
)
Snapshot Format¶
{
"id": "snap-20250115-143022-abc123",
"timestamp": "2025-01-15T14:30:22",
"message": "Before QE session",
"file_hashes": {
"src/api/users.py": "sha256:abc...",
"src/api/orders.py": "sha256:def..."
},
"parent_id": null
}
Getting Changes¶
Restoring Snapshots¶
QE Coordinator¶
Session coordination with locking and epoch system.
Locking System¶
Prevents concurrent deep QE runs:
- Deep QE: Exclusive lock (blocks other sessions)
- Quick Scan: Shared lock (multiple can run)
- Automatic cleanup: Stale locks from dead processes removed
Acquiring Locks¶
from superqode.workspace import QECoordinator
coordinator = QECoordinator(project_root)
lock = coordinator.acquire_lock(
session_id="qe-20250115",
mode="deep", # or "quick"
intent="Security audit"
)
if lock is None:
print("Another session is running")
return
try:
# Run QE...
finally:
coordinator.release_lock(lock)
Context Manager¶
with coordinator.session("qe-20250115", mode="deep") as lock:
if lock:
# Run QE...
# Lock automatically released
Epoch System¶
Detects if code changed during QE:
# Check if results are stale
if coordinator.is_result_stale(lock):
print("Warning: Code changed during QE")
# Bump epoch when files change
coordinator.bump_snapshot_epoch()
Epoch increments when: - Files are modified - Git operations occur - External changes detected
Diff Tracker¶
Track file changes for patch generation.
Capturing Baselines¶
from superqode.workspace import DiffTracker
tracker = DiffTracker(project_root)
# Before modifying a file
tracker.capture_baseline(Path("src/api/users.py"))
# ... agent modifies file ...
# Get unified diff
patch = tracker.get_unified_diff()
Change Types¶
| Type | Description |
|---|---|
ADD | File created |
DELETE | File removed |
MODIFY | File content changed |
RENAME | File moved/renamed |
Generating Patches¶
# Get unified diff (Git format)
patch = tracker.get_unified_diff()
# Get summary
summary = tracker.get_changes_summary()
# {
# "total_changes": 5,
# "additions": 1,
# "deletions": 0,
# "modifications": 3,
# "renames": 1,
# ...
# }
Patch Format¶
Unified diff format compatible with git apply:
--- a/src/api/users.py
+++ b/src/api/users.py
@@ -42,7 +42,9 @@ def search_users(query: str):
- sql = f"SELECT * FROM users WHERE name LIKE '%{query}%'"
+ sql = "SELECT * FROM users WHERE name LIKE ?"
+ params = (f"%{query}%",)
cursor.execute(sql, params)
Directory Watcher¶
Real-time file system monitoring.
Watchdog Integration¶
Uses watchdog library for efficient monitoring:
- Native OS events: Uses platform-specific file system events
- Debouncing: Combines rapid successive changes
- Pattern filtering: Ignore patterns (
.git,node_modules, etc.) - Async support: Async/await compatible
Basic Usage¶
from superqode.workspace import DirectoryWatcher
watcher = DirectoryWatcher(project_root)
@watcher.on_change
def handle_change(change: FileChange):
print(f"{change.change_type}: {change.path}")
watcher.start()
# ... monitoring active ...
watcher.stop()
Async Usage¶
async def monitor_changes():
watcher = DirectoryWatcher(project_root)
async for change in watcher.async_changes():
print(f"{change.change_type}: {change.path}")
Configuration¶
from superqode.workspace import WatcherConfig
config = WatcherConfig(
ignore_patterns=[
"*.pyc",
"__pycache__",
".git/*",
"node_modules/*"
],
watch_extensions=[".py", ".ts", ".js"],
debounce_interval=0.5, # seconds
recursive=True
)
watcher = DirectoryWatcher(project_root, config=config)
Change Events¶
| Event | Description |
|---|---|
CREATED | File/directory created |
MODIFIED | File modified |
DELETED | File/directory deleted |
MOVED | File/directory moved/renamed |
Git Guard Details¶
Comprehensive protection against Git operations.
Safe Commands¶
Read-only operations allowed:
# Allowed
git status
git log
git diff
git show
git branch -l # Listing only
git remote -v # Viewing only
Blocked Commands¶
Write operations blocked:
Command Analysis¶
Detailed analysis of Git commands:
from superqode.workspace import GitGuard
guard = GitGuard()
analysis = guard.analyze("git commit -m 'test'")
# Returns: GitCommandAnalysis with reason and suggestion
if analysis.is_blocked:
print(f"Blocked: {analysis.reason}")
print(f"Suggestion: {analysis.suggestion}")
Block Reasons¶
Human-readable reasons for blocking:
- commit: "Commits would permanently alter repository history"
- push: "Push would send changes to remote repository"
- reset: "Reset could lose tracked changes"
Safe Variants¶
Some commands have safe variants:
# Blocked: git branch new-feature
# Allowed: git branch -l (listing)
# Blocked: git tag v1.0
# Allowed: git tag -l (listing)
Integration¶
All workspace features work together:
- Coordinator manages session locking
- Git Worktree creates isolated workspace
- Git Snapshot captures initial state
- Diff Tracker monitors changes
- Directory Watcher provides real-time updates
- Git Guard prevents dangerous operations
- Snapshot Manager enables revert
Best Practices¶
1. Use Git Worktree for Git Repos¶
Most efficient for Git repositories:
2. Monitor with Watchers¶
Enable real-time monitoring:
3. Use Coordinator for Safety¶
Always coordinate sessions:
4. Check Stale Results¶
Verify results aren't stale:
Troubleshooting¶
Worktree Conflicts¶
Symptom: "Worktree already exists"
Solution:
Stale Locks¶
Symptom: Lock persists after session ends
Solution: Coordinator auto-cleans stale locks, but you can manually:
Watcher Not Working¶
Symptom: Changes not detected
Solution: Ensure watchdog installed:
Next Steps¶
- QE Roles - Understanding testing roles
- Quality Reports - Report format and structure
- Allow Suggestions - Fix demonstration workflow