Compare commits

...

1 Commits

Author SHA1 Message Date
HAL9000 d21ccdd9f6 docs: add git worktree sandbox guide, extend sandbox/plan-apply/context-tiers refs
CI / benchmark-publish (pull_request) Has been skipped
CI / push-validation (pull_request) Successful in 18s
CI / build (pull_request) Successful in 22s
CI / lint (pull_request) Successful in 25s
CI / helm (pull_request) Successful in 24s
CI / quality (pull_request) Successful in 40s
CI / typecheck (pull_request) Successful in 1m9s
CI / security (pull_request) Successful in 1m15s
CI / e2e_tests (pull_request) Successful in 3m9s
CI / integration_tests (pull_request) Successful in 4m13s
CI / unit_tests (pull_request) Successful in 5m10s
CI / docker (pull_request) Successful in 1m18s
CI / coverage (pull_request) Successful in 11m0s
CI / status-check (pull_request) Successful in 4s
CI / benchmark-regression (pull_request) Successful in 58m35s
- docs/modules/git-worktree-sandbox.md: new module guide for GitWorktreeSandbox
  (PR #5998) covering execute/apply phases, non-git fallback, conflict handling,
  and context hydration integration
- docs/reference/sandbox.md: add Strategy Selection section and Git Worktree
  Sandbox section documenting execute/apply phases and non-git fallback
- docs/reference/plan_apply.md: add Git Worktree Merge-Based Apply section with
  CLI output panels and fallback behaviour; update intro to reference PR #5998
- docs/reference/context_tiers.md: add Context Tier Hydration section documenting
  ContextTierHydrator (PR #4219), hydration algorithm, exclusion rules,
  configuration parameters, and LLMExecuteActor integration
- mkdocs.yml: add Git Worktree Sandbox to Modules nav
2026-04-10 18:33:15 +00:00
5 changed files with 288 additions and 2 deletions
+147
View File
@@ -0,0 +1,147 @@
# Git Worktree Sandbox
The **Git Worktree Sandbox** provides git-native isolation for plan execution
on `git-checkout` resources. Introduced in v3.5.0 (PR #5998), it replaces
the previous flat `shutil.copy2` apply with a proper `git merge` workflow,
giving users a clean git history and conflict-detection on apply.
## Why Git Worktrees?
A git worktree is a linked working tree that shares the same git object
database as the main repository but has its own checked-out branch and
working directory. This means:
- **Isolation**: LLM-generated changes are committed to a dedicated branch
(`cleveragents/plan-<plan_id>`) without touching the main working tree.
- **Auditability**: Every plan execution produces a real git commit with a
diff you can inspect before merging.
- **Conflict detection**: `git merge` surfaces conflicts that flat file copy
would silently overwrite.
- **Rollback**: The worktree branch can be deleted without affecting the
main branch.
## Architecture
```
agents plan execute <plan_id>
GitWorktreeSandbox.create()
├── git worktree add /tmp/ca-wt-<id> -b cleveragents/plan-<plan_id>
LLMExecuteActor writes files to worktree path
git commit -m "plan: <plan_id> execute output" (inside worktree)
sandbox_ref stored → plan record
agents plan apply <plan_id>
GitWorktreeSandbox.commit()
├── git merge --no-ff cleveragents/plan-<plan_id>
├── Display Apply Summary panel
├── Display Sandbox Cleanup panel
├── Display Next Steps panel
└── ✓ OK Changes applied
```
## Execute Phase
When `agents plan execute <plan_id>` runs for a plan linked to a
`git-checkout` resource:
1. `GitWorktreeSandbox.create()` is called with the resource's root path.
2. A temporary directory is created (e.g. `/tmp/ca-wt-<ulid>`).
3. `git worktree add <tmp_dir> -b cleveragents/plan-<plan_id>` creates the
isolated branch.
4. The `LLMExecuteActor` writes all generated files into `<tmp_dir>`.
5. Changes are committed: `git commit -m "plan: <plan_id> execute output"`.
6. The worktree path is stored as a sandbox reference in the plan record.
## Apply Phase
When `agents plan apply <plan_id>` runs:
1. The sandbox reference is resolved to the worktree path.
2. `git merge --no-ff cleveragents/plan-<plan_id>` is run in the main
repository.
3. On success, the CLI renders:
```
╭─ Apply Summary ─────────────────────────────────────────────╮
│ Plan: 01HXYZ... │
│ Artifacts: 3 files │
│ Changes: +42 / -7 │
│ Project: my-project │
│ Applied at: 2026-04-10T14:23:00Z │
╰─────────────────────────────────────────────────────────────╯
╭─ Sandbox Cleanup ───────────────────────────────────────────╮
│ ✓ Worktree removed │
│ ✓ Branch merged to main │
╰─────────────────────────────────────────────────────────────╯
╭─ Next Steps ────────────────────────────────────────────────╮
│ Review changes: git diff HEAD~1 │
│ Commit if satisfied: git commit --amend │
╰─────────────────────────────────────────────────────────────╯
✓ OK Changes applied
```
4. The worktree is removed: `git worktree remove <tmp_dir> --force`.
5. The worktree branch is deleted: `git branch -d cleveragents/plan-<plan_id>`.
## Non-Git Fallback
If the linked resource is not a git repository (e.g. a plain directory
resource), the sandbox falls back to `CopyOnWriteSandbox`:
- Files are copied from the sandbox directory to the project directory using
`shutil.copy2`.
- Path traversal guards prevent writes outside the project root.
- Protected directories (`.git`, `.cleveragents`, `node_modules`,
`__pycache__`) are skipped.
## Merge Conflict Handling
If `git merge` encounters conflicts:
1. The plan transitions to `ERRORED` processing state.
2. `error_message` is set to `"Merge failed: <details>"`.
3. `error_details` includes `merge_conflict` and `sandbox_rollback: "pending"`.
**Recovery steps:**
```bash
# Review the conflict details
agents plan errors <plan_id>
# Manually resolve conflicts in the worktree branch
git checkout cleveragents/plan-<plan_id>
# ... resolve conflicts ...
git commit -m "resolve: manual conflict resolution"
# Re-apply
agents plan apply <plan_id>
```
## Context Hydration
Before the LLM writes files to the worktree, the `ContextTierHydrator`
pre-populates the `ContextTierService` with the project's source files.
This ensures the LLM has full file context during execution.
See [Context Tiers Reference](../reference/context_tiers.md) for details on
the hydration pipeline.
## Related Documentation
- [Sandbox Infrastructure Reference](../reference/sandbox.md)
- [Plan Diff & Apply Reference](../reference/plan_apply.md)
- [Context Tiers Reference](../reference/context_tiers.md)
- [ADR-015: Sandbox & Checkpoint](../adr/ADR-015-sandbox-and-checkpoint.md)
+55
View File
@@ -107,3 +107,58 @@ from cleveragents.application.container import get_container
container = get_container()
svc = container.context_tier_service()
```
## Context Tier Hydration
Prior to v3.4.0 (fix in PR #4219), the `ContextTierService` started empty on
every CLI invocation, causing the LLM to receive zero file context during plan
execution. The **context tier hydrator** resolves this by pre-populating the
tier service from linked project resources before context assembly runs.
### How Hydration Works
The `ContextTierHydrator` is invoked automatically inside
`LLMExecuteActor.execute()` before context assembly:
1. Resolves the plan's linked project resources via `ProjectRepository`.
2. For each `git-checkout` resource: runs `git ls-files` to enumerate tracked
files.
3. For other directory resources: walks the filesystem with `os.walk`.
4. Reads each file (up to `max_file_size`, default **256 KB**) and creates a
`TieredFragment` in the **hot** tier.
5. Stops when the total budget (`max_total_size`, default **10 MB**) is
reached.
### Exclusion Rules
The hydrator skips:
- Binary files (detected by null-byte scan)
- Files exceeding `max_file_size` (256 KB)
- Directories: `.git`, `node_modules`, `__pycache__`, `.cleveragents`
### Configuration
| Parameter | Default | Description |
|-----------|---------|-------------|
| `max_file_size` | 262144 (256 KB) | Maximum size of a single file to hydrate |
| `max_total_size` | 10485760 (10 MB) | Total budget across all hydrated files |
### Integration with LLMExecuteActor
```python
# Pseudocode — hydration is automatic, no manual call needed
class LLMExecuteActor:
def execute(self, plan_id, ...):
hydrator = ContextTierHydrator(
tier_service=self.tier_service,
project_repository=self.project_repository,
resource_registry=self.resource_registry,
)
hydrator.hydrate(plan_id) # populates tier service
context = self.assembler.assemble(...) # now has file context
...
```
The hydrator is injected via constructor — no `get_container()` call is made
inside the actor, keeping it testable and DI-compliant.
+36 -2
View File
@@ -1,7 +1,8 @@
# Plan Diff & Apply Reference
This document describes the diff review and apply integration features
added in D0b.apply.
This document describes the diff review and apply integration features,
including the git worktree merge-based apply workflow introduced in v3.5.0
(PR #5998).
## CLI Commands
@@ -66,6 +67,39 @@ change list, and validation results.
## Apply Integration
### Git Worktree Merge-Based Apply
For plans linked to a git-checkout resource, `agents plan apply` uses a
git-native merge workflow instead of flat file copying:
1. **Execute phase** writes LLM output to an isolated git worktree branch
`cleveragents/plan-<plan_id>` (see [Sandbox Infrastructure](sandbox.md)).
2. **Apply phase** runs `git merge --no-ff` to merge the worktree branch
into the project's current branch.
3. The CLI displays spec-aligned output panels:
```
╭─ Apply Summary ─────────────────────────────────────────────╮
│ Plan: 01HXYZ... │
│ Artifacts: 3 files │
│ Changes: +42 / -7 │
│ Project: my-project │
│ Applied at: 2026-04-10T14:23:00Z │
╰─────────────────────────────────────────────────────────────╯
╭─ Sandbox Cleanup ───────────────────────────────────────────╮
│ ✓ Worktree removed │
│ ✓ Branch merged to main │
╰─────────────────────────────────────────────────────────────╯
╭─ Next Steps ────────────────────────────────────────────────╮
│ Review changes: git diff HEAD~1 │
│ Commit if satisfied: git commit --amend │
╰─────────────────────────────────────────────────────────────╯
✓ OK Changes applied
```
For non-git projects, apply falls back to flat file copy (`shutil.copy2`)
from the sandbox directory to the project directory.
### Empty ChangeSet Guard
The apply pipeline checks whether the ChangeSet has any entries before
+49
View File
@@ -15,6 +15,55 @@ committed.
| `copy_on_write` | `CopyOnWriteSandbox` | Filesystem copy for isolation |
| `git_worktree` | `GitWorktreeSandbox` | Git worktree for git repositories |
### Strategy Selection
The sandbox strategy is chosen automatically based on the resource type:
- **Git repositories** (`git-checkout` resources): `git_worktree` strategy is used.
The plan's changes are committed to an isolated branch
`cleveragents/plan-<plan_id>` inside a git worktree, keeping the working
tree clean until apply.
- **Non-git directories**: `copy_on_write` strategy is used. The resource
directory is copied to a temporary location; changes are written there and
copied back on apply.
- **No isolation needed**: `none` strategy writes directly to the resource.
## Git Worktree Sandbox
The `GitWorktreeSandbox` provides full git-native isolation for plan execution
on git-checkout resources. It was introduced in v3.5.0 (PR #5998) to replace
flat `shutil.copy2` apply with a proper `git merge` workflow.
### Execute Phase
1. A git worktree is created at a temporary path for the plan's linked
git-checkout resource.
2. A new branch `cleveragents/plan-<plan_id>` is checked out inside the
worktree.
3. LLM-generated file output is written to the worktree directory.
4. Changes are committed to the worktree branch — **no merge yet**.
5. The worktree path is stored as a sandbox reference for the apply phase.
### Apply Phase
1. The worktree branch is merged into the project's current branch via
`git merge --no-ff`.
2. The CLI displays spec-aligned output panels:
- **Apply Summary**: Plan ID, artifact count, insertions/deletions,
project name, applied-at timestamp.
- **Sandbox Cleanup**: worktree removed, branch merged to main.
- **Next Steps**: review `git diff`, commit changes.
- **Footer**: `✓ OK Changes applied`
3. The worktree is removed after a successful merge.
### Non-Git Fallback
If the linked resource is not a git repository, the sandbox falls back to
the `copy_on_write` strategy: files are copied from the sandbox directory
to the project directory using `shutil.copy2`. Path traversal guards
prevent writes outside the project root. Protected directories (`.git`,
`.cleveragents`, `node_modules`) are skipped.
## Sandbox Lifecycle
```
+1
View File
@@ -27,6 +27,7 @@ nav:
- Shell Safety: modules/shell-safety.md
- UKO Provenance Tracking: modules/uko-provenance.md
- Invariant Reconciliation: modules/invariant-reconciliation.md
- Git Worktree Sandbox: modules/git-worktree-sandbox.md
- Development:
- CI/CD Pipeline: development/ci-cd.md
- Quality Automation: development/quality-automation.md