Per-skill benefit declaration — extend gstack-context-bill from cost-only to cost/benefit
Problem
gstack-context-bill is a genuinely good instrument: a read-only, offline audit of "what an installed skills tree costs in tokens" — always-on frontmatter every session pays vs. per-invocation SKILL.md + forced references, with --diff to compare trees and --budget to enforce ceilings. The measured-error estimate is even honest about its own accuracy.
But it only ever measures one side of the ledger. It can answer "which skills are expensive"; it cannot answer "which skills are worth it". A skill that costs 500 always-on tokens and saves 20K of investigation every week, and a skill that costs 500 and saves nothing, are indistinguishable in its output. Cost-only accounting structurally biases every decision it informs toward removal — the only action it can justify is subtraction.
The README's Golden Age section is built on exactly the opposite framing: AI compresses work by dramatic ratios, and the interesting number is the ratio, not the spend. The compression-ratio table is a benefit argument. The tooling just never got the memo.
Proposal
An optional benefit side of the bill:
- Two opt-in frontmatter fields per skill:
estimated_token_saving: what running this skill typically saves versus the unassisted path (fewer failed attempts, less manual search, shorter fix cycles)avg_execution_time: wall-clock for a representative invocation
gstack-context-billgains a benefit column and a derived figure (saving ÷ cost) for skills that declare fields. Skills without the field render exactly as today — the bill stays byte-compatible for any tree that opts out, and--diff/--budgetsemantics are untouched.- Declarations before measurements, deliberately. Values start as the skill author's honest estimate — the same trust model as the token estimates context-bill already ships, which are estimates "always named in the output" rather than silent exact numbers. Later, estimates can be grounded by the local telemetry gstack already runs (the
/learnlineage of per-skill stats): anestimated_*field becomes ameasured_*field once enough local runs exist. Local, per-project — never a shared telemetry pool.
The decision the tool can then support changes character: not "cut the 2K always-on" but "the 2K always-on is the cheapest 20K you spend".
How this fits gstack
- Golden Age, instrumented — the compression-ratio table argues AI work is a ratio; this makes the ratio a first-class, per-skill, locally measurable number instead of a marketing table.
- Build for Yourself — the operator paying the token bill is the operator who benefits from seeing which skills pay their rent. No shared data, no network, no behavior change: it's the same read-only, offline posture context-bill already has.
- Cheap to build — two optional YAML fields and a column in an existing report. The hard part (honest measurement posture) was already solved by context-bill's estimate-naming convention.
Non-goals / open questions
- No mandatory field, no CI gate, no enforcement semantics — benefit data informs, the user decides.
- No change to the cost-measurement logic or the
--exactpath. - Open: whether
--diffshould also diff declared benefits (leaning no for v1 — cost diffs are objective, benefit estimate diffs invite arguing about the estimates).
Suggested TODOS.md entry
What: Add optional estimated_token_saving and avg_execution_time frontmatter fields to skills and a benefit column (with derived saving ÷ cost figure) to gstack-context-bill output.
Why: The bill measures only cost, so every decision it informs can only justify removal; skills that pay for themselves and skills that don't are indistinguishable in its output, which contradicts the Golden Age compression-ratio framing the README leads with.
Context: Opt-in per skill; output stays byte-compatible for non-declaring trees; --diff/--budget untouched. Estimates named as estimates (context-bill's existing convention), upgradeable to locally-measured values from per-skill run stats later. Read-only, offline, per-project — no shared telemetry.
Effort: S Priority: P3 Depends on: None
Source: garrytan/gstack