mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-30 23:09:32 +02:00
f8bb59094d
* feat(issue): add /issue skill for backlog-ready GitHub issue authoring
Interrogates an ambiguous request through five strict phases (why, scope,
technical, draft, final) and produces a GitHub issue precise enough that an
unfamiliar engineer or AI agent can execute it without follow-up. Slots in
after /office-hours (when the idea has passed the "worth building" bar) and
before /plan-eng-review (which assumes a plan already exists).
- issue/SKILL.md.tmpl + generated SKILL.md
- routing entry in root SKILL.md.tmpl
- llms.txt regenerated to include the new skill
* chore(spec): rename /issue → /spec + fix duplicate analytics block
Foundation commit for the /spec skill (extends PR #1698 by @jayzalowitz).
- Renames issue/ → spec/ (template + generated)
- Removes the hand-rolled analytics block in spec/SKILL.md.tmpl (lines 46-49 of the original); {{PREAMBLE}} already emits the analytics write with the telemetry opt-out guard, so the duplicate would have bypassed gstack-config set telemetry off
- Updates frontmatter (name: spec, expanded description with magical-moment preview, triggers reordered to lead with "spec this out")
- Updates root SKILL.md.tmpl routing entry → /spec
- Regenerates spec/SKILL.md and gstack/llms.txt via bun run gen:skill-docs
Co-Authored-By: Jay Zalowitz <jayzalowitz@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(spec): expansions — flags, archive, quality gate, plan-mode-aware Phase 5, /ship integration, tests
Builds on the @jayzalowitz foundation (commit a4e6ee38) with the full
expansion set from CEO + Eng + DX review (24 user decisions + 23 of 28
codex adversarial findings).
spec/SKILL.md.tmpl additions:
- Flag reference table (--dedupe / --no-gate / --audit / --execute /
--no-execute / --file-only / --plan-file / --sync-archive).
- Phase 1b --dedupe (default ON): gh issue list --search with graceful
skip on gh-not-installed / unauthed / rate-limited / other errors.
AskUserQuestion when matches found (merge / file-new / cancel).
- Phase 3 HARD requirement: agent MUST grep/read at least one piece of
evidence before asking. Project-level fallback prose for prompts with
no concrete file mapping. Greenfield escape clause.
- Phase 4.5 quality gate (default ON): codex adversarial dispatch with
fail-closed redaction (AWS/GitHub/Anthropic/OpenAI/private-key regex),
hard <<<USER_SPEC>>> delimiters + instruction boundary (prompt-injection
defense), score 0-10 with <7 block, up to 3 iterations, AskUserQuestion
escape on persistent <7 (ship anyway / save draft / one more try).
- Phase 5 plan-mode-aware dispatch: reads GSTACK_PLAN_MODE env. Active
→ file-only + load into plan file. Inactive → file + --execute spawn
by default. CLI overrides for explicit control.
- Archive block via eval $(gstack-paths) → $GSTACK_STATE_ROOT/projects/
$SLUG/specs/<datetime>-<pid>-<slug>.md. Atomic .tmp/mv write. Sync
excluded by default; --sync-archive to opt in.
- --execute path: dirty-worktree gate (porcelain check + 3-option AUQ
continue/stash/cancel), TOCTOU re-check after AUQ answer, SHA pin
via git rev-parse HEAD, unique branch spec/<slug>-$$ + PID-suffixed
worktree, mandatory final-confirm gate, stash policy with restore
safety (preserve ref, never auto-drop).
- TTHW timestamps captured at Phase 1 / first citation / file-or-spawn,
emitted as ttfc_ms + tthw_ms in preamble telemetry envelope.
Cross-system plumbing:
- scripts/resolvers/preamble/generate-preamble-bash.ts: emit
GSTACK_PLAN_MODE=active|inactive based on CLAUDE_PLAN_FILE presence.
- scripts/resolvers/preamble/generate-routing-injection.ts: add /spec
to the routing block injected into project CLAUDE.md.
- ship/SKILL.md.tmpl: new "Linked Spec" PR-body section. Reads archive
frontmatter spec_issue_number and adds Closes #N when full delivery
confirmed by existing plan-completion gate (codex F4 — conditional).
Branch-name inference NOT used (codex F3 — fragile under rebase).
Tests (W7):
- test/spec-template-invariants.test.ts: 35 deterministic assertions
covering Phase 1 hard gate, Phase 3 hard-grep mandate, --dedupe
graceful-skip paths, --execute race + security hardening (TOCTOU,
SHA pin, unique branch), quality-gate redaction + BLOCKED path,
archive atomic write + sync exclusion, plan-mode-aware Phase 5.
- test/spec-template-sync.test.ts: regen + byte-identical check.
- test/skill-e2e-spec-execute.test.ts (periodic-tier scaffold).
- test/skill-llm-eval-spec.test.ts (periodic-tier scaffold).
- test/helpers/touchfiles.ts: register both periodics in E2E_TIERS +
LLM_JUDGE_TOUCHFILES.
37/37 /spec tests pass. Full bun test exit 0 (pre-existing
url-validation timeout unrelated to /spec).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: v1.45.0.0 — regen all SKILL.md, bump VERSION, CHANGELOG entry
Mechanical regen pulling in two template-side changes:
- /spec expansion (spec/SKILL.md picks up ~1100 new lines)
- {{PREAMBLE}} now echoes GSTACK_PLAN_MODE env (every skill picks up
the new echo line in the preamble bash block)
VERSION 1.44.0.0 → 1.45.0.0 (MINOR per scale-aware rules: substantial
new capability — /spec skill with 5 CLI flags + race/security
hardening + plan-mode-aware Phase 5 + /ship integration).
CHANGELOG entry frames /spec as agent feedstock with the two-line
headline, "numbers that matter" table, and "what this means for
builders" close. Credits @jayzalowitz for the foundation contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(spec): register /spec in scripts/proactive-suggestions.json
Auto-generated by bun run gen:skill-docs after the v1.46 catalog-trim
contract picked up /spec's frontmatter. lead + routing extracted from
spec/SKILL.md.tmpl description: block.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(spec): TODOS deferrals + package.json sync for v1.47.0.0
- TODOS.md: add P2 entry for /spec --epic mode (deferred from CEO SCOPE
EXPANSION review), P3 entry for --dedupe semantic matching upgrade.
Both have full context blocks so future picker can resume cold.
- package.json: bump 1.46.0.0 → 1.47.0.0 to match VERSION (was stale
from the main merge; /ship Step 12 idempotency caught it).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: register /spec skill in README, AGENTS, CLAUDE.md project tree
Adds /spec to the three discoverability surfaces it was missing:
- README.md sprint skills table (between /autoplan and /learn)
- AGENTS.md plan-mode reviews table
- CLAUDE.md project structure tree (between /investigate and /retro)
/spec shipped in v1.47.0.0 with CHANGELOG coverage but the entry-point
docs hadn't been updated; a user landing on README or AGENTS would not
discover the skill exists without reading CHANGELOG.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Jay Zalowitz <jayzalowitz@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
194 lines
9.3 KiB
TypeScript
194 lines
9.3 KiB
TypeScript
/**
|
|
* Skill coverage matrix (v1.45.0.0 T1, cathedral Phase 0).
|
|
*
|
|
* Single source of truth mapping each gstack skill to its E2E test files.
|
|
* The CI gate at test/skill-coverage-matrix.test.ts fails if a skill has
|
|
* no gate-tier entry, ensuring the eval-first foundation holds: every
|
|
* skill has at least one CI-blocking check that asserts must-have
|
|
* behavior.
|
|
*
|
|
* Two tiers per entry:
|
|
* gate CI-blocking, runs on every PR, target <$0.50/test or free.
|
|
* periodic Weekly cron, deeper coverage, can cost ~$1-$3/test.
|
|
*
|
|
* The 'floor' entry refers to test/skill-coverage-floor.test.ts —
|
|
* a structural-compliance smoke test that covers every skill with
|
|
* file-IO checks (free, no LLM cost). When a skill has only 'floor'
|
|
* coverage, that's the eval-first minimum; future work can layer
|
|
* behavioral checks on top.
|
|
*/
|
|
|
|
export interface SkillCoverage {
|
|
/** Gate-tier test file paths (relative to repo root). At least one required per skill. */
|
|
gate: string[];
|
|
/** Periodic-tier test file paths. Optional but recommended. */
|
|
periodic: string[];
|
|
/** Brief note on why this coverage is the right shape for this skill. */
|
|
rationale?: string;
|
|
}
|
|
|
|
/**
|
|
* Per-skill coverage. Keys MUST match the top-level skill directory name.
|
|
* The CI test asserts every skill in the repo has an entry here AND that
|
|
* gate[] is non-empty.
|
|
*
|
|
* Adding a new skill: add an entry here AND either reference an existing
|
|
* test that covers it OR add 'test/skill-coverage-floor.test.ts' as the
|
|
* minimum gate-tier check.
|
|
*/
|
|
export const SKILL_COVERAGE: Record<string, SkillCoverage> = {
|
|
// ─── Core loop ──────────────────────────────────────────────
|
|
ship: {
|
|
gate: ['test/skill-e2e-ship-idempotency.test.ts', 'test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/skill-e2e-workflow.test.ts'],
|
|
},
|
|
review: {
|
|
gate: ['test/skill-e2e-review.test.ts', 'test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/skill-e2e-review-army.test.ts', 'test/regression-1539-review-self-verify.test.ts'],
|
|
},
|
|
qa: {
|
|
gate: ['test/skill-e2e-qa-workflow.test.ts', 'test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/skill-e2e-qa-bugs.test.ts'],
|
|
},
|
|
'qa-only': {
|
|
gate: ['test/skill-coverage-floor.test.ts'],
|
|
periodic: [],
|
|
rationale: 'qa-only is qa with --report-only; behavior tested via /qa coverage.',
|
|
},
|
|
investigate: {
|
|
gate: ['test/skill-coverage-floor.test.ts'],
|
|
periodic: [],
|
|
},
|
|
browse: {
|
|
gate: ['test/skill-coverage-floor.test.ts'],
|
|
periodic: [],
|
|
rationale: 'browse binary has its own integration suite under browse/test/.',
|
|
},
|
|
spec: {
|
|
gate: [
|
|
'test/spec-template-invariants.test.ts',
|
|
'test/spec-template-sync.test.ts',
|
|
'test/skill-coverage-floor.test.ts',
|
|
],
|
|
periodic: [
|
|
'test/skill-e2e-spec-execute.test.ts',
|
|
'test/skill-llm-eval-spec.test.ts',
|
|
],
|
|
rationale: '37 deterministic invariants pin Phase 1/3 gating, --execute race/security hardening, quality-gate redaction, archive contract, plan-mode-aware Phase 5. Periodic adds full PTY pipeline + LLM-judge.',
|
|
},
|
|
|
|
// ─── Plan triad ─────────────────────────────────────────────
|
|
'plan-ceo-review': {
|
|
gate: [
|
|
'test/skill-e2e-plan-ceo-finding-floor.test.ts',
|
|
'test/skill-e2e-plan-ceo-plan-mode.test.ts',
|
|
'test/skill-coverage-floor.test.ts',
|
|
],
|
|
periodic: [
|
|
'test/skill-e2e-plan-ceo-finding-count.test.ts',
|
|
'test/skill-e2e-plan-ceo-mode-routing.test.ts',
|
|
],
|
|
},
|
|
'plan-eng-review': {
|
|
gate: [
|
|
'test/skill-e2e-plan-eng-finding-floor.test.ts',
|
|
'test/skill-e2e-plan-eng-plan-mode.test.ts',
|
|
'test/skill-coverage-floor.test.ts',
|
|
],
|
|
periodic: [
|
|
'test/skill-e2e-plan-eng-finding-count.test.ts',
|
|
'test/skill-e2e-plan-eng-multi-finding-batching.test.ts',
|
|
],
|
|
},
|
|
'plan-design-review': {
|
|
gate: [
|
|
'test/skill-e2e-plan-design-finding-floor.test.ts',
|
|
'test/skill-e2e-plan-design-plan-mode.test.ts',
|
|
'test/skill-e2e-plan-design-with-ui.test.ts',
|
|
'test/skill-coverage-floor.test.ts',
|
|
],
|
|
periodic: ['test/skill-e2e-plan-design-finding-count.test.ts'],
|
|
},
|
|
'plan-devex-review': {
|
|
gate: [
|
|
'test/skill-e2e-plan-devex-finding-floor.test.ts',
|
|
'test/skill-e2e-plan-devex-plan-mode.test.ts',
|
|
'test/skill-coverage-floor.test.ts',
|
|
],
|
|
periodic: ['test/skill-e2e-plan-devex-finding-count.test.ts'],
|
|
},
|
|
autoplan: {
|
|
gate: ['test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/skill-e2e-autoplan-chain.test.ts', 'test/skill-e2e-autoplan-dual-voice.test.ts'],
|
|
},
|
|
'office-hours': {
|
|
gate: ['test/skill-e2e-office-hours.test.ts', 'test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/skill-e2e-office-hours-auto-mode.test.ts', 'test/skill-e2e-office-hours-phase4.test.ts'],
|
|
},
|
|
|
|
// ─── Polish + design ────────────────────────────────────────
|
|
'design-review': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'design-consultation': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'design-shotgun': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'design-html': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
cso: {
|
|
gate: ['test/skill-e2e-cso.test.ts', 'test/cso-preserved.test.ts', 'test/skill-coverage-floor.test.ts'],
|
|
periodic: [],
|
|
rationale: 'cso-preserved.test.ts pins must-not-strip security guidance phrases.',
|
|
},
|
|
'document-release': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'document-generate': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
|
|
// ─── Ops + integrations ─────────────────────────────────────
|
|
'land-and-deploy': { gate: ['test/skill-e2e-deploy.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
canary: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
benchmark: { gate: ['test/skill-e2e-benchmark-providers.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'benchmark-models': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
codex: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
retro: {
|
|
gate: ['test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/regression-1624-retro-stale-base.test.ts'],
|
|
},
|
|
'gstack-upgrade': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'context-save': { gate: ['test/skill-e2e-context-skills.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'context-restore': { gate: ['test/skill-e2e-context-skills.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'setup-deploy': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'setup-browser-cookies': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'setup-gbrain': {
|
|
gate: [
|
|
'test/skill-e2e-setup-gbrain-bad-token.test.ts',
|
|
'test/skill-e2e-setup-gbrain-path4-local-pglite.test.ts',
|
|
'test/skill-e2e-setup-gbrain-remote.test.ts',
|
|
'test/skill-coverage-floor.test.ts',
|
|
],
|
|
periodic: [],
|
|
},
|
|
'sync-gbrain': {
|
|
gate: ['test/skill-coverage-floor.test.ts'],
|
|
periodic: ['test/regression-1611-gbrain-sync-resume.test.ts'],
|
|
},
|
|
'open-gstack-browser': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'pair-agent': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
scrape: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
skillify: { gate: ['test/skill-e2e-skillify.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
learn: { gate: ['test/skill-e2e-learnings.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'plan-tune': { gate: ['test/skill-e2e-plan-tune.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
|
|
// ─── iOS family ─────────────────────────────────────────────
|
|
'ios-qa': { gate: ['test/skill-e2e-ios.test.ts', 'test/skill-coverage-floor.test.ts'], periodic: ['test/skill-e2e-ios-device.test.ts', 'test/skill-e2e-ios-swift-build.test.ts'] },
|
|
'ios-fix': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'ios-clean': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'ios-sync': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'ios-design-review': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
|
|
// ─── Safety / housekeeping ──────────────────────────────────
|
|
careful: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
freeze: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
unfreeze: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
guard: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'landing-report': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
health: { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'make-pdf': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
'devex-review': { gate: ['test/skill-coverage-floor.test.ts'], periodic: [] },
|
|
};
|