Limit the git lines that bin/handoff pickup prints #1543

Closed
opened 2026-11-04 17:05:37 +00:00 by jared · 3 comments
Owner

Problem

bin/handoff pickup injects git lines with no size limit. On 2026-11-04 in cc-os, a pickup printed 15 worktree: lines, and most named old agent-* worktrees that the handoff did not mention. That output costs about 1.3 KB on each pickup. A large working tree printed 26 status: lines. commit <sha>: lists every branch that holds the commit, so an old SHA can list many branches.

Reproduce

plugins/os/bin/handoff pickup <path> --project-root . --session S | grep -c '^worktree:'

Approach

Required work:

  1. In Handoff::LiveState, print a worktree: line only when the full handoff text names that worktree's path or branch. Match the branch as a whole word. PickupCommand gives LiveState the full text for this filter. References for tickets, commits, and paths still come from Document#progress. — check: present worktree in plugins/os/lib/handoff/live_state.rb
  2. In Handoff::WorkingState, print at most 20 status: lines, then one status: +N more line. This applies to pickup and prepare. — check: present more in plugins/os/lib/handoff/working_state.rb
  3. In the commit <sha>: line, print on main alone when main holds the commit, or on master alone when master holds it and main does not. Otherwise print the first three branches, then +N more when more exist. — check: present + in plugins/os/lib/handoff/live_state.rb
  4. In /os:pickup, state that a worktree line prints only for a worktree that the handoff names. — check: present handoff names in plugins/os/skills/pickup/SKILL.md
  5. Add one History row to docs/implementation-status/os.md — check: present #1543 in docs/implementation-status/os.md

Acceptance criteria

  1. Given a repository with two linked worktrees and a handoff that names one of them by path, when pickup runs, then the output has a worktree: line for that worktree and none for the other.
  2. Given a handoff that names a worktree only by its branch, and only outside ## Progress, when pickup runs, then the output has a worktree: line for it.
  3. Given a handoff that holds a longer word that contains a worktree's branch name, when pickup runs, then the output has no worktree: line for that worktree.
  4. Given 25 changed files, when pickup or prepare runs, then the output has 20 status: file lines and status: +5 more.
  5. Given 20 changed files, when pickup runs, then the output has 20 status: lines and no + line.
  6. Given a commit on main and on another branch, when pickup runs, then its line says on main |, with no other branch.
  7. Given a commit that only five non-main branches hold, when pickup runs, then its line names the first three branches and +2 more.

Owner sketch

class Handoff::LiveState
  def lines(text, full_text)
end

class Handoff::WorkingState
  def lines
end

