Skip to content

poteto-mode: writers get T3's worktree isolation, PR owners are child tasks, and a child is a leaf (2.2.6) - #68

Merged
chhoumann merged 4 commits into
mainfrom
fix/t3-delegation
Nov 7, 2026
Merged

chhoumann merged 4 commits into
mainfrom
fix/t3-delegation

Conversation

@chhoumann

@chhoumann chhoumann commented Nov 7, 2026 •

Copy link
Copy Markdown
Owner

Why

pstack inside T3 should hand work to children the way T3 manages them. Three things went against that. A writing child got a worktree the parent made by hand, which no T3 thread owns, so T3 never cleans it up and the PR came from a branch outside the thread (#50). Autopilot-full started each PR owner as a top-level thread, which T3 reserves for a thread the user asks for and which task_status and task_cancel cannot reach (#47). The session-start text told every session, children included, "This chat runs the playbook itself", so a child could run a playbook's fan-out (#21).

What changes

  • Dispatch on T3 (poteto-mode: inside T3, delegates should use delegate_task isolation instead of git worktree add #50). A writer gets delegate_task's isolation: "worktree". One writer may stay in the parent's checkout while the parent writes nothing. The brief asks the child to end with git branch --show-current and git rev-parse HEAD, because T3 can rename the branch mid-run and task_status does not report it. The parent merges the writer's branch with git merge, and a PR opens only from a T3 thread's branch. When delegate_task refuses with Unable to resolve the parent checkout commit, the rule says to commit first in a repo with no commit. It keeps git worktree add for a thread whose project is not a git checkout, for work in another checkout, and for a child whose worktree gets uncommitted changes copied in, as interrogate's adversaries do. swarm, arena, Orchestrate, Shipping, Feature step 4, and Opening a PR point at it. Isolation always starts at the parent's HEAD, so a child bound for another commit, such as a PR head or fresh trunk, gets its own worktree even when it only reads. It runs git fetch and resets its own branch there first. That covers Shipping verifiers, Autopilot-full owners, and swarm workers on another branch. A child sent into a worktree it does not own, such as a finished Orchestrate worker's, runs shared there by absolute path. Every child's report names pwd, its branch, and its commit, which is how an isolated arena candidate reports its output location.
  • Autopilot-full owners (fix(pstack): align delegated task lifecycle with T3 #47). Each PR owner is a delegate_task child with isolation: "worktree" from the root's checkout at trunk. It resets its own branch to fresh trunk before it writes. Its brief names the playbook and the root's thread ID, so it reports heads with t3_thread_send, and it lets the owner delegate. T3 tells a child never to watch a PR, so the owner babysits in drive mode and hands a wait for a person to the root, which watches that PR. This redoes the T3-mechanics part of @pb3975's fix(pstack): align delegated task lifecycle with T3 #47 as substitutions. Its fresh-review-round rule is left out, since Lauren's "Fresh subagents by default" and T3's own instructions already say it.
  • A child is a leaf (Recursive subagent explosion: leaf delegates re-read orchestrator skills and delegate further #21). The routing text and Dispatch on T3 say a delegate_task child does the work itself and starts no subagent unless its brief names one. Lauren's runner prompt stays as written. Both hooks files are unchanged.
  • Release 2.2.6. VERSION, the CHANGES.md entry, the stamped manifests, and the README's tag example. All three components stay pinned at cursor/plugins c742dd6.

#19 (settle each child thread after its result) is not in this PR. On T3 0.1.8-nightly.20261106 the sidebar leaves out every thread whose lineage has relationshipToParent: "subagent", which every delegate_task child has. So finished children never show in the sidebar, settled or not.

Evidence

All on this Mac with T3 Code (Nightly) 0.1.8-nightly.20261106, in throwaway repos and threads that are deleted since.

#50.

  • A thread whose project is not a git checkout called delegate_task with isolation: "worktree" and got invalid_request: Unable to resolve the parent checkout commit.
  • A thread in a git repo with no commit got the same error. After one commit, the same call ran the child in ~/.t3/worktrees/<repo>/t3-<hash>.
  • A T3 worktree thread made a local commit and left one file uncommitted. Its worktree child started at that commit without the file, committed, and its branch showed in the parent's git worktree list. git merge --ff-only <branch> moved the parent's branch onto it. The child's branch was t3/3098eef5 at its first command and scripted-git-test after its commit. task_status had no branch field. A shared child committed straight onto the parent's branch.
  • A thread on a local feature branch, behind an origin whose main and pr-head had moved since it cloned, started two worktree children. Both began at the parent's feature commit. One ran git fetch origin main && git reset --hard origin/main, landed on the trunk commit the parent had never fetched, and committed on top. The other lacked the PR head commit until git fetch origin pr-head, and then git reset --hard <sha> put it on exactly that commit. The parent's checkout stayed on its commit and clean.

#47. A worktree child's t3_thread_send to its parent's thread ID started a new parent run carrying MID-RUN REPORT from child: branch t3/5902a948 head 137ee27, before the child's completion arrived.

#21. From a read-only copy of this Mac's T3 store:

  • 488 delegate_task children exist since 2026-10-04. No grandchild ever started a child, so the five-level nesting in Recursive subagent explosion: leaf delegates re-read orchestrator skills and delegate further #21 did not recur here.
  • Before 2026-10-30, 6 of 456 children started children their brief did not ask for. One design child, whose brief named no subagent, started 8 delegate_task research children.
  • Since 2026-10-30, T3 itself tells each session "If you are a subagent or child, do the work yourself. Start no subagents unless your task says to." All 14 T3 Codex sessions since then carry it, and 0 of 32 children started a child unasked.
  • The new line ends the routing text's contradiction of that rule.

#19. In the installed client bundle, the sidebar keeps a thread only when !Df(ref, lineage, set), and Df is true for any lineage with relationshipToParent === "subagent". t3_thread_list counts 856 unsettled threads with subagents and 14 without.

Checks

  • bun install --frozen-lockfile and bun tools/generate.mjs --check pass, with 17 generated files current.
  • GIT_CONFIG_GLOBAL=/dev/null bun test tests/ --timeout 30000 gives 554 pass, 56 skip, and 0 fail at 5c6b649.
  • bun tools/sync.mjs <pstack|cursor-team-kit|thermos> c742dd6 --dry-run exits 0 for each component. Each fork map matches main's path for path, with the same changed-line counts, so each fork carries the same edit as its derived base. No fork is undeclared, and every substitution matches.
  • npx markdownlint-cli2@0.18.1 reports 0 errors on the changed Markdown trees.
  • The diff and this body contain no workplace name (case-insensitive grep, 0 hits).

Review

Two independent reviewers ran on fresh delegate_task children each round. They were claudeAgent/claude-fable-5-1 at effort xhigh and codex/gpt-6-astra at reasoningEffort xhigh.

  • Round 1 on a2f3ae7. Astra found no critical or high issue and raised three mediums. Fable raised one high, interrogate copying uncommitted changes into worktrees that isolation leaves empty, plus two mediums and a low. All are fixed in 86758d2. Dispatch on T3 keeps git worktree add for a worktree that gets copied changes, and the arena line defers to it. A swarm worker on another branch gets its own worktree and resets its own branch. An Orchestrate worker that reuses a worktree runs shared with its path. An owner babysits in drive mode and hands a wait for a person to the root, since a child cannot watch.
  • Round 2 on 86758d2. Astra found nothing at any severity. Fable found no critical or high issue and called it mergeable as is. One of its lows corrected a CHANGES claim, fixed in d9f6957.
  • Cursor Bugbot on d9f6957. Bugbot raised four mediums with one root: isolation always starts at the parent's HEAD. Shipping verifiers never moved to the PR head, Autopilot-full owners got the root's HEAD rather than trunk, Orchestrate reuse never put the worker in the reused worktree, and an isolated arena candidate had no output path at spawn. All are fixed in 5c6b649, with the base move verified live as above. A fresh Fable review of that fix diff found no critical or high issue and closed all four. It raised two lows. One is that a read-only child's brief now also tells it to reset its own branch. The other is that a PR from a fork needs the brief to name pull/<n>/head for git fetch.

Known follow-up, not fixed here because it is not critical or high:

  • The fallback and T3's own rule. T3's prompt says "Never make a child's checkout in the shell". The git worktree add fallback still does that in its three cases. main already did it for every writer, so this PR narrows the conflict. For copied uncommitted changes, an isolated child applying a patch would stay T3-native, but git diff leaves out untracked files.

Closes #50
Closes #21

…tasks, a child is a leaf

poteto-mode's Dispatch on T3 had the parent make each writing child's
worktree with git worktree add and remove it afterwards. No T3 thread is
bound to that worktree, so T3's cleanup never reaches it, and the work
ends on a branch no thread owns (#50). A writer now gets delegate_task's
isolation: "worktree", which starts from the thread checkout's HEAD
commit. One writer may stay in the parent's checkout instead. The brief
asks the child for its final branch and commit, since T3 can rename the
branch mid-run and task_status does not report it, and a PR opens only
from a T3 thread's branch. git worktree add stays for a thread whose
project is not a git checkout, which delegate_task refuses with "Unable
to resolve the parent checkout commit". swarm, arena, Orchestrate,
Shipping, Feature, and Opening a PR point at the same rule.

Autopilot-full started each PR owner as a top-level thread with
t3_thread_launch, which T3 reserves for a thread the user asks for and
which task_status and task_cancel cannot reach. Each owner is now a
delegate_task child in its own T3 worktree that reports heads with
t3_thread_send, redoing the T3 part of #47 by @pb3975.

The session-start routing text told every session, children included,
that it runs the playbook and delegates its steps. The routing text and
Dispatch on T3 now say a delegate_task child is a leaf unless its brief
names a subagent, in line with T3's own instruction to children (#21).

Settling child threads (#19) is left out: T3's sidebar already hides
every subagent thread.

All three components stay pinned at c742dd6.
…n owner's watch working

Review round 1 fixes for the 2.2.6 delegation patch.

interrogate reuses arena's per-candidate worktree step and copies the
scope's uncommitted changes into each worktree. The arena line made each
such worktree a T3-isolated child, and isolation leaves uncommitted edits
out, so a panel on uncommitted work would review a tree without the
change. Dispatch on T3 now keeps git worktree add for a child whose
worktree gets uncommitted changes copied in, and the arena line defers
to it.

A swarm worker that starts from another branch detached its checkout,
which for a reading worker running in the parent's checkout would move
the parent's HEAD, and for a writer left its commits off the branch it
reports. It now gets its own worktree and resets its own branch there.

An Orchestrate worker that reuses another worker's worktree is told to
run shared with that path, since isolation always makes a new worktree.

A delegate_task child has no watch_pull_request, so an Autopilot-full
owner babysits in drive mode and hands a wait for a person to the root.
Linked environments' T3 servers still list it, so the claim names the
child's own server, as review round 2 found.
@chhoumann
chhoumann marked this pull request as ready for review November 7, 2026 07:44

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d9f6957. Configure here.

Comment thread plugins/pstack/skills/arena/SKILL.md Resolved
…rent's HEAD

Cursor Bugbot on #68 found four places where a child needs a base other
than the parent's HEAD, which T3's worktree isolation always starts from.
A Shipping verifier was told the PR head but never moved to it, and an
Autopilot-full owner was said to start at trunk while it got whatever the
root had checked out. An Orchestrate worker reusing a finished worker's
worktree was named the path but not told to work there, and an arena
candidate in an isolated worktree had no output path the parent could
pass at spawn.

Dispatch on T3 now says that a child bound for another commit, such as a
PR head or fresh trunk, gets its own worktree even when it only reads,
fetches, and resets its own branch there first. A child sent into a
worktree it does not own runs shared and works there by absolute path,
and every child's report names pwd with its branch and commit. Shipping,
Autopilot-full, swarm, Orchestrate, and arena point at that rule.

On T3 0.1.8-nightly.20261106, two worktree children of a thread on a
stale feature branch started at its commit, fetched, and reset onto fresh
origin/main and onto an unfetched PR head SHA, leaving the parent's
checkout unchanged.
@chhoumann
chhoumann merged commit 111bb68 into main Nov 7, 2026
12 checks passed
@chhoumann
chhoumann deleted the fix/t3-delegation branch November 7, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant