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.
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, keptRun --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.
| 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:
claudeships template-only. Upstream rendersclaude/SKILL.md.tmplfor.agents/ Codex hosts and never writes aSKILL.mdbeside the source, so a catalog built fromSKILL.mdalone never saw the skill, it could not enter the strip set, andgen-skill-docsre-created.agents/skills/gstack-claudeafter every prune. The catalog now counts a.tmpl-only source too.gstack-upgradeis named with the prefix the host copies use. Building its host path asgstack-<name>aimed atgstack-gstack-upgrade, which never exists, so the real.agents/skills/gstack-upgradesurvived while its source dir was deleted. A name that already starts withgstack-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 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: falseExplicit $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.
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.
~/.gstack/strip-telemetry.shCustom gstack location:
~/.gstack/strip-telemetry.sh /path/to/your/gstackThe 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 --minimalUse --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.
~/.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.shAdd 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.
The script is idempotent. Run it once, run it ten times. If telemetry is already gone, it exits in under a second.
Eight phases:
-
Patch the generator -- Edits
scripts/resolvers/preamble.ts(and the v1.6+generate-preamble-bash.tssub-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. -
Patch custom sources -- Removes the custom learnings write-paths that live outside the generic resolver flow, including the
reviewtemplate and the hardcoded### Refresh learningsre-pull sections in theinvestigate,qa, andshiptemplates (added in gstack v1.43). -
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 intobin/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-startstays 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. -
Neutralize binaries -- Replaces telemetry, timeline, and learnings binaries in
bin/with no-op stubs so even stale generated docs cannot write persisted state. -
Patch tests -- Strips telemetry-specific test cases so the suite stays green.
-
Strip office-hours self-promo -- Patches
office-hours/SKILL.md.tmpland the Phase 6 section fileoffice-hours/sections/design-and-handoff.md.tmpl(which v1.57+ Reads at runtime instead of inlining), plus the regenerated.mdrenders 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. -
Comprehensive sweep (Phase 4.8) -- Walks every rendered
SKILL.mdandsections/*.mdacross 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 learningsmini-sections, and the emptybashfences left behind. Guarded so it never leaves a dangling$_TELreference, and the local builder profile is left intact. -
Verify -- Greps every copy for telemetry/timeline/learnings references, executable
_UPD=$(update checks, dead_TEL=reads, andycombinator.com/apply?ref=gstackresidue, failing loudly if anything slipped through.
bash,sed,python3(standard on macOS and Linux)bun(already required by gstack)
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.
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."
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 withgstack-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 withgstack-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.
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.