Skip to content

Load the Factory skills from the worktree as thirdshift-<skill>, replacing the Claude plugin - #400

Merged
JacobStephens2 merged 2 commits into
issue-136from
issue-391
Oct 5, 2026
Merged

JacobStephens2 merged 2 commits into
issue-136from
issue-391

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

The Factory skills stop being a Claude plugin. Each is renamed thirdshift-<skill> in skills/ and names the others in plain prose. thirdshift writes them out once per Command and links each one into the Run's worktree, where Claude Code finds project skills. See ADR 0012.

 Sessions::within(logs, worktree, steps)
-  Plugin::write()                       # temp dir + .claude-plugin/plugin.json
+  skills::link_into(worktree)
+    written_out()                       # temp dir, written once per Command
+    exclude()                           # "/.claude/skills/thirdshift-*" in .git/info/exclude, once, under a lock
+    <worktree>/.claude/skills/thirdshift-<skill> -> <temp>/thirdshift-<skill>
   steps(...)                            # every session, Repair and Resume
-    claude -p … --plugin-dir <dir> …
+    claude -p --permission-mode auto --output-format stream-json --verbose [--resume <id>] <prompt>
 Started::finish
+  skills::remove_written()
-/thirdshift:implement <Issue URL>
-The base branch is <base>. Review with /thirdshift:code-review using <base> as the fixed point.
+/thirdshift-implement <Issue URL>
+The base branch is <base>. Review with the `thirdshift-code-review` skill using <base> as the fixed point.
 skills/
-├── implement/  code-review/  pr/  tdd/  …
+├── thirdshift-implement/  thirdshift-code-review/  thirdshift-pr/  thirdshift-tdd/  …
+└── thirdshift-resolving-merge-conflicts/   # restored, see below

prompts/ and the Prompts and skills page are regenerated. The home page links point to the new skill anchors. ADR 0001's plugin consequence is marked as replaced by ADR 0012.

resolving-merge-conflicts had been dropped from skills/ by a skills sync (a2afa36), but the conflict Repair prompts still invoke it. It is restored here as thirdshift-resolving-merge-conflicts. That also fixes fresh_run's skills test, which was already failing on the base branch.

Evidence

  • Before: cargo test --test fresh_run → loads_every_factory_skill_as_the_thirdshift_plugin FAILED (skill resolving-merge-conflicts missing from the plugin). Sessions got --plugin-dir.
    After: cargo test passes in full. cargo clippy --all-targets is clean. The new and changed tests:
fresh_run::runs_claude_headless_…                      argv has no --plugin-dir
fresh_run::finds_every_factory_skill_in_the_worktree…  .claude/skills/thirdshift-*/SKILL.md, name: thirdshift-<skill>
fresh_run::the_linked_skills_are_kept_out_of_git       git status --porcelain is empty; `git add -A` commits no .claude/
fresh_run::a_second_run_adds_no_second_exclude_entry   exclude has exactly one "/.claude/skills/thirdshift-*"
fresh_run::ships_the_mattpocock_skills_mit_notice…     LICENSE is written out beside the linked skills
assert_every_session_found_the_factory_skills()        Resume, conflict Repair, and Architecture review → Spec run's Ticket Runs → Base fix → Spec review

The fake claude now snapshots the skills from its worktree's .claude/skills/, following the links, instead of from a plugin directory.

Merge Danger

Door: two-way

Revert to bring the plugin back. The .git/info/exclude entry it adds to each target repository stays behind, but it's harmless.

Blast Radius: every-session

Every session of every Command now finds its skills in the worktree rather than through --plugin-dir. If Claude Code didn't pick up project skills from a worktree's .claude/skills/ symlinks, every Run would lose its skills. A target repository that already has its own .claude/skills/thirdshift-* file or link gets it replaced in the worktree. A real directory under that name fails the Run.

Unaddressed findings

Standards

  • Global static WRITTEN: Mutex<Option<TempDir>> instead of an owned value passed down (temporal coupling). Skipped. "Once per Command" spans an Architect run's review and the Run it dispatches, and passing a value down would mean threading it through run::run_to_end, Asks and Delivery. The global follows the existing logs module pattern, remove_written is called once in Started::finish, and the tests' empty-$TMPDIR checks would catch a leak. Choose the Harness, Model and Effort on the command line and in the User config, with Claude #392 threads the Harness through the same path and can carry this along if wanted.
  • The thirdshift- prefix is a bare string in several places (EXCLUDE, skill_used_by arms, test FACTORY_SKILLS, fake's filter). Skipped. The occurrences sit across the crate/test boundary, and skill_used_by panics on any skill it doesn't know, so drift is caught.

Spec

  • CI-fix Repair and Resume prompts don't start with /thirdshift-<skill>. Skipped. They never invoked a skill, and no Factory skill fits them. Every prompt that invokes a skill starts with it.
  • No test for a CI-fix Repair, Review Repair or Continuation finding the skills. Skipped. Every session goes through Sessions::within, which links the skills, and the tests already cover a Resume, a Repair and every session kind in a dispatched Spec run.
  • Restoring thirdshift-resolving-merge-conflicts goes beyond the rename. Kept on purpose. The conflict Repair prompts invoke it, so without it their first line would name a missing skill.
  • Exit paths that skip Started::finish would leak the temp dir. A kept Failed-run worktree keeps dangling links. Skipped. No path that runs a session skips finish. The dangling links are excluded from git and replaced when the Run continues.
  • A real .claude/skills/thirdshift-* directory in a target repository fails the link. Skipped as an unlikely edge case outside the spec. The failure names the path.

Closes #391

🤖 Generated with Claude Code

JacobStephens2 and others added 2 commits October 5, 2026 00:06
The Factory skills stop being a Claude plugin. Each is renamed
thirdshift-<skill> in skills/, and names the others in plain prose.
thirdshift writes them out once per Command and links each into the
worktree's .claude/skills/, kept out of git by a /.claude/skills/thirdshift-*
entry in .git/info/exclude, added once. No session gets --plugin-dir, and
each prompt's first line is /thirdshift-<skill>.

Restores resolving-merge-conflicts, dropped from skills/ by a skills
update though the conflict Repair prompts still invoke it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ory skills (#391)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant