Skip to content
Merged
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ jobs:
- run: uv run --no-sync python tests/artifact_test.py
- run: uv run --python 3.13 --isolated --no-project --with dist/*.whl tests/smoke_test.py
- run: uv run --python 3.13 --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
- run: uv run --python 3.13 --isolated --no-project --with dist/*.whl tests/worktree_artifact_test.py
- run: uv run --python 3.13 --isolated --no-project --with dist/*.tar.gz tests/worktree_artifact_test.py

tests:
strategy:
Expand Down
55 changes: 55 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,61 @@ All notable changes follow Keep a Changelog. Versions follow Semantic Versioning

## [Unreleased]

## [0.16.0-alpha.0] - 2026-07-02

### Added

- Immutable host-owned `WorktreeProfile` and bounded lease/candidate/adoption state models with
separate repository and state roots, exact implementation profiles, path prefixes, and hard
tree/content/cleanup limits.
- Byte-safe fixed-argv Git boundary for exact clean repository admission, NUL-delimited index
pointers, raw object reads, locked detached no-checkout Worktrees, administrative identity,
bounded process lifecycle, and verified cleanup.
- Raw index materialization for regular `100644`/`100755` files plus immutable base manifests,
successful structured-mutation hash chains, complete-tree reconciliation, bounded diffs,
content-addressed candidate blobs, and canonical manifest hashes.
- `delegate_implementation` with model-visible `task/reason` only, fresh non-interactive
implementation children, exact SUBAGENT-provenance Read/Search/Write/Edit Tools, optional
host-fixed tests, independent snapshot, and cancellation-safe finalization.
- Separate high-risk `adopt_subagent_candidate` and `discard_subagent_candidate` Tools with
verified previews, ready/applying claims, clean-base/path/hash revalidation, canonical apply,
rollback, interrupted-state recovery, and uncertain-state evidence.
- Real-Git implementation/adoption integration and adversarial tests for hostile paths, aliases,
links, races, tampering, output/process limits, lease exhaustion, cancellation, cleanup, and
rollback failure.
- M6b architecture, threat-model, ADR, learning, and resume documentation.

### Changed

- Public package exports and installed-package smoke now include the governed Worktree profile,
runner, candidate, adoption, and discard APIs.
- M6a analysis profiles remain read-only; implementation is a separate profile and parent Tool
rather than a capability upgrade.

### Security

- Child completion cannot mutate or authorize mutation of the parent checkout. Candidate adoption
requires a second Policy/approval decision and exact original clean `HEAD`.
- Ordinary checkout is avoided during lease population. Only bounded regular files from verified
Git index/object bytes are materialized; ignored/untracked files, links, gitlinks, aliases,
unsupported modes, and over-budget trees fail closed.
- Ready candidates come from independent full-tree/base/ledger reconciliation and verified stored
blobs, not child summaries or bounded diff text.
- Adoption conflicts write no candidate files. Partial failures are either proven rolled back or
persisted as uncertain; interrupted applying states are classified as all-before, all-after, or
mixed before reuse.
- Worktree separation is not OS isolation, and multi-file adoption is not power-loss atomic,
distributed, exactly-once, or a database two-phase commit.

### Verification

- Local Python 3.12.13 and 3.13.14 each passed 1184 tests with 13 platform/privilege skips.
Python 3.13 package branch coverage was 88.49%, above the 85% gate. Ruff format/check, strict
Pyright, Bandit, and locked runtime dependency audit passed.
- Final reproducible artifact hashes, isolated smoke evidence, PR/main CI run IDs, tag commit,
release URL, and remote asset digests will be recorded after the remaining release gates
complete.

## [0.15.0-alpha.0] - 2026-07-02

### Added
Expand Down
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

A framework-light, provider-neutral coding agent built from first principles.

> Status: pre-alpha. M6a provides a provider-neutral Agent Core, Anthropic/OpenAI-compatible
> Status: pre-alpha. M6b provides a provider-neutral Agent Core, Anthropic/OpenAI-compatible
> adapters, a schema-validating Tool Registry, a cross-platform Workspace boundary, bounded
> Read/Search, conflict-aware Write/Edit, policy-governed argv command execution, and deterministic
> context admission, hardened read-only Git evidence, governed Pytest diagnostics, versioned SQLite
> Session/Trace persistence, fail-closed Checkpoint/Resume, and a host-controlled bounded Repair
> loop, provenance-aware lazy Skills, deterministic host-registered Tool Hooks, and host-pinned
> local MCP stdio Tools, and bounded host-profiled read-only analysis Subagents. OS sandboxing,
> local MCP stdio Tools, bounded host-profiled read-only analysis Subagents, and host-managed
> Worktree implementation candidates with separately approved adoption. OS sandboxing,
> shell-string execution, project-provided executable Hooks, automatic Repair resume, remote
> HTTP/OAuth MCP, write-capable Subagents/Worktrees, and live-provider CI are not implemented.
> HTTP/OAuth MCP, automatic commit/merge/push, and live-provider CI are not implemented.

## Requirements

Expand Down Expand Up @@ -257,6 +258,33 @@ In-process context isolation is not an OS sandbox. M6a cannot write, run command
Tools, open nested approval prompts, persist durable child traces, create Worktrees, or merge
changes. See `docs/architecture/governed-subagents.md`.

## Governed Worktree Candidates

M6b adds one separately governed implementation Tool. The parent model supplies only `task` and
`reason`; the host pins the exact clean repository, external state root, Git executable, allowed
path prefixes, implementation profile, optional fixed tests, and resource limits.

The host creates a locked detached `--no-checkout` Worktree and materializes the exact Git index
from raw object bytes. A fresh non-interactive child may use only host-approved Read/Search/
Write/Edit and optional `run_tests` Tools with `TrustSource.SUBAGENT`. It cannot use Git, arbitrary
commands, MCP/network, recursive delegation, or parent approval.

After the child stops, the host independently reconciles the complete tree with the immutable base
manifest and mutation ledger. Ready candidates persist canonical manifests and content-addressed
blobs outside the repository; the temporary Worktree is then verified and removed. Child
completion never mutates the parent checkout.

`adopt_subagent_candidate` is a separate high-risk WRITE Tool and approval. It requires the
original clean `HEAD`, revalidates every path/hash before the first replacement, applies only the
verified additions/modifications, and leaves them unstaged and uncommitted. Conflicts write
nothing; partial failures are either proven rolled back or marked uncertain for operator
recovery. `discard_subagent_candidate` accepts only a verified ready candidate.

Worktree path separation and rollback-aware adoption are not OS sandboxing or crash-atomic
transactions. M6b does not delete/rename files, run arbitrary commands, commit, merge, push, or
claim token/latency improvements. See
`docs/architecture/governed-worktree-candidates.md`.

## Documentation

- Product design: `docs/superpowers/specs/2026-06-29-mini-code-agent-design.md`
Expand All @@ -277,6 +305,7 @@ changes. See `docs/architecture/governed-subagents.md`.
- Governed Skills and Hooks: `docs/architecture/governed-extensions.md`
- Governed MCP stdio: `docs/architecture/governed-mcp.md`
- Governed analysis Subagents: `docs/architecture/governed-subagents.md`
- Governed Worktree candidates: `docs/architecture/governed-worktree-candidates.md`
- Threat model: `docs/architecture/threat-model.md`
- Provider protocol ADR: `docs/adr/0002-provider-wire-protocols.md`
- Workspace boundary ADR: `docs/adr/0003-workspace-boundary.md`
Expand All @@ -291,6 +320,7 @@ changes. See `docs/architecture/governed-subagents.md`.
- Inert Skills and host Hooks ADR: `docs/adr/0012-inert-skills-host-hooks.md`
- Host-pinned stdio MCP ADR: `docs/adr/0013-host-pinned-stdio-mcp.md`
- Bounded host-profiled Subagents ADR: `docs/adr/0014-bounded-host-profiled-subagents.md`
- Governed Worktree candidates ADR: `docs/adr/0015-governed-worktree-candidates.md`

## License

Expand Down
32 changes: 30 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,36 @@ text.
M6a children are in-process and are not an OS, process, memory, credential, or network sandbox.
Read-only Tool admission does not constrain malicious host-supplied Provider or Tool code.
Evidence hashes are not signatures, semantic validation, confidentiality, or durable audit.
M6a does not support child writes, command/network Tools, recursive delegation, Worktrees,
candidate adoption, merge, rollback, or exactly-once execution.
M6a remains read-only and does not support child writes, command/network Tools, recursive
delegation, Worktrees, candidate adoption, merge, rollback, or exactly-once execution.

M6b implementation delegation uses a separate immutable host profile. It pins an exact clean
repository and `HEAD`, an external non-overlapping state root, absolute Git executable, allowed
path prefixes, implementation Tool set, and hard tree/candidate/cleanup limits. The host creates
a locked detached no-checkout Worktree and materializes only regular `100644`/`100755` index
entries from raw Git object bytes. Ignored/untracked files, links, gitlinks, unsupported modes,
case aliases, and over-budget trees do not enter the lease.

Implementation children are fresh, non-interactive, and limited to SUBAGENT-provenance
Read/Search/Write/Edit plus optional host-fixed tests. They receive no Git, arbitrary command,
network, MCP, recursive delegation, deletion, rename, or parent approval authority. Successful
structured mutations form a hash-chained ledger, but candidate readiness is decided by an
independent complete-tree reconciliation against the immutable base manifest, ledger, path
allowlist, modes, content hashes, and resource limits.

Ready candidates persist canonical manifests and content-addressed blobs outside the repository.
Child completion never mutates the parent checkout. Adoption requires a separate high-risk WRITE
Tool, Policy decision, and approval. It revalidates the original clean `HEAD`, every path and
before-hash, applies only the verified candidate set, verifies after-hashes, and leaves changes
unstaged and uncommitted. Conflicts write no candidate files. Partial failure is either proven
rolled back or recorded as uncertain; interrupted applying state is classified before reuse.

Worktree path separation is not an OS, process, memory, credential, filesystem, or network
sandbox. In-process trusted Provider/Tool code retains the Agent process authority. Clean/hash
checks narrow but do not eliminate races with another process. Multi-file adoption is
process-serialized and rollback-aware, not power-loss atomic, distributed, exactly-once, or a
database two-phase commit. M6b does not delete/rename files, automatically adopt, stage, commit,
merge, push, reset, clean, or durably resume a child.

The project does not claim OS-level sandboxing unless an explicit sandbox backend is enabled and
documented. It also does not claim that Hook timeout stops work delegated to another thread or
Expand Down
98 changes: 98 additions & 0 deletions docs/adr/0015-governed-worktree-candidates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# ADR 0015: Separate Implementation Candidates from Parent Adoption

- Status: Accepted
- Date: 2026-07-02

## Context

M6a proved that an analysis child can use a fresh context, exact host-owned read-only Tools,
structured concurrency, and bounded evidence. Allowing that child to write directly into the
parent checkout would introduce a different authority boundary: repository identity, dirty user
work, concurrent mutations, partial filesystem failure, durable candidate state, cleanup, and
approval to publish a change.

A Git Worktree gives a separate checkout path but does not by itself provide a safe candidate
protocol. Ordinary checkout may execute conversion configuration. Child self-reported diffs
cannot be trusted. Automatically copying the result back would combine implementation and
publication authority and could overwrite user work.

## Decision

M6b uses a two-phase host-governed design.

First, `delegate_implementation` creates one host-managed locked detached no-checkout Worktree
lease from an exact clean `HEAD`. The host reads index pointers and raw Git objects with fixed,
byte-safe argv, materializes only regular files, and records an immutable base manifest.

The implementation child runs with a fresh context, exact SUBAGENT-provenance Read/Search/
Write/Edit Tools, optional host-fixed tests, non-interactive policy, and no Git, arbitrary command,
network, MCP, delegation, or parent approval. Successful structured mutations form a hash-chained
ledger.

After child completion, the host independently reconciles the complete lease tree, base manifest,
ledger, path allowlist, modes, content, and resource budgets. A verified candidate stores a
canonical manifest plus content-addressed blobs outside the repository. The Worktree is then
verified and removed. Rejected/no-change/cleanup-required outcomes remain distinct.

Second, `adopt_subagent_candidate` is a separate high-risk WRITE Tool and approval. It atomically
claims a ready candidate, revalidates exact repository/base/clean state and every destination,
stages same-directory temporary files, applies canonical replacements, and verifies the final
changed set and hashes. Conflicts write nothing. Partial failures roll back in reverse order and
become either proven rolled-back or uncertain. Interrupted applying state is classified as
all-before, all-after, or mixed. Discard is separately governed and only accepts ready candidates.

The initial release supports additions and modifications only. It never stages, commits, merges,
pushes, resets, or cleans the parent checkout.

## Consequences

Positive:

- child implementation cannot directly mutate the user's checkout;
- child completion and parent publication require separate Policy/approval decisions;
- materialization avoids working-tree checkout filters and uses an exact index snapshot;
- candidate authority comes from independent tree reconciliation and stored blobs, not model text;
- stale base, dirty parent, path drift, and hash drift fail before the first candidate write;
- process-local adoption has deterministic conflict, rollback, uncertain, and recovery states;
- failed child work can be cleaned without granting merge or Git authority;
- M6a's read-only profile and no-recursion guarantees remain unchanged.

Negative:

- Git object-format support is initially limited to SHA-1;
- only regular UTF-8 additions/modifications with supported modes can become ready;
- repository-sized materialization is bounded but can still cost time and disk space;
- Worktrees isolate paths, not process memory, credentials, filesystem, or network;
- cleanup and adoption are not crash-atomic or distributed transactions;
- an uncertain candidate requires operator inspection rather than automatic retry;
- the first release runs one implementation child per ToolCall and provides no automatic merge.

## Alternatives Rejected

- **Write directly in the parent checkout:** can collide with user changes and combines child
implementation with publication authority.
- **Create a branch and auto-merge:** grants Git mutation and merge authority without a separate
review/adoption decision.
- **Use ordinary `git worktree add` checkout:** may invoke configured working-tree conversions and
makes exact byte provenance harder to constrain.
- **Trust `git diff` or child summary as the candidate:** bounded presentation text is not an
adoption source of truth and can omit or misstate files.
- **Copy the complete Worktree back:** cannot enforce exact path, mode, content, or conflict
preconditions.
- **Adopt immediately after child success:** conflates model completion with verified readiness
and user approval.
- **Use only filesystem backups:** lacks a durable candidate state machine and clear recovery
classification.
- **Call adoption atomic:** multiple filesystem replacements cannot provide power-loss atomicity
without a stronger transactional storage design.
- **Give the child Git or arbitrary shell:** expands authority beyond bounded source changes and
host-fixed tests.
- **Run multiple implementation children into one candidate:** introduces ordering and conflict
semantics that are intentionally deferred.

## Follow-up

Future work may add deletion/rename, stronger process isolation, non-SHA-1 repositories, durable
operator recovery commands, candidate review UI, or multi-candidate composition. Each requires a
new threat analysis and must not weaken exact base/path/hash validation or separate adoption
approval.
Loading