Build worktree Thor CLI (bin/worktree start|finish) and merge skills into /os:worktree #508

Closed
opened 2026-08-25 17:55:54 +00:00 by jared · 3 comments
Owner

Context

The #505 finish run showed /os:worktree-finish improvising: git ops are locked to the worktree, so the session exited with keep, merged from the main checkout, re-entered to remove, and hit ExitWorktree's ownership refusal. Decision (user-approved 2026-08-25): move the mechanics into a deterministic Thor CLI plugins/os/bin/worktree backed by plugins/os/lib/worktree/ small command classes, and collapse the two skills into one /os:worktree start|finish skill that owns only session movement (EnterWorktree/ExitWorktree) and judgment (conflicts, commit messages). Thor is assumed globally installed — no Gemfile, no fallback hardening. Precedent: plugins/os-sdlc/bin/os-sdlc-runner is already a Thor CLI.

Tasks

  • Scaffold plugins/os/bin/worktree (Thor, #!/usr/bin/env ruby) + plugins/os/lib/worktree/ following the os-sdlc bin/lib pattern
  • start <name>: git worktree add under .claude/worktrees/, branch creation, plugin-symlink setup, then symlink gitignored per-project state: .cc-os dir and .sdlc/pipeline.db if present (NOT .sdlc/ wholesale — it holds tracked files, per ADR-0143), plus extra paths from a new .cc-os/config key (working name worktree-symlinks, comma-separated to fit the flat key=value format in plugins/os/hooks/state.py)
  • finish <branch>: sync-check loop — detect base moved since worktree creation; distinct exit codes: done / base-moved (merge base into branch, AI resolves conflicts) / conflicts (naming files); when clean: merge branch into base from the main checkout, verify branch is ancestor + no conflict markers, run bin/refresh-plugins when plugins/ changed, then git worktree remove + branch delete. The script never moves the session; removal happens after the session exits with keep, avoiding the ownership refusal
  • Merge skills into plugins/os/skills/worktree/SKILL.md (/os:worktree start|finish, argument-hint frontmatter, description keeps both trigger phrasings); delete the two old skill dirs
  • Rename sweep — replace old names in: docs/implementation-status.md, docs/implementation-status/os.md, docs/adr/0143, docs/adr/0106, plugins/os-sdlc/skills/implement/SKILL.md, plugins/cc-architect/references/conventions/cc-os-naming.md, plugins/os/CLAUDE.md (nothing live under ~/.claude per sweep 2026-08-25)
  • Superseding ADR for ADR-0085/0087 (also note 0085 still names os-shortcuts as the skills' home — location drift)
  • Update plugins/os/CLAUDE.md component map + invariants.md; History row in docs/implementation-status/os.md; bin/refresh-plugins after skill changes

Acceptance criteria

  • bin/worktree start x produces a worktree with .cc-os + pipeline.db symlinks and configured extras; exits 0 and prints the path
  • bin/worktree finish exit codes distinguish done / base-moved / conflicts, and refuses removal until branch is ancestor of base
  • Old skill names resolve nowhere; /os:worktree invocable after cache refresh

Out of scope: Gemfile/bundler hardening, thor-availability fallbacks, bulk changes to ADR-0143's symlink decision.

Origin

  • Trigger: /os:worktree-finish run closing #505 (ExitWorktree ownership refusal, screenshot 2026-08-25)
  • Improvised this session: manual git worktree remove + git branch -d after the tool refusal
  • Chain: ownership refusal ← skill re-enters worktree to remove after merging from main checkout ← skill prose never states where the merge runs ← DESIGN (plugins/os/skills/worktree-finish/SKILL.md, ADR-0087)
  • Root candidate: this ticket
## Context The #505 finish run showed /os:worktree-finish improvising: git ops are locked to the worktree, so the session exited with keep, merged from the main checkout, re-entered to remove, and hit ExitWorktree's ownership refusal. Decision (user-approved 2026-08-25): move the mechanics into a deterministic Thor CLI `plugins/os/bin/worktree` backed by `plugins/os/lib/worktree/` small command classes, and collapse the two skills into one `/os:worktree start|finish` skill that owns only session movement (EnterWorktree/ExitWorktree) and judgment (conflicts, commit messages). Thor is assumed globally installed — no Gemfile, no fallback hardening. Precedent: `plugins/os-sdlc/bin/os-sdlc-runner` is already a Thor CLI. ## Tasks - [ ] Scaffold `plugins/os/bin/worktree` (Thor, `#!/usr/bin/env ruby`) + `plugins/os/lib/worktree/` following the os-sdlc bin/lib pattern - [ ] `start <name>`: git worktree add under .claude/worktrees/, branch creation, plugin-symlink setup, then symlink gitignored per-project state: `.cc-os` dir and `.sdlc/pipeline.db` if present (NOT `.sdlc/` wholesale — it holds tracked files, per ADR-0143), plus extra paths from a new `.cc-os/config` key (working name `worktree-symlinks`, comma-separated to fit the flat key=value format in plugins/os/hooks/state.py) - [ ] `finish <branch>`: sync-check loop — detect base moved since worktree creation; distinct exit codes: done / base-moved (merge base into branch, AI resolves conflicts) / conflicts (naming files); when clean: merge branch into base from the main checkout, verify branch is ancestor + no conflict markers, run bin/refresh-plugins when plugins/ changed, then git worktree remove + branch delete. The script never moves the session; removal happens after the session exits with keep, avoiding the ownership refusal - [ ] Merge skills into `plugins/os/skills/worktree/SKILL.md` (`/os:worktree start|finish`, argument-hint frontmatter, description keeps both trigger phrasings); delete the two old skill dirs - [ ] Rename sweep — replace old names in: docs/implementation-status.md, docs/implementation-status/os.md, docs/adr/0143, docs/adr/0106, plugins/os-sdlc/skills/implement/SKILL.md, plugins/cc-architect/references/conventions/cc-os-naming.md, plugins/os/CLAUDE.md (nothing live under ~/.claude per sweep 2026-08-25) - [ ] Superseding ADR for ADR-0085/0087 (also note 0085 still names os-shortcuts as the skills' home — location drift) - [ ] Update plugins/os/CLAUDE.md component map + invariants.md; History row in docs/implementation-status/os.md; bin/refresh-plugins after skill changes ## Acceptance criteria - [ ] `bin/worktree start x` produces a worktree with .cc-os + pipeline.db symlinks and configured extras; exits 0 and prints the path - [ ] `bin/worktree finish` exit codes distinguish done / base-moved / conflicts, and refuses removal until branch is ancestor of base - [ ] Old skill names resolve nowhere; `/os:worktree` invocable after cache refresh Out of scope: Gemfile/bundler hardening, thor-availability fallbacks, bulk changes to ADR-0143's symlink decision. ## Origin - Trigger: /os:worktree-finish run closing #505 (ExitWorktree ownership refusal, screenshot 2026-08-25) - Improvised this session: manual `git worktree remove` + `git branch -d` after the tool refusal - Chain: ownership refusal ← skill re-enters worktree to remove after merging from main checkout ← skill prose never states where the merge runs ← DESIGN (plugins/os/skills/worktree-finish/SKILL.md, ADR-0087) - Root candidate: this ticket
Author
Owner

Work started on branch worktree-ticket-508-worktree-cli via /os-sdlc:implement (session 4b7df35f).

Work started on branch worktree-ticket-508-worktree-cli via /os-sdlc:implement (session 4b7df35f).
Author
Owner

implementation_failed: pipeline bound exhausted at behavior-verifier (verdict fail, dispatch 27, session 4b7df35f).

Failed step: behavior-verifier after increment 3.
Gate details: AC1 (bin/worktree start with .cc-os + pipeline.db + configured extra symlinks) is implemented and green — tests worktree_cli_start_test.rb, pipeline_db and extra_symlinks siblings. AC2 (finish exit codes done/base-moved/conflicts, ancestor refusal) and AC3 (skill merge into /os:worktree) have no implementation: Worktree::CLI declares only start, and both old skill dirs still exist.

Work lives on branch worktree-ticket-508-worktree-cli (not merged). Recovery requires a fresh implementation-open.

implementation_failed: pipeline bound exhausted at behavior-verifier (verdict fail, dispatch 27, session 4b7df35f). Failed step: behavior-verifier after increment 3. Gate details: AC1 (bin/worktree start with .cc-os + pipeline.db + configured extra symlinks) is implemented and green — tests worktree_cli_start_test.rb, pipeline_db and extra_symlinks siblings. AC2 (finish exit codes done/base-moved/conflicts, ancestor refusal) and AC3 (skill merge into /os:worktree) have no implementation: Worktree::CLI declares only start, and both old skill dirs still exist. Work lives on branch worktree-ticket-508-worktree-cli (not merged). Recovery requires a fresh implementation-open.
Author
Owner

Resolution

Done: Thor CLI plugins/os/bin/worktree (start|finish) built TDD via the os-sdlc pipeline on branch worktree-ticket-508-worktree-cli: start creates the worktree with .cc-os + pipeline.db symlinks and worktree-symlinks config extras; finish distinguishes exit 0 done / 1 conflicts (naming files) / 2 base-moved and refuses removal until the branch is an ancestor of base. Skills merged into /os:worktree (old dirs deleted), rename sweep across 7 docs files, ADR-0150 supersedes 0085/0087, invariants + History row updated, os target added to .sdlc/project.yaml.

Evidence: implementation_complete at dispatch 66 (behavior-verifier pass, session 4b7df35f); suite ruby plugins/os/tests/all.rb green across 9 worktree tests; gate history in .sdlc/pipeline.db; ADR docs/adr/0150-worktree-mechanics-move-to-a-deterministic-thor-cli-skills-merge-into-os-worktree.md

Follow-ups: #511 progress-based loop-guard reset (pre-existing, user-approved; implementation ready on branch worktree-agent-aac9c5cd71a72ccd3, ADR renumber needed at merge); #512 poodr map test-repair route (captured this session with skeptic VERDICT: CREATE); none further

## Resolution **Done:** Thor CLI plugins/os/bin/worktree (start|finish) built TDD via the os-sdlc pipeline on branch worktree-ticket-508-worktree-cli: start creates the worktree with .cc-os + pipeline.db symlinks and worktree-symlinks config extras; finish distinguishes exit 0 done / 1 conflicts (naming files) / 2 base-moved and refuses removal until the branch is an ancestor of base. Skills merged into /os:worktree (old dirs deleted), rename sweep across 7 docs files, ADR-0150 supersedes 0085/0087, invariants + History row updated, os target added to .sdlc/project.yaml. **Evidence:** implementation_complete at dispatch 66 (behavior-verifier pass, session 4b7df35f); suite ruby plugins/os/tests/all.rb green across 9 worktree tests; gate history in .sdlc/pipeline.db; ADR docs/adr/0150-worktree-mechanics-move-to-a-deterministic-thor-cli-skills-merge-into-os-worktree.md **Follow-ups:** #511 progress-based loop-guard reset (pre-existing, user-approved; implementation ready on branch worktree-agent-aac9c5cd71a72ccd3, ADR renumber needed at merge); #512 poodr map test-repair route (captured this session with skeptic VERDICT: CREATE); none further
jared closed this issue 2026-08-25 21:11:40 +00:00
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#508
No description provided.