garrytan / garrytan/gstack

Proposal: SKILL.local.md overlay for per-user skill customization

Open
#1,759 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

# Proposal: `SKILL.local.md` overlay for per-user skill customization

## Problem

gstack ships authoritative skill prompts in `~/.claude/skills/gstack//SKILL.md` (generated from `SKILL.md.tmpl` via `scripts/gen-skill-docs.ts`). When a user wants to tweak a skill for their own workflow or workspace, the only option today is to edit the generated `SKILL.md` (or its `.tmpl` source). Both are clobbered on the next `gstack-upgrade`, so the customization silently disappears the next time the user upgrades.

In practice this pushes users toward one of three workarounds:

1. Keep a side-channel patch and re-apply after every upgrade. Easy to forget, hard to audit.
2. Fork gstack and self-merge. Heavy for a 5-line workspace prompt.
3. Skip upgrades to preserve customization. Drifts further from upstream over time.

None of these are good. Per-user prompt customization seems like a first-class use case worth supporting natively.

## Concrete use cases

A few examples from real usage, biased toward workspace-aware shaping:

- **Workspace project routing in `/investigate` (avee, a multi-repo healthcare SaaS workspace).** Before forming a hypothesis, ask the user *which* codebase the symptom lives in: `avicennacloud`, `iaso`, `front-framework`, `online-booking-panel`, `oscar-avee`. Plus environment (prod/staging/local), affected user role, repro availability, recent suspected change. Generic gstack can't know that list — it's workspace-specific.
- **Workspace-specific glossary in `/review`.** Append "in this repo, 'provider' means clinician, not framework provider" so the reviewer doesn't get confused by domain terms.
- **Project-specific test commands in `/qa`.** Append "this project uses `just test`, not `npm test`, and Docker must be running" without forking the whole skill.
- **Team conventions in `/ship`.** Append "always include `Refs: ` in commit body" without touching the generated body.

These are not bug fixes to gstack. They're personal/workspace extensions that should live next to the user's CLAUDE.md, not in the gstack tree.

## Proposed design (sketch — looking for maintainer input)

A `SKILL.local.md` overlay file, mirroring how `CLAUDE.local.md` extends `CLAUDE.md`:

- Location: `~/.claude/skills//SKILL.local.md` (next to the existing `SKILL.md` symlink), or a workspace-scoped variant like `/.claude/skills//SKILL.local.md` for team-shared customizations.
- Discovery: at skill invocation time (or at `gen-skill-docs` time, whichever the maintainer prefers), if the overlay exists, append its contents to the generated `SKILL.md` body under a fenced section like `## User overlay (SKILL.local.md)`.
- Not committed to the gstack repo. Listed in `.gitignore` of any user repo that uses dev mode.
- Survives `gstack-upgrade` because it lives outside the generator's write paths.
- Frontmatter merge: probably *not* — keep overlays body-only to avoid clashes with `name:`, `allowed-tools:`, `triggers:`. Open question.

Open questions I'd want your call on:

1. **Append at invocation time vs at gen time?**
- *Invocation-time append* (the host reads SKILL.md, then concatenates SKILL.local.md if present): keeps `gen-skill-docs` untouched, but requires every host adapter to learn the convention.
- *Gen-time inclusion* (gen-skill-docs concatenates and writes the final file): single source of truth in the output, but means the generator has to be re-run after editing the overlay. Could be solved with a `--watch` mode or a lightweight `merge` subcommand.
2. **Personal (`~/.claude/skills//SKILL.local.md`) vs workspace (`.claude/skills//SKILL.local.md` in the repo)?** Both are useful — workspace for team-shared, personal for per-developer. Maybe support both with workspace taking precedence?
3. **Placement of the appended content.** Always at the end of the body? Or a `{{USER_OVERLAY}}` placeholder in the `.tmpl` that contributors can position deliberately (e.g., before Phase 1 in `/investigate`)?
4. **Scope.** Overlays for body content only, or also for adjusting frontmatter fields like extra `triggers:`? Frontmatter feels risky.
5. **Discovery / docs.** Should `bin/dev-setup` or `setup` mention overlays? `learn` skill surface them?

## Alternatives considered

- **Forking gstack per workspace.** Heavy for small tweaks; cuts the user off from upstream updates.
- **CLAUDE.md as the overlay surface.** Already happens informally (gstack reads CLAUDE.md for context), but the skill prompt body isn't appended from there — only used as runtime context. Not the same thing.
- **A new `gstack-config` key per skill.** Could work for boolean knobs ("ask project question: yes/no") but doesn't scale to free-form prose additions.
- **A patch file under `~/.gstack/patches/.diff`.** Works, but diffs are fragile across upstream changes; prose overlay is more upgrade-resistant.

## What I'd want to do next

If the direction sounds right, I'd take a stab at a PR. Before I write code, would you confirm:

- Append-time (invocation vs gen) preference?
- Personal vs workspace vs both?
- Placement (end-of-body vs `{{USER_OVERLAY}}` placeholder)?
- Any concerns about overlays escaping gstack's evaluation harness (`test:evals`, slop-scan)?

Happy to iterate the design here before writing anything.

---

Context: I hit this while wanting to add a workspace-aware "which project is this bug in?" step to `/investigate` for a multi-repo workspace. Patched `SKILL.md.tmpl` directly, realized it'd be clobbered on the next upgrade. Seemed like a generally useful primitive to land upstream rather than carry as a fork.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.