main · last commit
13 days ago ·
7g0stsfu
ah-9r4 DECISION: worktree/branch topology for agent-created child tasks
Past Stand
bd reopen ah-9r4
| Created by | Eugene Blikh |
| Owner | bigbes@gmail.com |
| Created | 2026-07-17T14:37:26Z |
| Updated | 2026-07-17T15:49:21Z |
| Closed | 2026-07-17T15:49:21Z |
Blocks the delegation loop. Parent X owns worktree <work_root>/<slug>/task-X on branch agent/task-X. Where does child Y work? git refuses to check the same branch out into two worktrees, so Y cannot enter X's. Branching Y off the default branch means a later merge into X's divergent branch; branching Y off agent/task-X breaks the review/publish path, because gitLogOneline/gitDiffStat (internal/runner/commands.go) compute <default>..HEAD against the repo default branch and would report all of X's work as Y's diff. Proposed split by whether the role writes code: ADVISORY roles (research/review/design — return text, touch no code) get a detached-HEAD worktree at X's tip. git permits many worktrees on the same COMMIT, just not the same BRANCH, so Y reads X's WIP with no collision and no merge. Only WRITER roles need real branches and a merge story — and the advisory-only subset may cover the useful cases, deferring the writer problem entirely. Verify the detached-HEAD claim against the pinned git before building on it.
DECISION (verified on git 2.55.0, 2026-07-17):
SPLIT roles by whether they write code.
ADVISORY roles (research/review/design — read parent WIP, return TEXT, publish nothing): each child gets a DETACHED-HEAD worktree at the parent's tip commit:
git worktree add --detach <child-wt> <parent-tip-sha>
Proven: child sees parent's uncommitted-into-branch WIP (the parent's committed tip), runs on 'HEAD (no branch)', and any commits it makes do NOT move the parent's agent/task-<id> branch. Teardown (git worktree remove) leaves only unreferenced commits — no branch leak, no merge. This is the recommended FIRST and possibly ONLY implementation.
WRITER roles (produce code that must land on the parent's branch): DEFERRED. They need a real branch plus a merge story, and note that gitDiffStat/gitLogOneline compute <default>..HEAD — a writer child branched off agent/task-<id> would misattribute ALL of the parent's work as the child's diff, so a writer child needs a different diff base (merge-base against the parent branch, not the repo default). Do not build until an advisory-only loop proves insufficient.
Confirmed anti-pattern: git refuses 'worktree add <path> agent/task-X' while X's worktree holds that branch ('already used by worktree at ...'), so a child can never simply enter the parent's branch.
CODE SEAM for ah-0ge.1: the runner's worktree creation (internal/runner/commands.go gitWorktreeAddNewBranch, base=default) needs a base-override path for child tasks: detached add at the parent tip instead of a new branch off default. Child worktree path can follow the normal <work_root>/<slug>/task-<childid> convention; only the base differs.
A written decision recording: which roles are advisory vs writer, how each child's worktree base is chosen, and what the diffstat base is for a child (if writer roles are in scope at all).
No outgoing dependencies.
ah-0ge.1
— Agent-created tasks via .task/tasks.json file channel
blocks
| id | ah-9r4 |
| content_hash | c8e9bb1e135799eacb8565a6f41478d32efa61f0c311dedb27b638a4b6f912c0 |
| title | DECISION: worktree/branch topology for agent-created child tasks |
| description | Blocks the delegation loop. Parent X owns worktree <work_root>/<slug>/task-X on branch agent/task-X. Where does child Y work? git refuses to check the same branch out into two worktrees, so Y cannot enter X's. Branching Y off the default branch means a later merge into X's divergent branch; branching Y off agent/task-X breaks the review/publish path, because gitLogOneline/gitDiffStat (internal/runner/commands.go) compute <default>..HEAD against the repo default branch and would report all of X's work as Y's diff. Proposed split by whether the role writes code: ADVISORY roles (research/review/design — return text, touch no code) get a detached-HEAD worktree at X's tip. git permits many worktrees on the same COMMIT, just not the same BRANCH, so Y reads X's WIP with no collision and no merge. Only WRITER roles need real branches and a merge story — and the advisory-only subset may cover the useful cases, deferring the writer problem entirely. Verify the detached-HEAD claim against the pinned git before building on it. |
| design | DECISION (verified on git 2.55.0, 2026-07-17): SPLIT roles by whether they write code. ADVISORY roles (research/review/design — read parent WIP, return TEXT, publish nothing): each child gets a DETACHED-HEAD worktree at the parent's tip commit: git worktree add --detach <child-wt> <parent-tip-sha> Proven: child sees parent's uncommitted-into-branch WIP (the parent's committed tip), runs on 'HEAD (no branch)', and any commits it makes do NOT move the parent's agent/task-<id> branch. Teardown (git worktree remove) leaves only unreferenced commits — no branch leak, no merge. This is the recommended FIRST and possibly ONLY implementation. WRITER roles (produce code that must land on the parent's branch): DEFERRED. They need a real branch plus a merge story, and note that gitDiffStat/gitLogOneline compute <default>..HEAD — a writer child branched off agent/task-<id> would misattribute ALL of the parent's work as the child's diff, so a writer child needs a different diff base (merge-base against the parent branch, not the repo default). Do not build until an advisory-only loop proves insufficient. Confirmed anti-pattern: git refuses 'worktree add <path> agent/task-X' while X's worktree holds that branch ('already used by worktree at ...'), so a child can never simply enter the parent's branch. CODE SEAM for ah-0ge.1: the runner's worktree creation (internal/runner/commands.go gitWorktreeAddNewBranch, base=default) needs a base-override path for child tasks: detached add at the parent tip instead of a new branch off default. Child worktree path can follow the normal <work_root>/<slug>/task-<childid> convention; only the base differs. |
| acceptance_criteria | A written decision recording: which roles are advisory vs writer, how each child's worktree base is chosen, and what the diffstat base is for a child (if writer roles are in scope at all). |
| notes | |
| status | closed |
| priority | 2 |
| issue_type | task |
| assignee | NULL |
| estimated_minutes | NULL |
| created_at | 2026-07-17T14:37:26Z |
| created_by | Eugene Blikh |
| owner | bigbes@gmail.com |
| updated_at | 2026-07-17T15:49:21Z |
| closed_at | 2026-07-17T15:49:21Z |
| closed_by_session | |
| external_ref | NULL |
| spec_id | |
| compaction_level | 0 |
| compacted_at | NULL |
| compacted_at_commit | NULL |
| original_size | NULL |
| sender | |
| ephemeral | 0 |
| wisp_type | |
| pinned | 0 |
| is_template | 0 |
| mol_type | |
| work_type | |
| source_system | |
| metadata | �{} |
| source_repo | |
| close_reason | Decided: advisory children use detached-HEAD worktree at parent tip (verified git 2.55.0); writer children deferred. Full rationale + code seam in the design field. |
| event_kind | |
| actor | |
| target | |
| payload | |
| await_type | |
| await_id | |
| timeout_ns | 0 |
| waiters | |
| hook_bead | |
| role_bead | |
| agent_state | |
| last_activity | NULL |
| role_type | |
| rig | |
| due_at | NULL |
| defer_until | NULL |
| no_history | 0 |
| started_at | NULL |
| is_blocked | 0 |
| id | db0446cc-58eb-5fa0-846e-7728bf9bb385 |
| issue_id | ah-0ge.1 |
| type | blocks |
| created_at | 2026-07-17T17:38:41Z |
| created_by | Eugene Blikh |
| metadata | �{} |
| thread_id | |
| depends_on_issue_id | ah-9r4 |
| depends_on_wisp_id | NULL |
| depends_on_external | NULL |
| id | 019f7082-c4b1-717e-9fce-0f0b1ef05c92 |
| issue_id | ah-9r4 |
| event_type | created |
| actor | Eugene Blikh |
| old_value | |
| new_value | |
| comment | NULL |
| created_at | 2026-07-17T17:37:26Z |
| id | 019f70c4-9923-7a25-898a-b4ee62bb18b8 |
| issue_id | ah-9r4 |
| event_type | updated |
| actor | Eugene Blikh |
| old_value | {"id":"ah-9r4","title":"DECISION: worktree/branch topology for agent-created child tasks","description":"Blocks the delegation loop. Parent X owns worktree \u003cwork_root\u003e/\u003cslug\u003e/task-X on branch agent/task-X. Where does child Y work? git refuses to check the same branch out into two worktrees, so Y cannot enter X's. Branching Y off the default branch means a later merge into X's divergent branch; branching Y off agent/task-X breaks the review/publish path, because gitLogOneline/gitDiffStat (internal/runner/commands.go) compute \u003cdefault\u003e..HEAD against the repo default branch and would report all of X's work as Y's diff.\nProposed split by whether the role writes code: ADVISORY roles (research/review/design — return text, touch no code) get a detached-HEAD worktree at X's tip. git permits many worktrees on the same COMMIT, just not the same BRANCH, so Y reads X's WIP with no collision and no merge. Only WRITER roles need real branches and a merge story — and the advisory-only subset may cover the useful cases, deferring the writer problem entirely.\nVerify the detached-HEAD claim against the pinned git before building on it.","acceptance_criteria":"A written decision recording: which roles are advisory vs writer, how each child's worktree base is chosen, and what the diffstat base is for a child (if writer roles are in scope at all).","status":"open","priority":2,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:26Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:37:26Z"} |
| new_value | {"design":"DECISION (verified on git 2.55.0, 2026-07-17):\n\nSPLIT roles by whether they write code.\n\nADVISORY roles (research/review/design — read parent WIP, return TEXT, publish nothing): each child gets a DETACHED-HEAD worktree at the parent's tip commit:\n git worktree add --detach \u003cchild-wt\u003e \u003cparent-tip-sha\u003e\nProven: child sees parent's uncommitted-into-branch WIP (the parent's committed tip), runs on 'HEAD (no branch)', and any commits it makes do NOT move the parent's agent/task-\u003cid\u003e branch. Teardown (git worktree remove) leaves only unreferenced commits — no branch leak, no merge. This is the recommended FIRST and possibly ONLY implementation.\n\nWRITER roles (produce code that must land on the parent's branch): DEFERRED. They need a real branch plus a merge story, and note that gitDiffStat/gitLogOneline compute \u003cdefault\u003e..HEAD — a writer child branched off agent/task-\u003cid\u003e would misattribute ALL of the parent's work as the child's diff, so a writer child needs a different diff base (merge-base against the parent branch, not the repo default). Do not build until an advisory-only loop proves insufficient.\n\nConfirmed anti-pattern: git refuses 'worktree add \u003cpath\u003e agent/task-X' while X's worktree holds that branch ('already used by worktree at ...'), so a child can never simply enter the parent's branch.\n\nCODE SEAM for ah-0ge.1: the runner's worktree creation (internal/runner/commands.go gitWorktreeAddNewBranch, base=default) needs a base-override path for child tasks: detached add at the parent tip instead of a new branch off default. Child worktree path can follow the normal \u003cwork_root\u003e/\u003cslug\u003e/task-\u003cchildid\u003e convention; only the base differs."} |
| comment | NULL |
| created_at | 2026-07-17T18:49:20Z |
| id | 019f70c4-9afa-7a16-a35e-03cab283f63a |
| issue_id | ah-9r4 |
| event_type | closed |
| actor | Eugene Blikh |
| old_value | |
| new_value | Decided: advisory children use detached-HEAD worktree at parent tip (verified git 2.55.0); writer children deferred. Full rationale + code seam in the design field. |
| comment | NULL |
| created_at | 2026-07-17T18:49:20Z |
No comments.
Close reason