User Story
As a split-portfolio adopter who wants to ship company-specific proprietary skills (e.g. /file-internal-bug that posts to our internal tracker, /check-policy against our private compliance corpus) AND company-wide handbooks that contain proprietary policy or IP, I want both to live in the private sibling repo — so the public fork holds only the stock framework plus my generic customisations, not my organization's confidential content.
Acceptance Criteria
Storage layout in the private repo
Discovery — custom skills
Discovery — custom handbooks
Single-fork mode unaffected
/setup integration
Docs
Tests
Design Notes
Why symlinks for skills. Claude Code discovers skills via .claude/skills/<name>/SKILL.md glob — we don't control that glob path. Two viable options: (a) symlink into the discovered location, (b) ship a Claude Code plugin per private skill. Option (a) is cheaper and works without a marketplace round-trip; option (b) is the cleaner long-term shape if Claude Code's plugin model becomes the canonical extension surface. v1 picks (a) for speed; v2 can swap to (b) without changing the storage layout.
Why custom-handbooks/ is just an additional Rex discovery path (not symlinked). Handbooks aren't discovered by Claude Code — they're discovered by Rex's agent prompt. So Rex's prompt simply adds a second glob source. No symlinks needed; less fragile.
Why "custom wins" on skill name collisions. If an adopter ships a custom skill with the same name as a framework skill, they did so deliberately to override. Surfacing a SessionStart warning makes the override visible without forcing a rename.
Depends on #242. This ticket assumes the v2 split-portfolio layout (config block extended with workspace + onboarding paths). Easier to build both together than to retrofit. Logical sequencing: #242 lands first → this PR layers on top.
Out of Scope
- Per-team / per-project handbook overrides (still framework-level only — file a separate ticket if multi-team adopters need it)
- Encryption on top of gitignore for the private custom dirs
- Distribution to OTHER organizations (these customs are private to one org by design — sharing across orgs is what the public framework + handbooks are for)
- A
/custom-skill authoring helper (manual cp framework-skill custom-skills/... + edit is fine for v1)
- Multi-version handbook conflict resolution (operator's prose responsibility)
Effort Estimate
TBD — likely 1 day after #242 lands.
User Story
As a split-portfolio adopter who wants to ship company-specific proprietary skills (e.g.
/file-internal-bugthat posts to our internal tracker,/check-policyagainst our private compliance corpus) AND company-wide handbooks that contain proprietary policy or IP, I want both to live in the private sibling repo — so the public fork holds only the stock framework plus my generic customisations, not my organization's confidential content.Acceptance Criteria
Storage layout in the private repo
custom-skills/<name>/SKILL.md— company-specific skillscustom-handbooks/{architecture,general,language/<lang>}/*.md— company-wide handbooks (same path-convention ashandbooks/in the public fork)Discovery — custom skills
_lib-portfolio-paths.shexposesportfolio_custom_skills_dir(default<private_repo>/custom-skills)SessionStart, a new hook (link-custom-skills.sh) ensures every<private_repo>/custom-skills/<name>/is visible to Claude Code via the public fork's.claude/skills/— implementation: gitignored symlinks at.claude/skills/<name>/pointing to the private dirSessionStartwith a visible warningDiscovery — custom handbooks
.claude/agents/code-reviewer.md§ 8 "Adopter Handbooks") gains a second discovery path:<private_repo>/custom-handbooks/, applying the SAME path-convention as the publichandbooks/(architecture/ always-load, language// on diff match, general/ always-load)ENFORCEMENT: blockingmarker behaves identically in custom handbooksSingle-fork mode unaffected
portfolioblock see ZERO behaviour change. Custom skills/handbooks are a split-portfolio feature./setupintegration/setup --split-portfoliocreates the new dirs in the private repo (emptycustom-skills/README.md+custom-handbooks/README.mdexplaining the convention)/setup --enable-private-customs(or part of the/updatemigration path from [Feature] Split-portfolio v2: workspace + onboarding move to private repo, plus /update migration #242) is the entry point for retrofitting existing split-portfolio adoptersDocs
docs/multi-project.md§ "Split-portfolio mode" gains a "Private custom skills + handbooks" subsectionhandbooks/README.mdcross-references the private custom-handbooks layerTests
link-custom-skills.shtests cover: no private repo (no-op), private repo with custom-skills (symlinks created), name collision (custom wins, warning emitted), Windows path (declined gracefully)_lib-portfolio-paths.shtests cover the new helperDesign Notes
Why symlinks for skills. Claude Code discovers skills via
.claude/skills/<name>/SKILL.mdglob — we don't control that glob path. Two viable options: (a) symlink into the discovered location, (b) ship a Claude Code plugin per private skill. Option (a) is cheaper and works without a marketplace round-trip; option (b) is the cleaner long-term shape if Claude Code's plugin model becomes the canonical extension surface. v1 picks (a) for speed; v2 can swap to (b) without changing the storage layout.Why custom-handbooks/ is just an additional Rex discovery path (not symlinked). Handbooks aren't discovered by Claude Code — they're discovered by Rex's agent prompt. So Rex's prompt simply adds a second glob source. No symlinks needed; less fragile.
Why "custom wins" on skill name collisions. If an adopter ships a custom skill with the same name as a framework skill, they did so deliberately to override. Surfacing a SessionStart warning makes the override visible without forcing a rename.
Depends on #242. This ticket assumes the v2 split-portfolio layout (config block extended with workspace + onboarding paths). Easier to build both together than to retrofit. Logical sequencing: #242 lands first → this PR layers on top.
Out of Scope
/custom-skillauthoring helper (manualcp framework-skill custom-skills/...+ edit is fine for v1)Effort Estimate
TBD — likely 1 day after #242 lands.