cd /news/ai-agents/show-hn-i-forked-an-agent-stack-and-… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-103551] src=toolbay.ai β†— pub= topic=ai-agents verified=true sentiment=Β· neutral

Show HN: I forked an agent stack and measured myself against it, losses included

Toolbay Stack v0.2.0, a free MIT-licensed agent stack forked from an unnamed upstream, claims to reduce context cost by 83% across 53 paired skills and includes 145 engines each with its own test, with a backtest that reproduces all measurements. The stack's 20 free skills are available via npx, and it is designed to fail loudly rather than silently, as demonstrated by a seeded failure where the upstream's guard exits 0 when missing while Toolbay exits 1.

read12 min views1 publishedAug 19, 2026
Show HN: I forked an agent stack and measured myself against it, losses included
Image: source

Toolbay Stack Β· v0.2.0

60 skills for Claude Code. 145 engines, and every single one carries its own test β€” an engine without one fails the suite rather than shipping. Free, MIT, no dependencies.

Most agent tooling fails silently: a guard that allows everything when it is missing, a check that exits 0 having done nothing, a save that writes somewhere you will never look. This is built around refusing that one behaviour, and the refusals are measured rather than claimed β€” npm run backtest

reproduces every number on this page.

Get it

Toolbay Stack is public and MIT licensed. Clone it and run it β€” there is no account, no telemetry, and no dependency to install.

git clone https://github.com/sriptcollector/toolbay-stack.git

It is not on npm yet, so there is no npx one-liner. Clone is the install path. Verified 2026-08-18:

curl -s -o /dev/null -w '%{http_code}' https://github.com/sriptcollector/toolbay-stack

β†’ 200 β€” publicgh api repos/sriptcollector/toolbay-stack --jq .license.spdx_id

β†’ MITnpm view toolbay-stack

β†’ E404 β€” not on npm yet

What does run today, on the same machine, with no account and no telemetry, is the 20 free MIT-licensed skills on the marketplace. That command is verified end to end, not asserted.

20 free skills, no account

npx toolbay add pr-reviewerInstalls a real Claude Code skill that reviews your diff before you push. See all 20.

Measurement 1

Context cost #

A SKILL.md

is injected into the conversation every time its skill is invoked, so its size is a cost you pay per invocation. The backtest reads both stacks off disk and pairs them by skill name.

Skill Toolbay gstack Smaller
/spec 9.2 KB 124 KB 93%
/review 8.8 KB 103.3 KB 91%
/qa 8.1 KB 81.2 KB 90%
/ship 8.4 KB 79.2 KB 89%
/retro 10.5 KB 90 KB 88%
/design-review 14.3 KB 102.5 KB 86%
53 paired 557.4 KB 3193.2 KB 83%

One session

investigate β†’ review β†’ ship β†’ context-restore

Of gstack’s 290.4 KB in that four-skill session, 134KB is lines an earlier skill in the same session already injected β€” an auto-generated preamble stamped into every skill and paid for again on every invocation. Toolbay Stack’s repeated share is 1.9 KB.

Bytes are measured; tokens are an estimate at 4 bytes/token. Files a skill reads while it runs are not counted, on either side.

Three skills are bigger here

The tool prints this and so do we. These are the guard skills, and the extra bytes are the documented failure modes and the list of what the guard does not cover. Trimming them to win a byte count would be gaming the number the measurement exists to report.

  • /careful β€” 6.1 KB here vs 2.5 KB upstream
  • /freeze β€” 5.7 KB here vs 3.1 KB upstream
  • /unfreeze β€” 1.7 KB here vs 1.5 KB upstream

Measurement 2

Correctness on seeded failures #

The backtest builds a fixture with a known defect, runs the equivalent command from both stacks against it, and records CAUGHT or MISSED per side. It fails closed: a scenario whose fixture did not build, whose upstream is not installed, or which timed out is scored for nobody.

The defects, with the file and the line

Open them yourself. Paths are inside a gstack install at ~/.claude/skills/

.

  • 01

A safety guard that allows everything when it is missing

gstack/investigate/SKILL.md:26

[ -x "$S" ] && bash "$S" || exit 0

This is the PreToolUse hook that is supposed to hold the edit boundary during a debugging session. If the guard script is not on the machine, the || exit 0 fires β€” and exit 0 with no output is how a PreToolUse hook spells ALLOW. The protection does not fail loudly, it evaporates silently.

Read directly from the file, and reproduced: backtest scenario guard-not-installed, where gstack exits 0 with no output at all and Toolbay Stack exits 1 so the failure is visible.

  • 02

