docs: update project documentation for v1.80.0.0

README troubleshooting + manual uninstall cover the skill ownership gate
(.gstack-owned marker, ~/.gstack/backups/skills/<ts>/, foreign same-name
skills left untouched). CLAUDE.md and CONTRIBUTING carry the ownership and
best-effort Chromium bootstrap invariants for people editing setup and
gstack-relink. PROJECT_STRUCTURE gains careful/, freeze/, guard/, unfreeze/,
gstack-upgrade/, gstack-relink, and the setup/relink/hook test files.
TESTING_INTERNALS documents the anchor-sliced setup harness convention.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-09-04 18:35:29 +00:00
co-authored by Claude Fable 5.1
parent 25fe33d447
commit 23fccb982a
5 changed files with 65 additions and 4 deletions
+5 -1
View File
@@ -460,6 +460,8 @@ When Conductor creates a new workspace, `bin/dev-setup` runs automatically. It d
- **`.claude/skills/` is gitignored.** The symlinks never get committed.
- **Never write raw `ln -snf` in `setup`.** Every link site in `setup` MUST route through the `_link_or_copy SRC DST` helper near the `IS_WINDOWS` detection. The helper preserves `ln -snf` on Unix and switches to `cp -R` / `cp -f` on Windows without Developer Mode, where plain `ln -snf` produces frozen file copies that don't refresh on `git pull`. `test/setup-windows-fallback.test.ts` enforces this with a static invariant — a single raw `ln` call outside the helper body fails CI.
- **Synchronous subagent dispatches must state the flag.** Claude Code runs Agent-tool subagents in the background by default (since v2.1.198), so any template step that dispatches a subagent and consumes its output must carry `run_in_background: false`. Use the `{{FOREGROUND_DISPATCH_NOTE}}` placeholder (`scripts/resolvers/constants.ts`) instead of hand-writing the guidance, and add the generated carrier file to `GENERATED_WITH_GUIDANCE` in `test/run-in-background-guidance.test.ts` in the same commit — its structural scanner fails CI on any generated dispatch imperative that lacks the flag.
- **Never delete or link over a skill entry `setup` cannot prove is gstack's.** Every destructive site in `setup` (the linker, the alias installer, both prefix-flip cleanups) and in `bin/gstack-relink` goes through the ownership helpers (`_claude_entry_is_ours` / `_claude_entry_owned_strongly` in `setup`, `_entry_is_ours` / `_entry_owned_strongly` in relink). A symlink into gstack or the `.gstack-owned` marker proves the whole directory; a byte-identical or generated-banner SKILL.md proves only that file, and a differing one is moved to `~/.gstack/backups/skills/<ts>/` first. `test/setup-link-ownership.test.ts`, `test/setup-cleanup-orphans.test.ts`, and `test/relink.test.ts` pin it. The rule is duplicated in the two scripts until the shared helper filed in TODOS.md lands: change both.
- **`./setup` never fails on Chromium.** The Playwright bootstrap (section `# 2` of `setup`) is best-effort and bounded: every failure becomes a reason code (`skipped`, `chromium-install`, `chromium-install-timeout`, `chromium-install-locked`, `windows-no-node`, `windows-node-modules`, `post-install-launch`) printed in the final summary alongside the browser-dependent skills, and skill registration always runs. `GSTACK_PLAYWRIGHT_INSTALL_TIMEOUT=<seconds>` (default 600) bounds the download; `GSTACK_SKIP_PLAYWRIGHT=1` skips it, the right knob for a no-browser box or a setup-only test loop. Anything you add after the bootstrap must stay independent of the browser. `test/setup-playwright-best-effort.test.ts` pins the block.
## Testing your changes in a real project
@@ -513,7 +515,9 @@ cd .claude/skills/gstack && ./setup --no-prefix # switch to /qa, /ship
cd .claude/skills/gstack && ./setup --prefix # switch to /gstack-qa, /gstack-ship
```
Setup cleans up the old symlinks automatically. No manual cleanup needed.
Setup cleans up the old symlinks automatically. No manual cleanup needed. Only
entries gstack created are removed: a skill of your own that shares a name (a
hand-written `qa/`, say) is left in place and named in setup's final summary.
### Alternative: point your global install at a branch