Learn
Git as the human acceptance boundary
Why should autonomous execution and human acceptance remain separate?
A useful autonomous coding system should be able to perform substantial work without making that work authoritative merely because execution completed.
Git provides a durable handoff:
execution produces changes → versioned, reviewable output → human acceptance
Source control is treated here as the acceptance and handoff boundary: after work exists, before it becomes accepted project state.
Execution is not acceptance
Four moments that must stay distinct:
| Moment | What it means |
|---|---|
| Execution | Model and worker perform work inside their boundary |
| Completion | The run ends (successfully or not) |
| Handoff | The result exists as Git-reviewable output |
| Acceptance | A human decides whether it becomes accepted project state |
A successful run does not imply accepted work. A contained run does not imply accepted work. A technically correct change still requires the acceptance policy the Botanist or project chose.
Why Git is useful here
Git is valuable for autonomous work because it creates a reviewable state transition. Useful properties, without overstating the tool:
- versioned changes;
- inspectable diffs;
- attribution and provenance where configured;
- branch separation from accepted default state;
- reversibility of committed repository work;
- existing review workflows (including pull requests);
- an explicit acceptance point a human can own.
Git does not make execution safe. Git is not the runtime containment boundary. It is the handoff and acceptance surface after work has already happened under other controls.
Git is not containment
Two different boundaries:
Containment limits what execution can touch. Git is where a human decides whether to accept the resulting repository state. Collapsing those questions confuses a held boundary with a kept change.
OpenTendril Fruit
Fruit is Git-reviewable output a cycle yields: a branch, PR, or artifact. The Botanist decides acceptance.
Producing Fruit and accepting Fruit are separate moments. Fruit is not “the merge,” and completing a run does not itself adopt the result as authoritative project state.
Current governed Git path
OpenTendril exposes a delegated Git capability family so a Pollinator asks the Stem to perform Git work under the substrate’s configured connection rather than shelling out Git on the host with ambient authority. Each operation class is separately grantable. The Core documents the deliberate ladder:
- git.commit Stage and commit in a resolved workspace under configured identity
- git.push Publish a branch using Stem-held credentials (mediated egress)
- git.pr Open a pull request for an already-published branch
Separation matters: a grant for git.pr alone must not publish a branch
as a side effect. Push and pull request are independent steps. Related
operations also exist as separate classes: git.branch,
git.status, git.branch.list, git.prune.
Not every Sprout run automatically performs all three steps. Paths differ: some runs produce local commits and workspace reconciliation; seed-style bounded work is designed to leave reviewable output on a dedicated branch without merging to the host checkout; delegated ladder calls only run the operations a grant and caller request.
Git branches and isolated workspaces
Two different uses of the word “branch” must not be collapsed:
- Branch (taxonomy) A capability and security group the Stem initialises: a zone of authority, not a Git ref.
- Git branch A source-control branch: versioned line of commits for isolation and review.
On the delegated Git path, a Pollinator receives an isolated per-Pollen Git worktree under a managed workspace root, created on an owned Git branch cut from the repository’s resolved default branch. That isolation prevents two subjects from staging each other’s uncommitted files onto each other’s branches under each other’s identity. The worktree still shares the object store, so commits remain visible as Git branches for push and review.
Separately, Sprout execution often uses shadow worktrees so work runs off the operator’s live checkout. Those are runtime isolation mechanics, not a second acceptance policy.
Pull requests
A pull request is one possible Fruit (handoff form) when configuration and
grants support it. The git.pr operation opens a PR for an
already-published branch. It does not push. It does not merge.
Do not read current behaviour as:
- OpenTendril always opens a PR;
- all Fruit must be a PR;
- PR creation means merge;
- PR approval is automatic.
When a PR already exists for the same head, the operation can return the existing one rather than duplicating or rewriting a description a human may have edited.
No implicit acceptance
Work arrives for review
Successful Sprout completion does not itself merge a pull request, update a remote protected or default branch, or constitute Botanist acceptance. The Objective still measures acceptance separately from whether the boundary held.
What current implementation does after a successful local Sprout that produced measurable file changes (when merge-back is enabled, the default for ordinary Sprout runs):
- The run commits in an isolated shadow worktree.
-
Those commits are then fast-forwarded into the host substrate checkout via
git merge --ff-only(after a protected-path check). That can advance the current local workspace branch without a separate human acceptance action. - That step is local workspace Git reconciliation. It is not a pull-request merge, not an update of a remote default branch, and not the Botanist’s acceptance decision defined by the Objective, but it does move versioned commits onto the local checkout’s current branch automatically.
Other current paths differ. Seed-style execution sets merge-back off and keeps
reviewable output on a dedicated seed branch without merging into the host
checkout. Remote-clone Sprout work pushes the terrarium branch rather than
merging into a local host path. Parallel-phenotype growth also disables
merge-back so variants do not rewrite the host checkout. Delegated
git.commit, git.push, and git.pr only run
when a grant and caller request them, and default-branch protection refuses
commits onto the resolved default branch unless a substrate explicitly opts
out (protection widens when the default branch cannot be determined).
Provenance
Provenance tells who or what produced a change. Review still determines whether to accept it. Provenance is not correctness.
On the delegated git.commit path, attribution is deny-closed: if the
substrate’s resolved commit identity is missing name or email (in local commit
mode), the commit is refused before any Git command runs. Unattributable
delegated commits are not created. API commit mode uses a different identity
path (GitHub App server-side authorship) and has its own requirements.
Ordinary Sprout-local commit paths may still fall back to ambient Git identity
when configured identity is incomplete. Attribution guarantees therefore differ
by execution path: delegated git.commit is stricter than ordinary
Sprout-local commit handling.
Reversibility
Committed, versioned output is easier to inspect and reverse than silent mutation of a working tree with no history. That is a real operational advantage of Git handoff.
It does not make every side effect of an autonomous run reversible. External API
calls, spent money, leaked data, and other non-repository effects are not undone
by git revert. Runtime
containment still matters for what can happen while
the work is running.
Relation to the experiment
Under the current Objective, a qualifying run should return work as commits on a branch (reviewable and revertible) rather than as changes already applied as authoritative remote state. Whether the Botanist accepts the work is measured separately from whether OpenTendril held the boundary.
That separation is the same “report, never decide” rule that observation obeys: the system says what happened; the human decides what to keep. Protocol details: the OpenTendril experiment.