Skip to content

OA07.1 PR-7 Worktree Runtime Boundary Plan

Purpose: turn the current placeholder workspace/ package into a maintained git-backed workspace boundary that lands the runtime bootstrap MVP in ADR-OA07 and ADR-OA07.1: real managed worktrees, mutable-step execution in the worktree root, and ROLLBACK(pre_run) against recorded base state.

Scope

This note covers PR-7 from TODO.md:

  • implement a real maintained workspace service,
  • create a managed branch + worktree from a committed base ref,
  • record pre-run workspace context including base_ref and base_sha,
  • run RUN_AGENT and RUN_VALIDATION against the worktree root,
  • make ROLLBACK(pre_run) restore the managed worktree to that recorded base state,
  • persist workspace context as canonical run evidence.

Out of scope for this PR:

  • commit/push/PR automation,
  • pre_step rollback and named checkpoints.

Current Code Reality

The maintained workspace layer is still a stub:

  • src/tnh_scholar/agent_orchestration/workspace/models.py only has RollbackTarget and a thin WorkspaceSnapshot.
  • src/tnh_scholar/agent_orchestration/workspace/protocols.py exposes capture_pre_run(run_id) -> None and rollback_pre_run() -> None, which is too narrow for managed worktree creation.
  • src/tnh_scholar/agent_orchestration/workspace/service.py contains only NullWorkspaceService.

The kernel already depends on the workspace service at the right lifecycle moments:

  • src/tnh_scholar/agent_orchestration/kernel/service.py:135 calls capture_pre_run(),
  • src/tnh_scholar/agent_orchestration/kernel/service.py:417 calls rollback_pre_run(),
  • src/tnh_scholar/agent_orchestration/kernel/service.py:767 uses snapshot() for runtime policy guards,
  • src/tnh_scholar/agent_orchestration/kernel/provenance.py:187 persists workspace snapshot and diff artifacts.

That means PR-7 can stay reasonably small, but it cannot remain fully isolated to workspace/. The protocol must be widened so the kernel can receive and persist real workspace context.

Proposed Design

1. Add a typed workspace context model

Introduce a canonical model such as WorkspaceContext with at least:

  • repo_root: Path
  • worktree_path: Path
  • branch_name: str
  • base_ref: str
  • base_sha: str

Recommended additions:

  • head_sha: str | None
  • run_id: str
  • created_at: datetime | None

This is the minimum state needed to:

  • reconstruct the mutable execution boundary,
  • enforce protected-branch rules accurately,
  • restore pre_run,
  • persist reviewable provenance.

2. Split workspace setup from workspace observation

The current capture_pre_run(run_id) method mixes two concerns:

  • creating the operational workspace boundary,
  • capturing rollback state.

For PR-7 the protocol should instead make setup explicit and center the workspace API on WorkspaceContext, not on the run-artifact directory. One reasonable shape:

def prepare_pre_run(*, run_id: str) -> WorkspaceContext: ...
def rollback_pre_run() -> WorkspaceContext: ...
def current_context() -> WorkspaceContext | None: ...
def snapshot() -> WorkspaceSnapshot: ...
def diff_summary() -> str: ...

Equivalent naming is fine, but the important contract change is:

  • pre-run setup must return structured context,
  • rollback must operate on stored context rather than implicit local state only.

3. Keep NullWorkspaceService, add GitWorktreeWorkspaceService

NullWorkspaceService should remain for tests and explicit non-operational contexts.

Add a maintained git-backed implementation that:

  1. Resolves a committed base ref from configuration.
  2. Records base_sha via git rev-parse.
  3. Creates a conductor-managed branch name for the run.
  4. Creates a dedicated git worktree under a stable workspace root.
  5. Stores the resulting WorkspaceContext in-memory for the run lifecycle.
  6. On rollback, discards and recreates that worktree at base_sha.

PR-7 should prefer a simple deterministic branch naming scheme over configurability:

  • example: tnh/run-<run_id>

Branch naming can move to config later if needed.

4. Persist workspace context as canonical evidence

PR-7 should add a typed artifact payload for workspace context rather than burying this state in ad hoc JSON.

Preferred options:

  • extend src/tnh_scholar/agent_orchestration/run_artifacts/models.py with a dedicated WorkspaceContextArtifact,
  • add a matching canonical artifact role such as workspace_context.

This artifact should be written once during run setup and reused by later review/debugging flows.

5. Include Minimal Mutable-Step Rewiring In PR-7

PR-7 should update src/tnh_scholar/agent_orchestration/kernel/service.py:261 and src/tnh_scholar/agent_orchestration/kernel/service.py:294 so RUN_AGENT and RUN_VALIDATION execute against the worktree root. This is the smallest aligned seam:

  • the workspace service becomes real,
  • mutable execution actually moves into the worktree,
  • artifact/manifests/events remain in the canonical run directory,
  • PR-8 can focus on the headless entry point rather than another protocol break.

Expected File Touches

Primary:

  • src/tnh_scholar/agent_orchestration/workspace/models.py
  • src/tnh_scholar/agent_orchestration/workspace/protocols.py
  • src/tnh_scholar/agent_orchestration/workspace/service.py

Kernel/provenance/run-artifact touches:

  • src/tnh_scholar/agent_orchestration/kernel/service.py
  • src/tnh_scholar/agent_orchestration/kernel/provenance.py
  • src/tnh_scholar/agent_orchestration/run_artifacts/models.py
  • src/tnh_scholar/agent_orchestration/run_artifacts/protocols.py
  • src/tnh_scholar/agent_orchestration/run_artifacts/filesystem_store.py

Tests:

  • tests/agent_orchestration/test_oa07_execution_validation_kernel.py
  • likely a new focused workspace service test module under /tests/agent_orchestration/

Testing Plan

Minimum tests for PR-7:

  1. Workspace service creates a worktree from a committed base ref and records base_sha.
  2. RUN_AGENT and RUN_VALIDATION receive the worktree root as working_directory.
  3. Rollback discards and recreates the worktree at the recorded base_sha.
  4. Kernel run setup persists workspace context as canonical evidence.
  5. Protected-branch guard still works, now against real workspace context.

Tests should use temporary local git repositories rather than mocking git entirely. The feature is mostly git lifecycle, so fake-only tests would miss the important failure modes.

Risks To Watch

  • Git subprocess surface can sprawl quickly. Keep one small helper layer rather than scattering raw command assembly across the service.
  • If the protocol returns too little context now, PR-8 will immediately need another breaking change.
  • If working_directory is not moved to the worktree in PR-7, the docs and implementation will still disagree after the slice lands.

Exit Criteria

PR-7 is done when:

  • the maintained runtime can create a real managed worktree for a run,
  • the workspace service records repo_root, worktree_path, branch_name, base_ref, and base_sha,
  • RUN_AGENT and RUN_VALIDATION execute against the worktree root,
  • ROLLBACK(pre_run) restores that worktree to recorded base state by discard/recreate,
  • workspace context is persisted as canonical run evidence,
  • the kernel and tests can use GitWorktreeWorkspaceService as the forward-path maintained implementation.