From e55dd9a99748a6f9e5153f01fea16cbf69612fc1 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 30 Oct 2026 00:58:06 -0700 Subject: [PATCH 1/4] Open the Attended Session on Cloning a Private Hub Checkout The attended procedure's first command ran `$handoff` from a hub checkout it never said to make, so a resuming session took the Skill tool's base directory, the maintainer's own checkout, as that checkout. Step 0 now clones the hub's main as the session's first command and names that clone as the one `$handoff` runs from. "Running the Chain" says the same. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/session-handoff/SKILL.md | 19 +++++++++++++++++-- .../.source-digests/session-handoff | 2 +- .../skills/session-handoff/SKILL.md | 19 +++++++++++++++++-- .github/skills/session-handoff/SKILL.md | 19 +++++++++++++++++-- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/.agents/skills/session-handoff/SKILL.md b/.agents/skills/session-handoff/SKILL.md index 9002fe4c0..bc19bfd90 100644 --- a/.agents/skills/session-handoff/SKILL.md +++ b/.agents/skills/session-handoff/SKILL.md @@ -210,11 +210,22 @@ returns fewer. A maintainer resuming work says little, often only "resume the handoff", and that phrase stands for the whole procedure below. Run every step without being reminded of any of them. +0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` + into the fleet worktree directory `repo-worktree` names, before any `git` or `$handoff` command: + + ```sh + git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate- + ``` + + That clone is the hub checkout "Running the Chain" sets `$handoff` from, so every later step + runs the chain's script there. The Skill tool's base directory is the maintainer's own hub + checkout, and never the one this procedure runs in. So no step runs `git status`, `git fetch`, + or `git worktree add` there, and none reads it as the hub checkout. 1. **Pick the link.** Where the maintainer names an issue, take it. Where none is named, read `python3 "$handoff" tracks --repo OWNER/NAME --json`. It prints each open handoff's number, title, track, labels, and updatedAt. It reads them from the repository's issue connection rather than the search index, so a link written moments ago is already read correctly. - `$handoff` is the hub checkout path "Running the Chain" sets. A nonzero exit, including the + `$handoff` is the script in the clone step 0 made. A nonzero exit, including the refusal over a read window that filled, means the list is not whole. So say so and ask rather than picking from it. Take a link carrying `blocked` first, newest update first among them. That is because its blocker is a decision only the maintainer can make, and the maintainer is @@ -338,8 +349,12 @@ chain, since `new` then archives and rewrites whatever `default` holds, and `clo - **`close`** is the one way a track ends. It comments the outcome given in `--body-file` on the track's issue, then closes it, and a rerun after the comment landed only closes. +`` below is a hub checkout of the session's own, never the maintainer's. In an +attended session it is the clone "The Attended Session" step 0 makes, in the hub itself as in any +other repository. + ```sh -handoff="/scripts/handoff.py" # in the hub itself, scripts/handoff.py +handoff="/scripts/handoff.py" # a hub checkout of the session's own python3 "$handoff" current --repo OWNER/NAME --track "" python3 "$handoff" resume --repo OWNER/NAME --track "" --history 5 python3 "$handoff" chain --repo OWNER/NAME --track "" --grep "an escaped regex" diff --git a/.claude-plugin/fleet-skills/.source-digests/session-handoff b/.claude-plugin/fleet-skills/.source-digests/session-handoff index 9a39cb49f..ab56e84ca 100644 --- a/.claude-plugin/fleet-skills/.source-digests/session-handoff +++ b/.claude-plugin/fleet-skills/.source-digests/session-handoff @@ -1 +1 @@ -d6e2ed39334468a3 +c1a56863ac2fbd83 diff --git a/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md b/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md index 9002fe4c0..bc19bfd90 100644 --- a/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md @@ -210,11 +210,22 @@ returns fewer. A maintainer resuming work says little, often only "resume the handoff", and that phrase stands for the whole procedure below. Run every step without being reminded of any of them. +0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` + into the fleet worktree directory `repo-worktree` names, before any `git` or `$handoff` command: + + ```sh + git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate- + ``` + + That clone is the hub checkout "Running the Chain" sets `$handoff` from, so every later step + runs the chain's script there. The Skill tool's base directory is the maintainer's own hub + checkout, and never the one this procedure runs in. So no step runs `git status`, `git fetch`, + or `git worktree add` there, and none reads it as the hub checkout. 1. **Pick the link.** Where the maintainer names an issue, take it. Where none is named, read `python3 "$handoff" tracks --repo OWNER/NAME --json`. It prints each open handoff's number, title, track, labels, and updatedAt. It reads them from the repository's issue connection rather than the search index, so a link written moments ago is already read correctly. - `$handoff` is the hub checkout path "Running the Chain" sets. A nonzero exit, including the + `$handoff` is the script in the clone step 0 made. A nonzero exit, including the refusal over a read window that filled, means the list is not whole. So say so and ask rather than picking from it. Take a link carrying `blocked` first, newest update first among them. That is because its blocker is a decision only the maintainer can make, and the maintainer is @@ -338,8 +349,12 @@ chain, since `new` then archives and rewrites whatever `default` holds, and `clo - **`close`** is the one way a track ends. It comments the outcome given in `--body-file` on the track's issue, then closes it, and a rerun after the comment landed only closes. +`` below is a hub checkout of the session's own, never the maintainer's. In an +attended session it is the clone "The Attended Session" step 0 makes, in the hub itself as in any +other repository. + ```sh -handoff="/scripts/handoff.py" # in the hub itself, scripts/handoff.py +handoff="/scripts/handoff.py" # a hub checkout of the session's own python3 "$handoff" current --repo OWNER/NAME --track "" python3 "$handoff" resume --repo OWNER/NAME --track "" --history 5 python3 "$handoff" chain --repo OWNER/NAME --track "" --grep "an escaped regex" diff --git a/.github/skills/session-handoff/SKILL.md b/.github/skills/session-handoff/SKILL.md index 9002fe4c0..bc19bfd90 100644 --- a/.github/skills/session-handoff/SKILL.md +++ b/.github/skills/session-handoff/SKILL.md @@ -210,11 +210,22 @@ returns fewer. A maintainer resuming work says little, often only "resume the handoff", and that phrase stands for the whole procedure below. Run every step without being reminded of any of them. +0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` + into the fleet worktree directory `repo-worktree` names, before any `git` or `$handoff` command: + + ```sh + git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate- + ``` + + That clone is the hub checkout "Running the Chain" sets `$handoff` from, so every later step + runs the chain's script there. The Skill tool's base directory is the maintainer's own hub + checkout, and never the one this procedure runs in. So no step runs `git status`, `git fetch`, + or `git worktree add` there, and none reads it as the hub checkout. 1. **Pick the link.** Where the maintainer names an issue, take it. Where none is named, read `python3 "$handoff" tracks --repo OWNER/NAME --json`. It prints each open handoff's number, title, track, labels, and updatedAt. It reads them from the repository's issue connection rather than the search index, so a link written moments ago is already read correctly. - `$handoff` is the hub checkout path "Running the Chain" sets. A nonzero exit, including the + `$handoff` is the script in the clone step 0 made. A nonzero exit, including the refusal over a read window that filled, means the list is not whole. So say so and ask rather than picking from it. Take a link carrying `blocked` first, newest update first among them. That is because its blocker is a decision only the maintainer can make, and the maintainer is @@ -338,8 +349,12 @@ chain, since `new` then archives and rewrites whatever `default` holds, and `clo - **`close`** is the one way a track ends. It comments the outcome given in `--body-file` on the track's issue, then closes it, and a rerun after the comment landed only closes. +`` below is a hub checkout of the session's own, never the maintainer's. In an +attended session it is the clone "The Attended Session" step 0 makes, in the hub itself as in any +other repository. + ```sh -handoff="/scripts/handoff.py" # in the hub itself, scripts/handoff.py +handoff="/scripts/handoff.py" # a hub checkout of the session's own python3 "$handoff" current --repo OWNER/NAME --track "" python3 "$handoff" resume --repo OWNER/NAME --track "" --history 5 python3 "$handoff" chain --repo OWNER/NAME --track "" --grep "an escaped regex" From 7422dc87fa398371cb465ed89e041b0e2a278330 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 30 Oct 2026 01:01:30 -0700 Subject: [PATCH 2/4] Keep the Hub Clone Apart From Task Worktrees and Fresh Before Writes Name the step 0 clone so it never takes a task worktree's path, and pull it before step 6 writes. State that wherever the skill loaded from is not the session's hub checkout, without claiming what that location is. Drop the in-hub relative-path exception the unattended seats still cited. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/session-handoff/SKILL.md | 13 ++++++++----- .agents/skills/unattended-handoff/SKILL.md | 4 ++-- .../fleet-skills/.source-digests/session-handoff | 2 +- .../fleet-skills/.source-digests/unattended-handoff | 2 +- .../fleet-skills/skills/session-handoff/SKILL.md | 13 ++++++++----- .../fleet-skills/skills/unattended-handoff/SKILL.md | 4 ++-- .github/skills/session-handoff/SKILL.md | 13 ++++++++----- .github/skills/unattended-handoff/SKILL.md | 4 ++-- 8 files changed, 32 insertions(+), 23 deletions(-) diff --git a/.agents/skills/session-handoff/SKILL.md b/.agents/skills/session-handoff/SKILL.md index bc19bfd90..ddd07231f 100644 --- a/.agents/skills/session-handoff/SKILL.md +++ b/.agents/skills/session-handoff/SKILL.md @@ -211,16 +211,19 @@ A maintainer resuming work says little, often only "resume the handoff", and tha the whole procedure below. Run every step without being reminded of any of them. 0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` - into the fleet worktree directory `repo-worktree` names, before any `git` or `$handoff` command: + into a new directory before any `git` or `$handoff` command. `` is a name no directory + there already holds, so the clone never takes a path a task worktree wants: ```sh - git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate- + git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate-hub- ``` That clone is the hub checkout "Running the Chain" sets `$handoff` from, so every later step - runs the chain's script there. The Skill tool's base directory is the maintainer's own hub - checkout, and never the one this procedure runs in. So no step runs `git status`, `git fetch`, - or `git worktree add` there, and none reads it as the hub checkout. + runs the chain's script there. Bring it up to date with `git -C pull --ff-only` before + step 6 writes, since a clone is whatever it last fetched. Wherever this skill was loaded from is + never this session's hub checkout, whatever checkout or snapshot holds it. So no step reads that + location as the hub checkout or runs `$handoff` from it. A task worktree `repo-worktree` creates + off a base clone is a separate act, and that skill governs it. 1. **Pick the link.** Where the maintainer names an issue, take it. Where none is named, read `python3 "$handoff" tracks --repo OWNER/NAME --json`. It prints each open handoff's number, title, track, labels, and updatedAt. It reads them from the repository's issue connection diff --git a/.agents/skills/unattended-handoff/SKILL.md b/.agents/skills/unattended-handoff/SKILL.md index b58afd90b..ad9200ed8 100644 --- a/.agents/skills/unattended-handoff/SKILL.md +++ b/.agents/skills/unattended-handoff/SKILL.md @@ -48,8 +48,8 @@ One worker runs at a time, so no two rounds claim the same file and no round nee `backlog-burndown` does. Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with -`handoff="/scripts/handoff.py"` (in the hub itself, `scripts/handoff.py`), as -`session-handoff` "Running the Chain" sets it. Each seat sets it for itself, since the picker and +`handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. +`` is a hub checkout of the seat's own on `main`. Each seat sets it for itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes diff --git a/.claude-plugin/fleet-skills/.source-digests/session-handoff b/.claude-plugin/fleet-skills/.source-digests/session-handoff index ab56e84ca..5024c3911 100644 --- a/.claude-plugin/fleet-skills/.source-digests/session-handoff +++ b/.claude-plugin/fleet-skills/.source-digests/session-handoff @@ -1 +1 @@ -c1a56863ac2fbd83 +3d46732d46b822f5 diff --git a/.claude-plugin/fleet-skills/.source-digests/unattended-handoff b/.claude-plugin/fleet-skills/.source-digests/unattended-handoff index c6735ff18..93f51fb3c 100644 --- a/.claude-plugin/fleet-skills/.source-digests/unattended-handoff +++ b/.claude-plugin/fleet-skills/.source-digests/unattended-handoff @@ -1 +1 @@ -1d20087d171e45ee +3522e9e38bc56557 diff --git a/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md b/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md index bc19bfd90..ddd07231f 100644 --- a/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md @@ -211,16 +211,19 @@ A maintainer resuming work says little, often only "resume the handoff", and tha the whole procedure below. Run every step without being reminded of any of them. 0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` - into the fleet worktree directory `repo-worktree` names, before any `git` or `$handoff` command: + into a new directory before any `git` or `$handoff` command. `` is a name no directory + there already holds, so the clone never takes a path a task worktree wants: ```sh - git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate- + git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate-hub- ``` That clone is the hub checkout "Running the Chain" sets `$handoff` from, so every later step - runs the chain's script there. The Skill tool's base directory is the maintainer's own hub - checkout, and never the one this procedure runs in. So no step runs `git status`, `git fetch`, - or `git worktree add` there, and none reads it as the hub checkout. + runs the chain's script there. Bring it up to date with `git -C pull --ff-only` before + step 6 writes, since a clone is whatever it last fetched. Wherever this skill was loaded from is + never this session's hub checkout, whatever checkout or snapshot holds it. So no step reads that + location as the hub checkout or runs `$handoff` from it. A task worktree `repo-worktree` creates + off a base clone is a separate act, and that skill governs it. 1. **Pick the link.** Where the maintainer names an issue, take it. Where none is named, read `python3 "$handoff" tracks --repo OWNER/NAME --json`. It prints each open handoff's number, title, track, labels, and updatedAt. It reads them from the repository's issue connection diff --git a/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md b/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md index b58afd90b..ad9200ed8 100644 --- a/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md @@ -48,8 +48,8 @@ One worker runs at a time, so no two rounds claim the same file and no round nee `backlog-burndown` does. Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with -`handoff="/scripts/handoff.py"` (in the hub itself, `scripts/handoff.py`), as -`session-handoff` "Running the Chain" sets it. Each seat sets it for itself, since the picker and +`handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. +`` is a hub checkout of the seat's own on `main`. Each seat sets it for itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes diff --git a/.github/skills/session-handoff/SKILL.md b/.github/skills/session-handoff/SKILL.md index bc19bfd90..ddd07231f 100644 --- a/.github/skills/session-handoff/SKILL.md +++ b/.github/skills/session-handoff/SKILL.md @@ -211,16 +211,19 @@ A maintainer resuming work says little, often only "resume the handoff", and tha the whole procedure below. Run every step without being reminded of any of them. 0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` - into the fleet worktree directory `repo-worktree` names, before any `git` or `$handoff` command: + into a new directory before any `git` or `$handoff` command. `` is a name no directory + there already holds, so the clone never takes a path a task worktree wants: ```sh - git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate- + git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate-hub- ``` That clone is the hub checkout "Running the Chain" sets `$handoff` from, so every later step - runs the chain's script there. The Skill tool's base directory is the maintainer's own hub - checkout, and never the one this procedure runs in. So no step runs `git status`, `git fetch`, - or `git worktree add` there, and none reads it as the hub checkout. + runs the chain's script there. Bring it up to date with `git -C pull --ff-only` before + step 6 writes, since a clone is whatever it last fetched. Wherever this skill was loaded from is + never this session's hub checkout, whatever checkout or snapshot holds it. So no step reads that + location as the hub checkout or runs `$handoff` from it. A task worktree `repo-worktree` creates + off a base clone is a separate act, and that skill governs it. 1. **Pick the link.** Where the maintainer names an issue, take it. Where none is named, read `python3 "$handoff" tracks --repo OWNER/NAME --json`. It prints each open handoff's number, title, track, labels, and updatedAt. It reads them from the repository's issue connection diff --git a/.github/skills/unattended-handoff/SKILL.md b/.github/skills/unattended-handoff/SKILL.md index b58afd90b..ad9200ed8 100644 --- a/.github/skills/unattended-handoff/SKILL.md +++ b/.github/skills/unattended-handoff/SKILL.md @@ -48,8 +48,8 @@ One worker runs at a time, so no two rounds claim the same file and no round nee `backlog-burndown` does. Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with -`handoff="/scripts/handoff.py"` (in the hub itself, `scripts/handoff.py`), as -`session-handoff` "Running the Chain" sets it. Each seat sets it for itself, since the picker and +`handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. +`` is a hub checkout of the seat's own on `main`. Each seat sets it for itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes From def0b14b20d378528b2086d291b9b01457141e4c Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 30 Oct 2026 01:02:54 -0700 Subject: [PATCH 3/4] Name the Clone's Parent and Say When an Unattended Seat Clones Define `` in step 0 again, and have each unattended seat clone its own hub checkout on main the same way, since neither its feature-branch worktree nor the launch checkout qualifies. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/session-handoff/SKILL.md | 5 +++-- .agents/skills/unattended-handoff/SKILL.md | 4 +++- .claude-plugin/fleet-skills/.source-digests/session-handoff | 2 +- .../fleet-skills/.source-digests/unattended-handoff | 2 +- .claude-plugin/fleet-skills/skills/session-handoff/SKILL.md | 5 +++-- .../fleet-skills/skills/unattended-handoff/SKILL.md | 4 +++- .github/skills/session-handoff/SKILL.md | 5 +++-- .github/skills/unattended-handoff/SKILL.md | 4 +++- 8 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.agents/skills/session-handoff/SKILL.md b/.agents/skills/session-handoff/SKILL.md index ddd07231f..b3b4279d9 100644 --- a/.agents/skills/session-handoff/SKILL.md +++ b/.agents/skills/session-handoff/SKILL.md @@ -211,8 +211,9 @@ A maintainer resuming work says little, often only "resume the handoff", and tha the whole procedure below. Run every step without being reminded of any of them. 0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` - into a new directory before any `git` or `$handoff` command. `` is a name no directory - there already holds, so the clone never takes a path a task worktree wants: + into a new directory under ``, the fleet worktree directory `repo-worktree` names, + before any `git` or `$handoff` command. `` is a name no directory under `` + already holds, so the clone never takes a path a task worktree wants: ```sh git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate-hub- diff --git a/.agents/skills/unattended-handoff/SKILL.md b/.agents/skills/unattended-handoff/SKILL.md index ad9200ed8..ac30ef1fc 100644 --- a/.agents/skills/unattended-handoff/SKILL.md +++ b/.agents/skills/unattended-handoff/SKILL.md @@ -49,7 +49,9 @@ One worker runs at a time, so no two rounds claim the same file and no round nee Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with `handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. -`` is a hub checkout of the seat's own on `main`. Each seat sets it for itself, since the picker and +`` is a hub checkout of the seat's own on `main`. So each seat first clones one, as +`session-handoff` "The Attended Session" step 0 does. A worktree on a feature branch is not one, +and neither is the checkout the run was launched in. Each seat sets it for itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes diff --git a/.claude-plugin/fleet-skills/.source-digests/session-handoff b/.claude-plugin/fleet-skills/.source-digests/session-handoff index 5024c3911..57d56df09 100644 --- a/.claude-plugin/fleet-skills/.source-digests/session-handoff +++ b/.claude-plugin/fleet-skills/.source-digests/session-handoff @@ -1 +1 @@ -3d46732d46b822f5 +8cbc582747f43c58 diff --git a/.claude-plugin/fleet-skills/.source-digests/unattended-handoff b/.claude-plugin/fleet-skills/.source-digests/unattended-handoff index 93f51fb3c..0752be809 100644 --- a/.claude-plugin/fleet-skills/.source-digests/unattended-handoff +++ b/.claude-plugin/fleet-skills/.source-digests/unattended-handoff @@ -1 +1 @@ -3522e9e38bc56557 +7ab06dd18b9e3ddd diff --git a/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md b/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md index ddd07231f..b3b4279d9 100644 --- a/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/session-handoff/SKILL.md @@ -211,8 +211,9 @@ A maintainer resuming work says little, often only "resume the handoff", and tha the whole procedure below. Run every step without being reminded of any of them. 0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` - into a new directory before any `git` or `$handoff` command. `` is a name no directory - there already holds, so the clone never takes a path a task worktree wants: + into a new directory under ``, the fleet worktree directory `repo-worktree` names, + before any `git` or `$handoff` command. `` is a name no directory under `` + already holds, so the clone never takes a path a task worktree wants: ```sh git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate-hub- diff --git a/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md b/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md index ad9200ed8..ac30ef1fc 100644 --- a/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md @@ -49,7 +49,9 @@ One worker runs at a time, so no two rounds claim the same file and no round nee Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with `handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. -`` is a hub checkout of the seat's own on `main`. Each seat sets it for itself, since the picker and +`` is a hub checkout of the seat's own on `main`. So each seat first clones one, as +`session-handoff` "The Attended Session" step 0 does. A worktree on a feature branch is not one, +and neither is the checkout the run was launched in. Each seat sets it for itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes diff --git a/.github/skills/session-handoff/SKILL.md b/.github/skills/session-handoff/SKILL.md index ddd07231f..b3b4279d9 100644 --- a/.github/skills/session-handoff/SKILL.md +++ b/.github/skills/session-handoff/SKILL.md @@ -211,8 +211,9 @@ A maintainer resuming work says little, often only "resume the handoff", and tha the whole procedure below. Run every step without being reminded of any of them. 0. **Clone a hub checkout of the session's own, as the first command.** Clone the hub's `main` - into a new directory before any `git` or `$handoff` command. `` is a name no directory - there already holds, so the clone never takes a path a task worktree wants: + into a new directory under ``, the fleet worktree directory `repo-worktree` names, + before any `git` or `$handoff` command. `` is a name no directory under `` + already holds, so the clone never takes a path a task worktree wants: ```sh git clone --branch main https://github.com/ptr727/ProjectTemplate.git /ProjectTemplate-hub- diff --git a/.github/skills/unattended-handoff/SKILL.md b/.github/skills/unattended-handoff/SKILL.md index ad9200ed8..ac30ef1fc 100644 --- a/.github/skills/unattended-handoff/SKILL.md +++ b/.github/skills/unattended-handoff/SKILL.md @@ -49,7 +49,9 @@ One worker runs at a time, so no two rounds claim the same file and no round nee Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with `handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. -`` is a hub checkout of the seat's own on `main`. Each seat sets it for itself, since the picker and +`` is a hub checkout of the seat's own on `main`. So each seat first clones one, as +`session-handoff` "The Attended Session" step 0 does. A worktree on a feature branch is not one, +and neither is the checkout the run was launched in. Each seat sets it for itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes From 9e0a7def02915c64a0999812fc9fec4d0f760665 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 30 Oct 2026 01:04:38 -0700 Subject: [PATCH 4/4] Scope the Hub Clone to the Picker and the Worker The orchestrator runs one command and never the chain's script, so only the picker and the worker clone a hub checkout. The picker's write limit now names its own clone beside the handoff it creates. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/unattended-handoff/SKILL.md | 12 ++++++------ .../fleet-skills/.source-digests/unattended-handoff | 2 +- .../fleet-skills/skills/unattended-handoff/SKILL.md | 12 ++++++------ .github/skills/unattended-handoff/SKILL.md | 12 ++++++------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.agents/skills/unattended-handoff/SKILL.md b/.agents/skills/unattended-handoff/SKILL.md index ac30ef1fc..f7bffc1ca 100644 --- a/.agents/skills/unattended-handoff/SKILL.md +++ b/.agents/skills/unattended-handoff/SKILL.md @@ -49,10 +49,10 @@ One worker runs at a time, so no two rounds claim the same file and no round nee Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with `handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. -`` is a hub checkout of the seat's own on `main`. So each seat first clones one, as -`session-handoff` "The Attended Session" step 0 does. A worktree on a feature branch is not one, -and neither is the checkout the run was launched in. Each seat sets it for itself, since the picker and -the worker are separate subagents and share no shell. +`` is a hub checkout of the seat's own on `main`. So the picker and the worker each +first clone one, as `session-handoff` "The Attended Session" step 0 does. A worktree on a feature +branch is not one, and neither is the checkout the run was launched in. Each sets `$handoff` for +itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes @@ -274,8 +274,8 @@ does not qualify, since skipping one costs nothing and a guess costs a revert an That skill's rules on the body bind it. 5. **Choose the worker's tier** by `backlog-burndown`'s "Choosing the Worker's Model Tier", naming `frontier` or `standard` and never a model. -6. **Reply with one line.** A picker writes nothing but the handoff it creates, and returns `STOP` - where a read it needs cannot run. +6. **Reply with one line.** A picker writes nothing but the handoff it creates and its own hub + clone, and returns `STOP` where a read it needs cannot run. ## The Worker diff --git a/.claude-plugin/fleet-skills/.source-digests/unattended-handoff b/.claude-plugin/fleet-skills/.source-digests/unattended-handoff index 0752be809..512a4f44e 100644 --- a/.claude-plugin/fleet-skills/.source-digests/unattended-handoff +++ b/.claude-plugin/fleet-skills/.source-digests/unattended-handoff @@ -1 +1 @@ -7ab06dd18b9e3ddd +e3c16ac2f356aacb diff --git a/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md b/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md index ac30ef1fc..f7bffc1ca 100644 --- a/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md @@ -49,10 +49,10 @@ One worker runs at a time, so no two rounds claim the same file and no round nee Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with `handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. -`` is a hub checkout of the seat's own on `main`. So each seat first clones one, as -`session-handoff` "The Attended Session" step 0 does. A worktree on a feature branch is not one, -and neither is the checkout the run was launched in. Each seat sets it for itself, since the picker and -the worker are separate subagents and share no shell. +`` is a hub checkout of the seat's own on `main`. So the picker and the worker each +first clone one, as `session-handoff` "The Attended Session" step 0 does. A worktree on a feature +branch is not one, and neither is the checkout the run was launched in. Each sets `$handoff` for +itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes @@ -274,8 +274,8 @@ does not qualify, since skipping one costs nothing and a guess costs a revert an That skill's rules on the body bind it. 5. **Choose the worker's tier** by `backlog-burndown`'s "Choosing the Worker's Model Tier", naming `frontier` or `standard` and never a model. -6. **Reply with one line.** A picker writes nothing but the handoff it creates, and returns `STOP` - where a read it needs cannot run. +6. **Reply with one line.** A picker writes nothing but the handoff it creates and its own hub + clone, and returns `STOP` where a read it needs cannot run. ## The Worker diff --git a/.github/skills/unattended-handoff/SKILL.md b/.github/skills/unattended-handoff/SKILL.md index ac30ef1fc..f7bffc1ca 100644 --- a/.github/skills/unattended-handoff/SKILL.md +++ b/.github/skills/unattended-handoff/SKILL.md @@ -49,10 +49,10 @@ One worker runs at a time, so no two rounds claim the same file and no round nee Every command below that runs the chain's script writes it as `python3 "$handoff" ...`, with `handoff="/scripts/handoff.py"`, as `session-handoff` "Running the Chain" sets it. -`` is a hub checkout of the seat's own on `main`. So each seat first clones one, as -`session-handoff` "The Attended Session" step 0 does. A worktree on a feature branch is not one, -and neither is the checkout the run was launched in. Each seat sets it for itself, since the picker and -the worker are separate subagents and share no shell. +`` is a hub checkout of the seat's own on `main`. So the picker and the worker each +first clone one, as `session-handoff` "The Attended Session" step 0 does. A worktree on a feature +branch is not one, and neither is the checkout the run was launched in. Each sets `$handoff` for +itself, since the picker and the worker are separate subagents and share no shell. ## Invocation and What It Authorizes @@ -274,8 +274,8 @@ does not qualify, since skipping one costs nothing and a guess costs a revert an That skill's rules on the body bind it. 5. **Choose the worker's tier** by `backlog-burndown`'s "Choosing the Worker's Model Tier", naming `frontier` or `standard` and never a model. -6. **Reply with one line.** A picker writes nothing but the handoff it creates, and returns `STOP` - where a read it needs cannot run. +6. **Reply with one line.** A picker writes nothing but the handoff it creates and its own hub + clone, and returns `STOP` where a read it needs cannot run. ## The Worker