Origin

  • Trigger: user request in this session, after #1542 shipped
  • Improvised this session: none
  • Chain: pickup injects unneeded lines ← git output has no filter or limit ← DESIGN (plugins/os/lib/handoff/live_state.rb, #1542)
  • Root candidate: none found; searched handoff, pickup, LiveState, WorkingState, worktree:, status: lines, git lines
  • Where: plugins/os/lib/handoff/live_state.rb; plugins/os/lib/handoff/working_state.rb
  • Session: 914a3148-8417-4934-9c2d-748527da22e6
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/914a3148-8417-4934-9c2d-748527da22e6.jsonl

VERDICT: CREATE

## Problem `bin/handoff pickup` injects git lines with no size limit. On 2026-11-04 in cc-os, a pickup printed 15 `worktree:` lines, and most named old `agent-*` worktrees that the handoff did not mention. That output costs about 1.3 KB on each pickup. A large working tree printed 26 `status:` lines. `commit <sha>:` lists every branch that holds the commit, so an old SHA can list many branches. ## Reproduce ``` plugins/os/bin/handoff pickup <path> --project-root . --session S | grep -c '^worktree:' ``` ## Approach Required work: 1. In `Handoff::LiveState`, print a `worktree:` line only when the full handoff text names that worktree's path or branch. Match the branch as a whole word. `PickupCommand` gives `LiveState` the full text for this filter. References for tickets, commits, and paths still come from `Document#progress`. — check: present `worktree` in `plugins/os/lib/handoff/live_state.rb` 2. In `Handoff::WorkingState`, print at most 20 `status:` lines, then one `status: +N more` line. This applies to `pickup` and `prepare`. — check: present `more` in `plugins/os/lib/handoff/working_state.rb` 3. In the `commit <sha>:` line, print `on main` alone when `main` holds the commit, or `on master` alone when `master` holds it and `main` does not. Otherwise print the first three branches, then `+N more` when more exist. — check: present `+` in `plugins/os/lib/handoff/live_state.rb` 4. In `/os:pickup`, state that a `worktree` line prints only for a worktree that the handoff names. — check: present `handoff names` in `plugins/os/skills/pickup/SKILL.md` 5. Add one History row to `docs/implementation-status/os.md` — check: present `#1543` in `docs/implementation-status/os.md` ## Acceptance criteria 1. Given a repository with two linked worktrees and a handoff that names one of them by path, when `pickup` runs, then the output has a `worktree:` line for that worktree and none for the other. 2. Given a handoff that names a worktree only by its branch, and only outside `## Progress`, when `pickup` runs, then the output has a `worktree:` line for it. 3. Given a handoff that holds a longer word that contains a worktree's branch name, when `pickup` runs, then the output has no `worktree:` line for that worktree. 4. Given 25 changed files, when `pickup` or `prepare` runs, then the output has 20 `status:` file lines and `status: +5 more`. 5. Given 20 changed files, when `pickup` runs, then the output has 20 `status:` lines and no `+` line. 6. Given a commit on `main` and on another branch, when `pickup` runs, then its line says `on main |`, with no other branch. 7. Given a commit that only five non-main branches hold, when `pickup` runs, then its line names the first three branches and `+2 more`. ## Owner sketch ```ruby class Handoff::LiveState def lines(text, full_text) end class Handoff::WorkingState def lines end ``` ## Origin - Trigger: user request in this session, after #1542 shipped - Improvised this session: none - Chain: pickup injects unneeded lines ← git output has no filter or limit ← DESIGN (`plugins/os/lib/handoff/live_state.rb`, #1542) - Root candidate: none found; searched handoff, pickup, LiveState, WorkingState, worktree:, status: lines, git lines - Where: plugins/os/lib/handoff/live_state.rb; plugins/os/lib/handoff/working_state.rb - Session: 914a3148-8417-4934-9c2d-748527da22e6 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/914a3148-8417-4934-9c2d-748527da22e6.jsonl VERDICT: CREATE
Author
Owner

Work started on branch ticket-1543.

Work started on branch ticket-1543.
Author
Owner

Resolution

Done: pickup prints a worktree line only for a worktree the handoff names; status stops at 20 lines plus a count; a commit on main prints main alone, otherwise three branches and a count.

Evidence: main 3dbcc38a; plugins/os suite 236 runs, 0 failures; rubocop clean; worktree lines fell from 15 to 0 on a test handoff. Hand-finished after implementation 229 escalated; one design audit run, findings fixed or answered.

Follow-ups: map red-round rule on a green-by-design boundary test captured through /os-backlog:capture

## Resolution **Done:** pickup prints a worktree line only for a worktree the handoff names; status stops at 20 lines plus a count; a commit on main prints main alone, otherwise three branches and a count. **Evidence:** main 3dbcc38a; plugins/os suite 236 runs, 0 failures; rubocop clean; worktree lines fell from 15 to 0 on a test handoff. Hand-finished after implementation 229 escalated; one design audit run, findings fixed or answered. **Follow-ups:** map red-round rule on a green-by-design boundary test captured through /os-backlog:capture
jared closed this issue 2026-11-04 17:27:52 +00:00
Author
Owner

Correction: the close comment cites main 3dbcc38a, but that commit was not on main at close time. worktree finish had exited 2 because main moved. The merge landed after the close; the merge commit on main is 0ae8ec37, and the suite passes there with 236 runs and 0 failures.

Correction: the close comment cites main 3dbcc38a, but that commit was not on main at close time. worktree finish had exited 2 because main moved. The merge landed after the close; the merge commit on main is 0ae8ec37, and the suite passes there with 236 runs and 0 failures.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#1543
No description provided.