Skip to content

Latest commit

 

History

42 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gstack-debloat

ci release tested against gstack v1.84.1 license MIT

v1.1.1 keeps the strip working against gstack v1.84.1: the learnings verification markers are now line-anchored headings, so upstream's new routing prose ("run Prior Learnings and Confidence Calibration") can no longer false-positive a clean strip. v1.1.0 added optional skill pruning, support for newer gstack runtime scripts, and quieter Codex startup with compact skill descriptions.

gstack is a skills framework for AI coding agents (Claude Code, Codex). The QA, code review, shipping, and design-review workflows are useful.

It also ships with a pile of stuff you didn't ask for: telemetry, an auto update-check that fires on every skill invocation, dead gstack-config reads in half the skills, and an /office-hours closing sequence that ends in a YC apply pitch plus a curated funnel of YC/Lightcone/Paul Graham resources with a "want me to open these in your browser?" prompt.

Remote telemetry is only one layer. gstack also writes local analytics, session timelines, and project learnings to ~/.gstack/. Skill names, timestamps, outcomes, durations, and AI-generated "learnings" accumulate on disk even when telemetry is set to off. None of it is opt-in, and all of it costs you tokens and noise on every run.

This script strips all of it. Telemetry, the timeline/learnings persistence layer, the auto update-check, the dead telemetry reads, and the office-hours self-promotion, gone. Cleanly, completely, and automatically after every upgrade, across every install copy (Claude Code, .agents, .kiro, .factory, Codex). The only thing kept is the local builder profile, because that one's actually useful and never leaves your machine.


Before / after