A failing test suite that reports success

gstack/ship/sections/tests.md:170

bin/test-lane 2>&1 | tee /tmp/ship_tests.txt &

The exit status of a shell pipeline is the status of its LAST command, and the last command here is tee, which essentially always succeeds. The test suite's own exit code is discarded before anything can read it. This is the step that decides whether a change is safe to land.

Read directly from the file in gstack 1.60.1.0.

  • 03

An expiry that cannot be parsed means never expires

gstack/ios-qa/daemon/src/allowlist.ts:56

if (Number.isFinite(exp) && exp < now) continue;

exp comes from Date.parse on the entry's expires_at. A malformed date gives NaN, Number.isFinite(NaN) is false, so the continue never runs and the entry is returned as valid. A device grant with a garbled expiry is not rejected and is not expired β€” it is permanent.

Read directly from the file in gstack 1.60.1.0.

  • 04

A destructive command waved straight through

backtest scenario careful-block-device

dd if=/dev/zero of=/dev/sda

A command that destroys a filesystem. gstack's guard allowed it silently β€” exit 0, output "{}". Its sibling scenario careful-quoted-sql does the same with psql -c "DROP TABLE users;": the pattern match stops at the first escaped quote, so the guard never sees the DROP.

npm run backtest --only careful-block-device (raw log: .toolbay/backtest/raw/careful-block-device.gstack.log)

  • 05

A corrupt row that silently vanishes from your learnings

backtest scenario learn-corrupt-row

LEARNINGS: 3 loaded   # over a store with 4 rows on disk

Given a learnings store with four rows, one of them unparseable, gstack exits 0 and reports three. The fourth is gone and nothing says so. Toolbay Stack names the damaged row and exits 3.

npm run backtest --only learn-corrupt-row (raw log: .toolbay/backtest/raw/learn-corrupt-row.gstack.log)

  • 06

Saved context that reports NO_CHECKPOINTS over files that exist

backtest scenario restore-slug-unresolvable

resolved CHECKPOINT_DIR=[/projects//checkpoints]

On a machine where the slug helper is not at the path the skill hard-codes, the directory resolves with an empty middle segment, and the skill prints NO_CHECKPOINTS at exit 0 over saved context that is sitting on disk. An empty answer that looks like a real answer.

npm run backtest --only restore-slug-unresolvable (raw log: .toolbay/backtest/raw/restore-slug-unresolvable.gstack.log)

The other direction

What gstack does better #

This section is the reason to believe the rest of the page. If you want the original, use the original β€” it is upstream, it is very good, and it is where most of these ideas came from.

Four scenarios where upstream is correct too

Scored as ties. These are not wins for us.

  • freeze-boundary-posix

freeze boundary enforced with POSIX-style absolute paths β€” both allowed the edit inside and denied the one outside - careful-rm-rf

rm -rf on a real directory β€” both warned first - careful-safe-artifact

rm -rf node_modules β€” both correctly stayed silent - freeze-traversal-escape

an edit that leaves the boundary through .. β€” both denied it

One command both stacks wave straight through

aws s3 rm s3://bucket --recursive

Neither stack's pattern list covers it. Both allowed it silently (exit 0, output "{}"). This is a real hole in Toolbay Stack, not just in upstream.

A capability upstream has that this fork never ported

learn-cross-project-trust-gate

Cross-project learnings with a trust allowlist. A learning written by another project, without trusted: true, is correctly refused by gstack. Toolbay Stack has no cross-project learnings reader at all, so there is nothing to gate.

Skills that exist only upstream: none, as of 2026-08-17

This section used to name six. The last four β€” benchmark-models, landing-report, setup-gbrain, sync-gbrain β€” landed on 2026-08-17, so every one of upstream's 53 skills now has a counterpart here. The heading is generated from the list rather than written, so it will say a number again the moment upstream ships something this fork has not matched.

Seven exist only here (backtest, memory, modes, router, suggest, toolbay, video) and are not compared, because only one stack has them. Counts: 60 skills here, 53 upstream, 53 paired. Parity in the skill list is not parity in behaviour β€” the capability named above is still missing.

Two results you should not quote at us

One scenario (freeze-boundary-windows-paths) is Windows-only: gstack denied an edit that was inside the boundary because it reads a drive-letter path as relative. It does NOT reproduce on macOS or Linux, where Claude Code sends POSIX paths and upstream's guard is correct β€” see freeze-boundary-posix, which upstream passes. The backtest prints this caveat itself.

A third scenario (ios-qa-expiry-unparseable) is INCONCLUSIVE: the upstream half only runs on macOS and this was measured on win32. It is scored for nobody.

Measurement 3

The hook that runs before every tool call #

The careful

guard is a PreToolUse hook, so its latency is added to every single tool call in a session. Median over 12 runs:

Most of each number is interpreter startup: 59ms of the Toolbay hook is bare node, 37ms of the gstack hook is bare bash. The gap is real but it is not 7x of our own code.

On top of the fork

What is actually ours #

Modes

A stance layer. Set SHIP, CRAFT, WILD or LOCK per project and every other skill changes what it does β€” /review in SHIP flags blockers only, the same /review in LOCK flags everything and rejects any claim without a citation. The four modes live in one hand-edited modes.json and the code knows none of their names, so a stance is a thing you edit rather than argue with. Everything fails closed: no mode, an unknown name, a corrupt or empty config all land on a restrained built-in stance and print the reason.

Memory

Claude's own memory keeps facts. This keeps corrections β€” it writes at the moment you say "no, not like that", and refuses to store one without the reason, because the reason is the only part that transfers. A newer entry never silently wins: a contradiction is surfaced with both sides and neither is applied until you say which is true. Every rule knows its scope, and when that is unclear it goes narrow. Off until you run enable twice.

Suggest

Reads the project's actual state and says what is worth doing next, with the evidence. Names the command, never runs it, and says "nothing worth suggesting" when that is true. The active mode changes what gets offered, and every suppressed suggestion is printed with the weight that dropped it β€” but no mode at any weight can suppress a credential about to be committed.

Backtest

The reason you are reading real numbers instead of adjectives. It seeds fixtures with a known defect, runs the equivalent command from BOTH stacks, and records CAUGHT or MISSED per side. It fails closed: a scenario whose fixture did not build, whose upstream is missing, or which timed out is scored for nobody. You can point it at your own setup and prove your own hooks fire.

Cursor support

The guards port to Cursor, and the installer refuses to install a skill whose guard Cursor cannot actually enforce, naming the missing capability. What is not covered is printed at the top of every installed copy rather than left for you to find: Tab autocomplete does not go through the freeze boundary, and your own typing is never guarded.

Why this lives on Toolbay

The skill that reaches the marketplace #

Every agent stack dead-ends the same way. gstack’s routing rule ends with β€œIf nothing matches, answer directly.” (its SKILL.md

, line 531 β€” quoted exactly, because a page like this one does not get to paraphrase inside quotation marks). The toolbay

skill is the one thing a fork can add that upstream structurally cannot: somewhere to go. Blocked on a capability that does not exist locally, it searches the live catalogue on this site. Finished something reusable, it can evaluate and list it without you opening a form.

The rails on it are not optional. Search results are paid listings you would be buying, and are always shown with the price. An empty result stays empty rather than being padded with something loosely related. Revenue figures are ranges with a stated basis, never a single number and never a forecast. It is offered once, and declined means dropped. And the mode can switch it off outright β€” LOCK refuses find

and call

before a token is read or a packet is sent. There is no bypass flag.

Check it yourself

Reproduce every number on this page #

These are the commands the figures above came from. They read the upstream install, never write inside it, and log every process they start β€” argv, cwd, env overrides, exit status, stdout, stderr, duration β€” under .toolbay/backtest/raw/

.

npm run backtest                    # every scenario, both stacks
node tools/backtest.mjs --list      # what the scenarios are
node tools/backtest.mjs --family context
node tools/backtest.mjs --gstack <dir>   # point it at your own install
npm test                            # 145 engine selftests

All 145 engines passed their own selftest, and every engine on disk has one. An engine with no selftest fails the suite, because the list is read off the filesystem instead of maintained by hand β€” which is how the old hand-written list came to name seven engines while fifteen shipped.

Measured 2026-08-17 on node v24.14.1 / win32 against gstack 1.60.1.0. Your numbers will differ with your install; that is the point of shipping the command rather than the screenshot.

Toolbay Stack is an MIT fork of gstack by Garry Tan, which is excellent software and the origin of most of the workflow skills here. Every derived skill carries an attribution header, the MIT notice is preserved, and this project is not affiliated with or endorsed by him. If you want the original, use the original.

── more in #ai-agents 4 stories Β· sorted by recency
── more on @toolbay stack 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/show-hn-i-forked-an-…] indexed:0 read:12min 2026-08-19 Β· β€”