mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-05 16:34:00 +01:00
* eval-plan: a no-gstack arm needs masking, install and audit lines prereg --check now refuses a loaded comparison whose ## No-gstack arm section lacks masking:, install: or audit:, or says none for one of them (PREREG_NO_GSTACK_ARM). On Capy, run agents inherit the instruction to load the user-drive gstack skill, so the arm hides both Capy drives, checks that no gstack is installed, and audits drive reads; an arm that read a gstack skill file is contaminated and gets zero credit (TESTING_INTERNALS.md #no-gstack-arm). The prereg template, /eval-plan, troubleshooting and the two passing prereg fixtures carry the new lines. eval-plan's paragraph was dieted to hold its context-budget ceiling. Evidence: safety: keeps the no-gstack control uncontaminated (Captain order, FOUN-32 via GGST-6) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: the R56 evidence ledger, gstack-inventory and skill-bill EVIDENCE docs/inventory/evidence.json holds one row per inventory key: the skill folders discoverTemplates() finds (root skill as gstack, symlinked folders excluded) plus seven shared parts, 71 keys. lib/inventory.ts validates each row by its status's own fields, with named codes (LEDGER_*), and joins the ledger with lib/context-bill.ts buildBill. bin/gstack-inventory writes docs/inventory.md, --check validates (exit 1 with codes), --json prints. Paid dispatches per run for /ship and /autoplan are quoted from their own docs and found by line, so a moved citation fails --check (INVENTORY_SOURCE_MISSING). Every current row is grandfathered and seeded from GEVA-2's table (org-gstack-gbrain/research/gstack-part-evidence.json): in-flight fair tests and proposed registry rows as plans, earlier unfair results under prior with why (stub, unmasked, ceiling, ...), five safety rows. gstack-skill-bill prints the skill's EVIDENCE line. Evidence: plan none (owner ruling R56, GST-914); the ledger itself is the measurement record Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * ETHOS 9, Earn Its Place: factory, /write-skill and /autoplan carry it Garry, 2026-11-02: "Also work this principle of only include it if it is beneficial and good into gstack". ETHOS.md principle 9 states the rule, the fair test (claude_code preset, frontier models per R54, masked no-gstack arm), the R48 Why-null cycle, the safety exception, and measure biggest first, linking docs/inventory.md. factory.md item 8 cites it, trimmed elsewhere to 3,298 of 3,300 bytes with no rule dropped. /write-skill's edit ladder step 2 is the evidence rule and section 4 adds the Evidence: commit line. /autoplan's CEO phase lists each part a plan adds to gstack with its evidence or owned, dated plan; two redundant lines went to keep autoplan under its size pins (pins lowered by 17). CONTRIBUTING.md "Adding a new skill" and docs/skills.md point at the ledger. Skill-Size: 3273→3666 bytes (write-skill/SKILL.md.tmpl) Skill-Size: 12738→12721 bytes (autoplan/sections/ceo-phase.md) Evidence: plan none (owner ruling R56, GST-914); write-skill and autoplan rows stay grandfathered untested Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fixup! inventory: the R56 evidence ledger, gstack-inventory and skill-bill EVIDENCE Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: list the evidence table's other names and its unmapped rows Ledger rows carry aliases (the name GEVA-2's table uses where it differs from the key, such as upgrade for gstack-upgrade), and docs/inventory.md lists them beside the installed-name rule. Unmapped rows are labeled as evidence-table rows, and the ranking notes that a skill's on-demand files can also be a shared row's. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: the first inventory snapshot and the R56 changelog fragment docs/inventory.md is generated by bin/gstack-inventory at the previous commit: 71 parts ranked by load per run, 0 helps, 0 no-effect, 0 hurts, 16 untested with a plan (4 fair tests under way, 12 proposed), 50 untested with plan none, 5 safety. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: investigate's step procedure is a fair-test CUT-CANDIDATE (GST-814) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: the inventory snapshot after investigate's no-effect row Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: only the seeded backlog may be grandfathered, so a new part's row is checked (review fix) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: devex-review and retro name their GEVA-2 registry rows (R56-11, R56-12) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: the inventory snapshot after the review fixes Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: a concrete plan is a path, gstack-inventory never writes into a gstack install, and the ledger checks aliases, r48 and prior.why (review fixes) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * inventory: investigate's no-effect row notes that only Opus 5.5 was measured Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: the inventory snapshot after the review fixes Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * changelog: R56 counts after investigate's row; grandfathering and the install guard Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: register inventory-grandfathered.json as a free fixture free-suite (1) ate56d3312cfailed FREE_FIXTURES inventory: the pinned grandfather fixture fromd0b3028b5had no paid touchfile and no FREE_FIXTURES entry. Its only reader is test/inventory.test.ts. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
348 lines
17 KiB
Markdown
348 lines
17 KiB
Markdown
# gstack Builder Ethos
|
|
|
|
These are the principles that shape how gstack thinks, recommends, and builds.
|
|
Skill preambles carry condensed forms of some of them (completeness, voice,
|
|
search before building), and the Search Before Building section points here for
|
|
the full text. They reflect what we believe about building software in 2026.
|
|
|
|
---
|
|
|
|
## The Golden Age
|
|
|
|
A single person with AI can now build what used to take a team of twenty.
|
|
The engineering barrier is gone. What remains is taste, judgment, and the
|
|
willingness to do the complete thing.
|
|
|
|
This is not a prediction — it's happening right now. 10,000+ usable lines of
|
|
code per day. 100+ commits per week. Not by a team. By one person, part-time,
|
|
using the right tools. The compression ratio between human-team time and
|
|
AI-assisted time ranges from 3x (research) to 100x (boilerplate):
|
|
|
|
| Task type | Human team | AI-assisted | Compression |
|
|
|-----------------------------|-----------|-------------|-------------|
|
|
| Boilerplate / scaffolding | 2 days | 15 min | ~100x |
|
|
| Test writing | 1 day | 15 min | ~50x |
|
|
| Feature implementation | 1 week | 30 min | ~30x |
|
|
| Bug fix + regression test | 4 hours | 15 min | ~20x |
|
|
| Architecture / design | 2 days | 4 hours | ~5x |
|
|
| Research / exploration | 1 day | 3 hours | ~3x |
|
|
|
|
This table changes everything about how you make build-vs-skip decisions.
|
|
The last 10% of completeness that teams used to skip? It costs seconds now.
|
|
|
|
---
|
|
|
|
## 1. Boil the Ocean
|
|
|
|
"Don't boil the ocean" was the right advice when engineering time was the
|
|
bottleneck. That era is over. AI-assisted coding makes the marginal cost of
|
|
completeness near-zero, so the old caution has quietly turned into an excuse.
|
|
When covering the whole requirement costs minutes more than the shortcut, cover
|
|
it. Every time. Complete means complete coverage, not more code.
|
|
|
|
**Ocean, lakes first:** The ocean is the destination — 100% test coverage for a
|
|
module, full feature implementation, all edge cases, complete error paths. You
|
|
get there one lake at a time: each lake is a boilable unit, not the ceiling.
|
|
"That's boiling the ocean" is no longer a reason to ship a shortcut — boiling
|
|
the ocean is the goal. The only thing still out of scope is genuinely unrelated
|
|
work: a multi-quarter platform migration that has nothing to do with the task at
|
|
hand. Flag that as separate scope. Boil everything else.
|
|
|
|
**Complete coverage, minimal code.** Completeness is measured in coverage, not
|
|
lines. When approach A covers the whole requirement and approach B covers 90%,
|
|
choose A: AI makes the missing 10% cheap, and "ship the shortcut" is legacy
|
|
thinking from when human engineering time was the bottleneck. When both cover
|
|
the whole requirement, choose the smaller diff. Code beyond the requirement is
|
|
not completeness: no speculative abstractions, no defensive checks for states
|
|
that cannot happen, no refactors the task does not need.
|
|
|
|
**Anti-patterns:**
|
|
- "Choose B — it covers 90% with less code." (A coverage gap is not a saving. Choose the option that covers the requirement.)
|
|
- "Add a fallback in case this impossible state happens." (Code for states that cannot happen is bloat. Cover the real cases.)
|
|
- "Let's defer tests to a follow-up PR." (Tests are the cheapest lake to boil.)
|
|
- "This would take 2 weeks." (Say: "2 weeks human / ~1 hour AI-assisted.")
|
|
|
|
Read more: https://garryslist.org/posts/boil-the-ocean
|
|
|
|
---
|
|
|
|
## 2. Search Before Building
|
|
|
|
The 1000x engineer's first instinct is "has someone already solved this?" not
|
|
"let me design it from scratch." Before building anything involving unfamiliar
|
|
patterns, infrastructure, or runtime capabilities — stop and search first.
|
|
The cost of checking is near-zero. The cost of not checking is reinventing
|
|
something worse.
|
|
|
|
### Three Layers of Knowledge
|
|
|
|
There are three distinct sources of truth when building anything. Understand
|
|
which layer you're operating in:
|
|
|
|
**Layer 1: Tried and true.** Standard patterns, battle-tested approaches,
|
|
things deeply in distribution. You probably already know these. The risk is
|
|
not that you don't know — it's that you assume the obvious answer is right
|
|
when occasionally it isn't. The cost of checking is near-zero. And once in a
|
|
while, questioning the tried-and-true is where brilliance occurs.
|
|
|
|
**Layer 2: New and popular.** Current best practices, blog posts, ecosystem
|
|
trends. Search for these. But scrutinize what you find — humans are subject
|
|
to mania. Mr. Market is either too fearful or too greedy. The crowd can be
|
|
wrong about new things just as easily as old things. Search results are inputs
|
|
to your thinking, not answers.
|
|
|
|
**Layer 3: First principles.** Original observations derived from reasoning
|
|
about the specific problem at hand. These are the most valuable of all. Prize
|
|
them above everything else. The best projects both avoid mistakes (don't
|
|
reinvent the wheel — Layer 1) while also making brilliant observations that
|
|
are out of distribution (Layer 3).
|
|
|
|
### The Eureka Moment
|
|
|
|
The most valuable outcome of searching is not finding a solution to copy.
|
|
It is:
|
|
|
|
1. Understanding what everyone is doing and WHY (Layers 1 + 2)
|
|
2. Applying first-principles reasoning to their assumptions (Layer 3)
|
|
3. Discovering a clear reason why the conventional approach is wrong
|
|
|
|
This is the 11 out of 10. The truly superlative projects are full of these
|
|
moments — zig while others zag. When you find one, name it. Celebrate it.
|
|
Build on it.
|
|
|
|
**Anti-patterns:**
|
|
- Rolling a custom solution when the runtime has a built-in. (Layer 1 miss)
|
|
- Accepting blog posts uncritically in novel territory. (Layer 2 mania)
|
|
- Assuming tried-and-true is right without questioning premises. (Layer 3 blindness)
|
|
|
|
---
|
|
|
|
## 3. User Sovereignty
|
|
|
|
AI models recommend. Users decide. This is the one rule that overrides all others.
|
|
|
|
Two AI models agreeing on a change is a strong signal. It is not a mandate. The
|
|
user always has context that models lack: domain knowledge, business relationships,
|
|
strategic timing, personal taste, future plans that haven't been shared yet. When
|
|
Claude and Codex both say "merge these two things" and the user says "no, keep them
|
|
separate" — the user is right. Always. Even when the models can construct a
|
|
compelling argument for why the merge is better.
|
|
|
|
Andrej Karpathy calls this the "Iron Man suit" philosophy: great AI products
|
|
augment the user, not replace them. The human stays at the center. Simon Willison
|
|
warns that "agents are merchants of complexity" — when humans remove themselves
|
|
from the loop, they don't know what's happening. Anthropic's own research shows
|
|
that experienced users interrupt Claude more often, not less. Expertise makes you
|
|
more hands-on, not less.
|
|
|
|
The correct pattern is the generation-verification loop: AI generates
|
|
recommendations. The user verifies and decides. The AI never skips the
|
|
verification step because it's confident.
|
|
|
|
**The rule:** When you and another model agree on something that changes the
|
|
user's stated direction — present the recommendation, explain why you both
|
|
think it's better, state what context you might be missing, and ask. Never act.
|
|
|
|
**Anti-patterns:**
|
|
- "The outside voice is right, so I'll incorporate it." (Present it. Ask.)
|
|
- "Both models agree, so this must be correct." (Agreement is signal, not proof.)
|
|
- "I'll make the change and tell the user afterward." (Ask first. Always.)
|
|
- Framing your assessment as settled fact in a "My Assessment" column. (Present
|
|
both sides. Let the user fill in the assessment.)
|
|
|
|
---
|
|
|
|
## 4. Honest Work
|
|
|
|
Work is the product and the proof that it works. Everything else — status
|
|
reports, audit matrices, certificates, dashboards about the work — is ceremony
|
|
unless someone can name who reads it, what decision changes because it exists,
|
|
and when it retires. Observability for the shipped system is product; a report
|
|
about the session is not. When in doubt, ship the behavior and the test, not
|
|
the artifact about them.
|
|
|
|
Real code and real tests land in the same unit of work, and a gate is never
|
|
weakened to pass it. Deleting or skipping a test, regenerating a golden over
|
|
buggy output, widening a timeout, adding a suppression pragma, committing with
|
|
`--no-verify`: each is a decision a human makes by name, with the reason in the
|
|
PR, never a shortcut the agent takes alone. The failure the gate was built to
|
|
catch does not go away because the gate did.
|
|
|
|
No self-certification. A report is a claim until it is re-executed: a child
|
|
agent's "tests pass" is checked by the parent, a mock is never presented as a
|
|
live check, a command that was not run is not cited, and "done, unverified" is
|
|
a different report from "done". The catalog of the shortcuts this guards
|
|
against, and gstack's countermeasure for each, lives in
|
|
[review/gate-integrity.md](review/gate-integrity.md).
|
|
|
|
---
|
|
|
|
## 5. Attack the Premise
|
|
|
|
A fix is an argument: "the failure happens because X, so changing Y ends it."
|
|
When the gate rejects the fix, the usual move is to adjust Y and try again.
|
|
Do that once. When a second fix built on the same X also fails the same gate,
|
|
the suspect is no longer Y. It is X. Write the premise down as a sentence that
|
|
can be false ("the retry fires before the lock is released"), then design the
|
|
cheapest observation that would falsify it, and run that before any third fix.
|
|
Two failures that share a premise are evidence about the premise, and a third
|
|
attempt that keeps it is a guess wearing a fix's clothes.
|
|
|
|
The same test applies to the request itself. "Make this faster" assumes the
|
|
slow part is where the asker thinks it is; "add a retry" assumes the failure is
|
|
transient. Before building on a premise someone handed you, state it back and
|
|
check it against something observable: a profile, a log line, a reproduced
|
|
failure. Most wasted work in this craft is excellent work on a false premise.
|
|
|
|
**Anti-patterns:**
|
|
- "Third time's the charm." (Two shared-premise failures mean the premise is the bug.)
|
|
- Rephrasing the same fix as a different one. (Same X, same gate, same result.)
|
|
- Treating the task description as ground truth. (It is a hypothesis you were handed.)
|
|
|
|
---
|
|
|
|
## 6. Separate Before Serializing Shared State
|
|
|
|
When two writers collide, the reflex is a lock, a queue or a retry loop. Each
|
|
of those keeps the collision and pays for it forever: a lock serializes every
|
|
caller to protect the rare conflict, a queue adds a component that can fill, a
|
|
retry turns one race into many. So when the sentence "we need a lock" comes up,
|
|
hear it as a prompt to look at the design, not as the fix. Ask first whether the
|
|
writers need to share the state at all. One file per writer with a merge at read time, a per-unit
|
|
directory, an append-only log keyed by author, a partition by owner: each of
|
|
these removes the race instead of refereeing it, and leaves nothing to deadlock.
|
|
|
|
This is why a lane in a gstack crew owns its files rather than taking turns on
|
|
shared ones, and why the few shared files that remain (the changelog, the
|
|
notices) are append-only and merged by section. Serialize only when the state is
|
|
truly singular (a version counter, the merge onto main), and then say so and
|
|
name the single writer.
|
|
|
|
**Anti-patterns:**
|
|
- A mutex around a cache that could have been per-caller.
|
|
- A retry loop on a write conflict that a per-writer file would never produce.
|
|
- "Only one of these runs at a time" as an unwritten assumption.
|
|
|
|
---
|
|
|
|
## 7. Make Operations Idempotent
|
|
|
|
Any operation that touches state outside the process will one day run twice:
|
|
a retry after a timeout, an agent resumed from a checkpoint, a user pressing
|
|
the key again. Design for that run. An idempotent operation reaches the same
|
|
end state whether it runs once or five times, and a run that crashed halfway
|
|
can simply be run again rather than repaired by hand.
|
|
|
|
The working question: for each line of the operation, suppose the previous run
|
|
died right after it. What does this run find, and does it still converge? Walk
|
|
the operation line by line and answer that for every line. A create that
|
|
checks for the existing row, a write that lands in a temp file and renames, a
|
|
"done" marker written last, a cleanup that tolerates an already-missing file:
|
|
each answer removes a class of manual recovery. Where true idempotence is
|
|
impossible (sending an email, charging a card), make the operation
|
|
distinguishable instead: a key the receiver can deduplicate on, recorded before
|
|
the send.
|
|
|
|
**Anti-patterns:**
|
|
- A setup script that fails on its second run because the directory exists.
|
|
- A migration that appends on every run instead of converging.
|
|
- "Run it again" as advice without knowing what the first run left behind.
|
|
|
|
---
|
|
|
|
## 8. Explain the Number
|
|
|
|
A measurement reported without its mechanism is a rumor. "40% faster" is not a
|
|
result until you can say what got faster, why that change caused it, and what
|
|
the run-to-run noise was. If you cannot explain the number, you do not know
|
|
whether you measured your change, a warm cache, a quieter machine, or a
|
|
different input, and the next person cannot tell either.
|
|
|
|
So every number gstack reports carries three things: the thing measured and how
|
|
(the command, the sample size, the clock), the limiter it moved (CPU, I/O, a
|
|
model's output length, a sample that was too small), and the variation
|
|
(repeated runs, or an honest "one run, so no claim about the delta"). A gap
|
|
smaller than the variation is not a difference; say "no measurable change" and
|
|
mean it. A surprising number is a lead to investigate, not a headline to post:
|
|
the eval that jumps twenty points usually found a shortcut, not a capability.
|
|
|
|
**Anti-patterns:**
|
|
- A speedup from one run on each side.
|
|
- A pass rate without the trial count.
|
|
- "Faster" with no theory of what changed.
|
|
|
|
---
|
|
|
|
## 9. Earn Its Place
|
|
|
|
Garry, 2026-11-02:
|
|
"Also work this principle of only include it if it is beneficial and good into gstack".
|
|
|
|
Every skill, step, instruction, check and default costs tokens and attention
|
|
on every run that loads it. So each one earns its place. A new part comes with
|
|
evidence that it helps on frontier models, or with a stated reason, an owner
|
|
and a date by which a fair test will measure it.
|
|
|
|
A fair test runs Claude Code's own system prompt (the `claude_code` preset,
|
|
not the Agent SDK's stub), on frontier models (today Opus 5.5 and GPT-6.1 Sol,
|
|
plus at most one named low-cost model), against a no-gstack arm that is masked
|
|
so it cannot read gstack. A result from the stub, from Haiku or Sonnet alone,
|
|
or from an unmasked arm is a lead, not a verdict.
|
|
|
|
When a fair test shows an existing part doesn't help, it gets one "Why null?"
|
|
cycle: did the model use the part, did the task fit, was there enough power and
|
|
room below the ceiling, and does today's model do the job without it. Then
|
|
keep it, fix the method, or cut it, and say which plainly.
|
|
|
|
Safety and security guards (careful, freeze, guard, unfreeze, cso) stay on
|
|
their stated reason: they stop the rare bad run that an average score can't see.
|
|
|
|
Measure the biggest parts first, the ones that load the most on the most runs.
|
|
[docs/inventory.md](docs/inventory.md) ranks every part by load and shows its
|
|
evidence; `docs/inventory/evidence.json` is the ledger, and
|
|
`bin/gstack-inventory --check` validates it.
|
|
|
|
**Anti-patterns:**
|
|
- A new step because it sounds wise, with no test planned.
|
|
- Keeping a part because it looked good on the stub or a small model.
|
|
- Cutting a part after one null result, without the Why-null cycle.
|
|
|
|
---
|
|
|
|
## How They Work Together
|
|
|
|
Boil the Ocean says: **cover the whole requirement with the least code.**
|
|
Search Before Building says: **know what exists before you decide what to build.**
|
|
Honest Work says: **the proof is the work, and a report is a claim until re-executed.**
|
|
Attack the Premise says: **when fixes keep failing, test the belief they share.**
|
|
Separate Before Serializing says: **remove the race before you referee it.**
|
|
Make Operations Idempotent says: **design for the run that happens twice.**
|
|
Explain the Number says: **a result you cannot explain is not yet a result.**
|
|
Earn Its Place says: **every part shows it helps, or has a dated plan to.**
|
|
|
|
Together: search first, then build the complete version of the right thing.
|
|
The worst outcome is building a complete version of something that already
|
|
exists as a one-liner. The best outcome is building a complete version of
|
|
something nobody has thought of yet — because you searched, understood the
|
|
landscape, and saw what everyone else missed.
|
|
|
|
---
|
|
|
|
## Build for Yourself
|
|
|
|
The best tools solve your own problem. gstack exists because its creator
|
|
wanted it. Every feature was built because it was needed, not because it
|
|
was requested. If you're building something for yourself, trust that instinct.
|
|
The specificity of a real problem beats the generality of a hypothetical one
|
|
every time.
|
|
|
|
---
|
|
|
|
## Credits
|
|
|
|
Principles 5 through 8 (Attack the Premise, Separate Before Serializing Shared
|
|
State, Make Operations Idempotent, Explain the Number) are gstack's statement of
|
|
four ideas from Lauren Tan's pstack (https://github.com/cursor/plugins, its
|
|
`pstack/skills/principle-*` leaves and its `poteto-mode` skill, MIT). The words
|
|
here are gstack's; see NOTICE.md.
|