What a skill preamble runs on every invocation, before vs after:

  ## Preamble (run first)
  ```bash
- _UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || ...)   # network call
- [ -n "$_UPD" ] && echo "$_UPD" || true
- _TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry || echo off) # dead read
- _SESSION_ID=...; echo "TELEMETRY: ..."                                       # session tracking
  mkdir -p ~/.gstack/sessions
  ...

And the /office-hours closing sequence:

- A personal note from me, Garry Tan, the creator of GStack: ... apply to Y Combinator?
- ### Founder Resources (all tiers)   # 34-link YC/Lightcone/PG funnel
- "Want me to open any of these in your browser?"
  ### Next-skill recommendations      # the actual useful part, kept

Run --check to see whether your install still has any of it. Since v1.71 that means scanning the runtime scripts too, not just the rendered skills: upstream moved the writes into bin/gstack-skill-start, so a render can look spotless while every JSONL append still fires.


What gets removed

Component What it does Gone
_TEL, _TEL_START, _SESSION_ID Shell vars that track your session Yes
generateTelemetryPrompt() The opt-in prompt (community/anonymous/off) Yes
TEL_PROMPTED flag Tracks whether you've been asked about telemetry Yes
~/.gstack/analytics/ writes Local JSONL logging on every skill run Yes
~/.gstack/projects/*/timeline.jsonl Per-project session timeline Yes
~/.gstack/projects/*/learnings.jsonl Per-project AI-generated learnings Yes
.pending-* file handling Deferred telemetry finalization Yes
"Telemetry (run last)" epilogue End-of-skill duration + outcome logging Yes
gstack-telemetry-log Remote telemetry binary Deleted
gstack-telemetry-sync Remote telemetry sync binary Deleted
gstack-analytics Analytics CLI binary Deleted
gstack-timeline-log / gstack-timeline-read Timeline persistence/readback binaries Neutralized
gstack-learnings-log / gstack-learnings-search Learnings persistence/readback binaries Neutralized
{{LEARNINGS_SEARCH}} / {{LEARNINGS_LOG}} Generated skill-doc injections for learnings Removed
### Refresh learnings sections Hardcoded mid-skill learnings re-pull blocks in investigate / qa / ship templates (v1.43+) Removed
Telemetry test assertions Tests that would fail after stripping Removed
bin/gstack-skill-start noise v1.71 moved the inline preamble bash into this script: the analytics append, the .pending-* drain, the learnings pull, the timeline write, the telemetry consent prompt, and the per-run update-check all live here now Stripped in place (the script keeps emitting its STATUS lines)
gstack-skill-end v1.71's whole "Telemetry (run last)" epilogue in one binary — duration + outcome analytics, timeline write, remote hand-off Neutralized
skill-end artifacts sync Kept. v1.71 folded the artifacts-sync drain into gstack-skill-end, so removing telemetry would have taken it with it. --discover-new has no other caller, so artifacts a skill produced would never be enqueued. Restored as its own fence, the way upstream shipped it through v1.70 Kept
## Operational Self-Improvement v1.71 made the learnings write unconditional ("this step ALWAYS runs") in every skill's completion protocol Removed
- Telemetry (run last) skip-list rows composition.ts + autoplan list a section that no longer exists Removed
_UPD=$(gstack-update-check ...) preamble check Auto update-check that runs on every skill invocation (network call + echoed output = token waste) Removed
Standalone _TEL=$(... get telemetry) reads Dead telemetry reads in codex / autoplan / review / plan-*-review / ship steps (value never consumed; runs gstack-config on every invoke) Removed
/office-hours "Garry's Personal Plea" YC apply pitch (3 sub-tiers) + ycombinator.com/apply?ref=gstack Removed
/office-hours "Founder Resources (all tiers)" 34-item curated YC / Lightcone / Paul Graham funnel + open-in-browser flow Removed
/office-hours Then proceed to Founder Resources below. stitches Cross-tier handoff lines into the resource funnel Removed

After patching, the script regenerates all 50+ SKILL.md files and runs a final comprehensive sweep (Phase 4.8) over every rendered skill and section file across all install copies — main, .agents/, .kiro/, .factory/, and ~/.codex/ — then verifies that telemetry, timeline, learnings, auto update-check, dead _TEL= reads, and office-hours self-promo references are gone. The local builder profile (gstack-developer-profile) is intentionally kept.

After a --minimal prune, the router's routing table (the - User asks X → invoke /skill`` lines in the main SKILL.md) is filtered to skills that are actually on disk, so the model is never told to invoke a command that no longer resolves. It is driven by what is present rather than by the keep-set, so it self-heals after any regeneration and is a no-op on a full install.

Two skills used to sit outside --minimal's reach entirely, and both came back on every run:

  • claude ships template-only. Upstream renders claude/SKILL.md.tmpl for .agents / Codex hosts and never writes a SKILL.md beside the source, so a catalog built from SKILL.md alone never saw the skill, it could not enter the strip set, and gen-skill-docs re-created .agents/skills/gstack-claude after every prune. The catalog now counts a .tmpl-only source too.
  • gstack-upgrade is named with the prefix the host copies use. Building its host path as gstack-<name> aimed at gstack-gstack-upgrade, which never exists, so the real .agents/skills/gstack-upgrade survived while its source dir was deleted. A name that already starts with gstack- now maps to the bare host name.

What stays: Everything that makes gstack useful. Skill discovery, repo mode detection, proactive suggestions, the browse daemon, review logs, and the core skill workflows. The opt-in /gstack-upgrade --force check stays too, so you can still upgrade manually when you choose. Only the automatic per-preamble update-check is removed. Nothing user-facing is removed except persisted memory features and the auto update-check.


Codex startup and skill activation

Codex skills can be symlinked from a Claude install while their generated preamble still points at ~/.codex/skills/gstack. The strip patches the generator to find an executable startup helper file in the repository or a global Codex, agents, or Claude install before deriving the other runtime paths. Older gstack versions with inline startup retain their original runtime paths. If startup is unavailable, the skill keeps its conservative defaults and reports the missing helper only when it blocks required work. It no longer asks for an upgrade on every run.

Codex also gets gstack's existing compact catalog descriptions. Detailed trigger lists move into the skill body, as they already do for Claude Code. Automatic discovery remains enabled.

Other installed skills have their own triggers. A description such as "Must always apply" or "Use when reading any TypeScript file" can activate those skills during a gstack task. Narrow those descriptions to the work that needs them. To make a particular skill explicit-only in Codex, set this in its agents/openai.yaml, preserving any existing metadata:

policy:
  allow_implicit_invocation: false

Explicit $skill invocation still works. Claude's disable-model-invocation frontmatter is a different setting. See the Codex skill documentation. This script leaves unrelated skills and Codex's own announcement rules alone.

Install or update

Download the current main version to ~/.gstack/, where it survives gstack updates. Run these same commands to update an existing installation.

(
  set -e
  mkdir -p "$HOME/.gstack"
  gstack_download=$(mktemp "$HOME/.gstack/strip-telemetry.sh.XXXXXX")
  curl -fsSL https://raw.githubusercontent.com/VXNCXNX/gstack-debloat/main/strip-telemetry.sh \
    -o "$gstack_download"
  chmod +x "$gstack_download"
  mv "$gstack_download" "$HOME/.gstack/strip-telemetry.sh"
)

For the published v1.1.1 release specifically, replace /main/ in the download URL with /v1.1.1/. Release notes list the changes included in that version. Run the script after downloading it.

Use

Manual

~/.gstack/strip-telemetry.sh

Custom gstack location:

~/.gstack/strip-telemetry.sh /path/to/your/gstack

Optional skill pruning

The default run keeps installed skills. To reduce the skill catalog, inspect the curated keep-set and preview removals before applying --minimal:

~/.gstack/strip-telemetry.sh --list-skills
~/.gstack/strip-telemetry.sh --minimal --dry-run
~/.gstack/strip-telemetry.sh --minimal

Use --keep "browse,qa,review,investigate" for a custom set, or --keep-file /path/to/skills.txt with one skill name per line. Both imply --minimal; the gstack core and command shim are always retained. Pruning removes other skills from the install copies, so rerun with the same options after gstack upgrades or regeneration.

Preview & verify

~/.gstack/strip-telemetry.sh --dry-run   # list files that WOULD be stripped; writes nothing
~/.gstack/strip-telemetry.sh --check     # exit 0 if clean, 1 if any noise remains
~/.gstack/strip-telemetry.sh --help

--check writes nothing and is CI / pre-commit friendly, drop it in a hook to fail the moment a gstack upgrade reintroduces telemetry:

~/.gstack/strip-telemetry.sh --check || ~/.gstack/strip-telemetry.sh

Automatic (recommended)

Add this to your ~/.claude/CLAUDE.md (or paste it into the Claude Code / Codex CLI as a prompt):

Download https://raw.githubusercontent.com/VXNCXNX/gstack-debloat/main/strip-telemetry.sh to a temporary file inside ~/.gstack/, creating that directory if needed. Only after the download succeeds, make the temporary file executable and move it to ~/.gstack/strip-telemetry.sh, then run it. Preserve any existing installation if the download fails. Then add a "gstack Post-Upgrade" section to my ~/.claude/CLAUDE.md that tells you to always run ~/.gstack/strip-telemetry.sh after any gstack upgrade.

That's it. Claude handles the install, runs the strip, and wires itself up to do it again after every future upgrade.


How it works

The script is idempotent. Run it once, run it ten times. If telemetry is already gone, it exits in under a second.

Eight phases:

  1. Patch the generator -- Edits scripts/resolvers/preamble.ts (and the v1.6+ generate-preamble-bash.ts sub-module) to remove telemetry variables, timeline startup logging, learnings injection, timeline-based context recovery, and the per-preamble auto update-check. Fixes the proactive prompt dependency chain that was gated on telemetry state.

  2. Patch custom sources -- Removes the custom learnings write-paths that live outside the generic resolver flow, including the review template and the hardcoded ### Refresh learnings re-pull sections in the investigate, qa, and ship templates (added in gstack v1.43).

  3. Patch the v1.71 runtime scripts -- gstack v1.71 ("token-load reduction") moved ~6.3KB of inline preamble bash out of the generators and into bin/gstack-skill-start, and the skill-end telemetry fence into bin/gstack-skill-end. Every surface the earlier phases stripped from the generated text now lives in those scripts instead, so the renders look clean while the writes carry on. This phase strips them at the source. gstack-skill-start stays alive and keeps emitting its STATUS lines (repo mode, session kind, proactive suggestions, model overlays, the instruction-block gates); only the noise comes out. The proactive-suggestions prompt was chained off the telemetry consent prompt having fired, so it is re-chained onto the lake intro rather than left dead.

  4. Neutralize binaries -- Replaces telemetry, timeline, and learnings binaries in bin/ with no-op stubs so even stale generated docs cannot write persisted state.

  5. Patch tests -- Strips telemetry-specific test cases so the suite stays green.

  6. Strip office-hours self-promo -- Patches office-hours/SKILL.md.tmpl and the Phase 6 section file office-hours/sections/design-and-handoff.md.tmpl (which v1.57+ Reads at runtime instead of inlining), plus the regenerated .md renders and the .agents/ / ~/.codex/ copies. Removes the YC apply pitch, the curated "Founder Resources" funnel, and the "Want me to open these in your browser?" prompt from Phase 6 of the closing sequence. The skill still produces the design doc and recommends the next planning skill -- it just stops pitching YC.

  7. Comprehensive sweep (Phase 4.8) -- Walks every rendered SKILL.md and sections/*.md across all install copies (main, .agents/, .kiro/, .factory/, ~/.codex/) and strips anything the targeted phases miss: standalone dead _TEL=$(... get telemetry) reads, orphaned stubbed-binary call lines, whole ### Refresh learnings mini-sections, and the empty bash fences left behind. Guarded so it never leaves a dangling $_TEL reference, and the local builder profile is left intact.

  8. Verify -- Greps every copy for telemetry/timeline/learnings references, executable _UPD=$( update checks, dead _TEL= reads, and ycombinator.com/apply?ref=gstack residue, failing loudly if anything slipped through.

Requirements

  • bash, sed, python3 (standard on macOS and Linux)
  • bun (already required by gstack)

Compatibility

Tested through gstack v1.84.1.0. The script is version-tolerant: each phase matches its patterns idempotently and skips cleanly when a pattern is absent, so it keeps working across gstack releases. New persistence surfaces introduced upstream are added phase by phase as they appear.

CI clones the latest gstack on every push and weekly, strips it, regenerates the skills, and asserts --check stays clean and skills still render — so upstream drift that reintroduces noise turns the badge red before you hit it.


Why not just set telemetry to "off"?

Because gstack-config set telemetry off only disables the remote binary. The local analytics directory still gets created. The JSONL file still gets appended to on every skill run. Separate session timeline and learnings files can still be written under ~/.gstack/projects/.

"Off" means "we still collect it locally, we just don't send it remotely." This script means "there is nothing left to collect."


FAQ

Does this break gstack? No. Core gstack workflows still work. The script removes telemetry and persisted local memory features. The main behavioral change is that timeline/history/learnings-based context recovery no longer exists, by design.

Will gstack updates re-add this stuff? Yes. Upstream updates can reintroduce telemetry, timeline logging, learnings persistence, and the auto update-check. That is why the CLAUDE.md instruction exists.

What about the new opt-in surfaces gstack has added since v1.83? Two upstream additions send data off-machine or persist it locally, and this script deliberately leaves both alone because they are off by default and consent-gated, unlike the telemetry it strips:

  • Memorable bridge (v1.83, gstack-memorable enable): hands each prompt to the third-party memorable.sh CLI through a Claude Code hook. Registers only when you run the command; revoke with gstack-memorable disable.
  • Design detector (v1.84, bin/gstack-design-detect): probes for the impeccable engine on design skills and, with your one-time consent, downloads it from impeccable's own releases into ~/.impeccable, recording an egress receipt first. Turn every trace off with gstack-config set design_detector off.

Neither runs anything or leaves the machine without an explicit yes, which is the line this script draws: strip everything that is on by default, document everything that asks first.

Does this work with vendored/local installs? Yes. Pass the install path as an argument: ~/.gstack/strip-telemetry.sh ./path/to/gstack

I use Codex/Kiro, not Claude Code. The script patches the source generator, so regenerated Codex/Kiro skill docs will also be telemetry-free. You may need to re-run ./setup after stripping.


License

MIT


gstack is built by Garry Tan. This project is not affiliated with or endorsed by gstack. We just think great tools deserve great privacy defaults.

About

Strip every gstack annoyance: telemetry, local analytics/timeline/learnings, the per-invoke auto update-check, dead telemetry reads, and the /office-hours YC funnel. Idempotent, runs after every upgrade.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages