mirror of
https://github.com/garrytan/gstack.git
synced 2026-08-31 18:30:39 +02:00
* feat(autoplan): eng review always runs last — the gate reviews the final amended plan Reorder the pipeline to CEO -> Design (if UI scope) -> DX (if developer-facing scope) -> Eng. The old order (CEO -> Design -> Eng -> DX) let DX findings land AFTER the required gate signed off, so eng validated a stale plan. Accept-all semantics made explicit: every AskUserQuestion resolves to the recommended option; premises no longer pause the pipeline mid-run (clearly-wrong ones queue as User-Challenge items at the single Final Approval Gate). Eng's Codex voice now sees the DX consensus summary. New free static test pins the order; the chain E2E gains DX-between and Eng-terminal assertions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(review): simplification specialist — advisory over-engineering lens with ponytail's tag vocabulary New 8th Review Army specialist (DIFF_LINES > 100, --simplification force flag) hunting unrequested STRUCTURE only: delete/stdlib/native/speculative/shrink closed tags, one-line findings, lines_removable field. speculative: replaces ponytail's yagni: tag — we import the lens, not the posture; coverage stays sacred (Completeness Gaps owns it, suppressions inlined, shrink needs >=5 lines). Advisory carve-out in the merge step: advisory findings are excluded from quality_score and the findings-count header, render with an [ADVISORY] label, and are ASK-only in Fix-First. Zero-findings case prints the lens-scoped 'Simplification: lean already — nothing to cut.' from the PARENT (the specialist keeps the exact NO FINDINGS contract); with findings, the parent prints 'net: -N lines possible' summed from lines_removable. Tests: static pins for the carve-out + early-out contract (gen-skill-docs), two periodic e2e cases with planted fixtures — activation (over-build traps: hand-rolled Intl, one-impl abstract, dead config) and false-flag precision (a lean ETHOS 'choose A' diff must yield NO FINDINGS). Inspired by dietrichgebert/ponytail's /ponytail-review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(preamble): reuse ladder in Search Before Building — rungs 2-5 of ponytail's ladder, completeness kept Tier-3+ skills gain a per-edit reflex the section only stated as research discipline: before writing new code, stop at the first rung that holds — repo helper, stdlib, native platform feature, installed dependency — then build the COMPLETE version of what remains. The closing clause is the explicit reconciliation with Boil the Ocean: the ladder governs structure, never coverage. Rungs 1/6/7 (YAGNI / one line / minimum that works) are deliberately NOT imported. Also ports ponytail's root-cause rule: one guard in the shared function beats a guard in every caller. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(preamble): bounded-closer output rule for tier-2+ skills After completing work, skills report in a few short lines — what changed, what was skipped, what to watch — and cut any explanation that outgrows the change. Explicit exemptions protect every mandated output: decision briefs, completion-status blocks, user-requested explanations, and report-shaped skills' report formats (the report IS the work in /qa-only, /plan-*-review, /retro, /document-generate). Rationale is signal-to-noise, not tokens: ponytail's own benchmark shows terse prose alone doesn't cut cost (caveman arm: -20% LOC, +7% tokens), and independent replications found its 'skipped on purpose' essays ate the code savings. Includes a good/bad closer example pair per the model-overlay guidance that a positive example beats a 'don't be verbose' instruction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(resolvers): terse-mode savings claim matches measurement — 2.6KB, not 3-5KB Measured on the v1.71 render: --explain-level=terse saves exactly 2,611 bytes per tier-2+ skill. The old ~3-5KB claim predated the preamble restructuring. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(retro,preamble): gstack-shortcut debt ledger — accepted shortcuts leave a joined trail When the user accepts an option that is BOTH Completeness <= 7 AND a durable-scope call, the decision ledger entry (gstack-decision-log, ceiling + upgrade trigger in the rationale) is the source of truth, and the agent marks each cut corner in code with gstack-shortcut(dec-<id>): <ceiling>, upgrade when <trigger> — same edit, no follow-up question, never agent-initiated. /retro Step 11.5 harvests markers into a debt ledger (grep || true — zero matches is the healthy case; skill installs and docs excluded), joins on the decision id so nothing double-counts, tags unlinked and no-trigger rot risks, and closes with 'N markers, M with no trigger.' /review suppressions: a marker with ceiling+trigger downgrades a would-be Completeness Gaps finding to acknowledged debt. Redaction test pins that the marker ships untouched (the ledger is the point) — it does not match the TODO(owner) hygiene shape. Format from dietrichgebert/ponytail's ponytail-debt; store inverted to gstack's existing decision ledger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: refresh golden ship baselines after preamble additions (reuse ladder + bounded closer) The golden-file regression test pins the rendered ship skill byte-for-byte; the WS3/WS7 preamble sections are deliberate changes, so the baselines re-capture per the goldens' own update protocol. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(hosts): instruction-only tier — a 2KB committed rules digest any agent host can read New agents-digest/gstack-AGENTS.md (1,765 bytes, hard 2,048-byte budget): gstack's ethos one-liners, the reuse ladder, and voice rules for hosts with no install arm — Zed, Amp, Jules, or any AGENTS.md-reading agent. Generated by scripts/gen-agents-digest.ts, auto-refreshed by gen:skill-docs, committed like llms.txt so setup's explainer arms can point at it before any toolchain exists. First line carries the gstack version as its own staleness nudge. Delivery is print-path + user-performed copy ONLY: setup never writes or overwrites a user's AGENTS.md (a test pins this — no cp/ln/mv/redirect into AGENTS.md anywhere in setup). openclaw and hermes explainer arms print the path; slate keeps routing to the full Claude install and gbrain ships from its own repo. HostConfig gains the optional install.instructionTier slot, declared by both instruction-tier hosts. README host table now matches what setup actually does. Inspired by dietrichgebert/ponytail's instruction-tier AGENTS.md fallback — one generated source, never per-host hand copies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(preamble): AskUserQuestion repetition cut — gated, passed NOT-WORSE A/B Removes the duplicate statements v1.71's compaction left in the AskUserQuestion Format section: the completeness rule restated in the prose triad, the auto-decide marker syntax stated twice, the Conductor-flakiness explanation stated twice, and the self-check's full triad restatement. Every verbosity floor and all 14 format pins stay (Layer 0 green). The gate this decision rested on ran before landing (new periodic skill-e2e-auq-repetition-cut-ab.test.ts, pre-cut ref3263fffevs this render, same harness as auq-verbose-vs-carved-ab): POST 7/7 format elements, substance 5 — identical to PRE. No degradation; the load-bearing-repetition hypothesis did not hold for these duplicates. Net: -236 bytes per tier-2+ skill (~9.7KB corpus). Golden ship baselines re-captured for the deliberate change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(evals): with-skill vs without-skill arm benchmark — measures whether gstack's behavioral layer earns its tokens Ponytail's honest-benchmark method pointed at gstack itself: 3 build-shaped tasks (native-platform over-build trap, CRUD endpoint, bug fix with planted decoys) x 2 arms, real claude -p sessions, scored on the git diff left behind. A research instrument, not a release gate — no assertion compares arm scores. Arms use the PROVEN project-scope pattern: the with-arm installs a build-discipline skill (extracted reuse-ladder + bounded-closer content, not whole-file copies) into the fixture's .claude/skills/ with a CLAUDE.md routing line and an explicit invocation; a live spike confirmed claude -p discovers and invokes project-scope skills via the Skill tool (3 turns, exact-output probe). Fixtures are git init + local bare origin; diff capture is three lines of git, no worktree machinery. Failure taxonomy: zero-diff arms are VALID scored cells (deterministic 0/none, no API call), harvest failures record harvest:null, judge_error cells are excluded from aggregates but named in the report — nothing drops silently. armJudge: fixed sonnet judge, 0-3 unrequested-structure rubric, must name the construct or say none, bounded retry-on-malformed; callJudge gains optional temperature/max_tokens (defaults unchanged). recordE2E now populates tokens_used for every E2E. Eval schema v2: harvest gains {insertions, deletions, net}, tolerant reads keep v1 runs comparable. Registered periodic in E2E_TIERS + touchfiles (with the auq-repetition-cut A/B); periodic detach timeout raised to the new shard-census floor. Free selftest (8 tests, zero API) pins fixtures, extraction, arm asymmetry, diff capture, judge plumbing, and the retry bound. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: absorb the ponytail-import wave into the guard fixtures — ceilings, schema pin, triad phrasing Skeleton ceilings re-captured for the 17 carved skills the wave deliberately grew (reuse ladder + bounded closer + shortcut trail, net of the gated -236B AUQ cut), each with its measured size in the comment per the carve-guards protocol. eval-store schema pin updated to v2 (harvest gains insertions/deletions/net). The AUQ prose-triad keeps its pinned per-choice phrasing ('explicit on EACH choice') while still deferring the score scale to the canonical Format rule — the shipped cut is strictly closer to the pre-cut text than the render that already passed the NOT-WORSE gate. Autoplan carve anchors follow the Phase 2.5 renumbering. Golden ship baselines re-captured. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: observability partial-file pin follows eval-store schema v2 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(test-runner): GSTACK_FREE_JOBS + opt-in flaky-retry pass for syscall-supervised sandboxes GSTACK_FREE_JOBS overrides the computed shard count (the free runner's analogue of the paid runner's EVALS_JOBS). On Vercel sandboxes, PID 1 installs a seccomp filter whose supervisor spuriously fails access(2) for busy processes — measured: 200/200 git-init probes fail 'Cannot access work tree: Permission denied' while the suite runs at 6 shards, 0/200 idle; statx succeeds while access fails on the same path in the same process. One serial mega-shard maximizes per-process pressure and fails too; 2 shards is the measured sweet spot. GSTACK_FREE_RETRY_FLAKY=1 (default OFF — dev boxes should see flakes) re-runs attributed failures once, serially, capped at 5 files; a clean retry downgrades to a loud FLAKY-PASS naming the offenders, a repeat failure stays red, timeouts and unattributed failures never retry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(browse): portable temp paths — TEMP_DIRS allowlist, tmpdir()-based test files Local path validation now accepts os.tmpdir() alongside the classic /tmp (new TEMP_DIRS in platform.ts): on macOS os.tmpdir() is /var/folders/..., and TMPDIR-honoring CI/sandbox environments point it elsewhere entirely — both are legitimate scratch space. Remote file serving (TEMP_ONLY) stays pinned to TEMP_DIR alone; no change to the exfil boundary. commands.test.ts drops 41 hardcoded /tmp literals for a tmpp() helper on os.tmpdir() (two message assertions now reference the same variable), and path-validation's symlink-escape test targets /etc/hosts instead of /etc/crontab — the target must EXIST for realpath to resolve the link (a dangling target falls back to the link's own path and passes vacuously), and /etc/crontab is absent on Amazon Linux. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(config): portable sha256 — Linux ships sha256sum, not shasum resolve-user-slug and endpoint hashing exited 127 on Amazon Linux (shasum is a macOS/perl tool). New _sha256_hex helper prefers sha256sum and falls back to shasum, matching gstack-verify-gate's existing pattern; both call sites converted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(next-version): only trust ls-remote when origin is actually configured Without the guard, git DWIMs the literal 'origin' as an ssh host/path; on hosts whose transport launders exit codes the probe 'succeeds' with zero branches and the allocator silently sees an empty queue — the exact duplicate-allocation failure (#2545) fetchGitClaimed exists to prevent. git remote get-url origin gates the probe; absence falls through to the existing local-refs path with its staleness warning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(testing): sandbox-doctor — one command makes a cloud sandbox run the suite green Measured failure taxonomy for Vercel/Conductor sandboxes (missing /dev/fd, 64M /dev/shm, seccomp-supervisor access(2) EACCES under load, uid-1000 processes with FULL capabilities defeating chmod-denial tests, no X server, no git identity, Conductor git-shim exit-code laundering) plus the idempotent script that treats all of it and seeds the run recipe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(config): converge on main's self-contained sha8_of — its tests extract the function standalone The merge kept a branch-local _sha256_hex helper; main's v1.72 landed the same portability fix inline WITH tests that extract sha8_of()'s text and run it under a shim-only PATH — a helper call can't satisfy that shape. Adopt the landed implementation at both hash sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: coverage for GSTACK_FREE_JOBS override and failingFiles attribution Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: coverage for TEMP_DIRS widening and remote-serving TEMP_ONLY asymmetry Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: coverage for gstack-shortcut marker grammar and retro harvest joint Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: coverage for sandbox-doctor shell syntax and idempotency guards Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test-runner): empty-shard outcome carries failingFiles; harden flaky-retry list The empty-shard early return omitted the (required) failingFiles field — tsc TS2741 — feeding undefined into the flaky-retry flatMap. Also drop the dead 'else if (worst !== 0)' guard (the enclosing if already pins it). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(release): version-bump write regenerates the version-stamped agents digest agents-digest/gstack-AGENTS.md embeds VERSION in its first line and is byte-freshness-gated (test/agents-digest.test.ts + Skill Docs Freshness CI), but nothing in the release path regenerated it — every version-bumping ship of this repo would land red. write now spawns the repo's own generator when present (agentsDigest true/false/null in the output JSON), and ship's evidence gate allow-lists the digest alongside VERSION/package.json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(setup): instruction-tier explainer prints the script-anchored digest path $(pwd) printed a nonexistent path when setup ran from any other directory; both arms now share one print_instruction_tier() using SOURCE_GSTACK_DIR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(digest): broaden AGENTS.md writer tripwire; pin digest-resolver ladder lockstep The print-path-only guard now catches tee/install/rsync/dd/truncate, >> appends, and laundered variable-destination writes. New test ties the digest's hand-rendered reuse-ladder text to the preamble resolver so an edit to either fails CI instead of shipping drift. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(retro): shortcut harvest drops placeholder markers and convention docs The Step 11.5 grep matched documentation mentions (dec-<id>, dec-*) in checklists, resolver sources, and convention tests, reporting phantom debt rows on gstack itself. A trailing filter kills placeholder forms; prose tells the agent to discard convention-quoting hits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(review): advisory findings count in per-specialist stats Without this, simplification (all-advisory by construction) would log findings:0 every run and auto-gate itself into permanent silence after 10 dispatches. The advisory carve-out governs score and header only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(evals): arm-benchmark harvest and judge hardening - Harvest diffs against the recorded seed SHA (origin/main is movable by an agent that commits AND pushes; a recorded SHA is not). - Fixtures get a node_modules .gitignore and the git wrapper a 64MB maxBuffer, so a vendored-dependency arm is scored instead of killing the cell. - The judge diff cap is a named constant with loud truncation (log + judge_reasoning suffix). - Judge prompt block markers carry a per-call random sentinel, so a diff containing a faked closing marker cannot escape the data block. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(evals): AUQ A/B vendored pre-cut arm + judge-error inconclusive taxonomy - The PRE arm read a branch-local SHA (3263fffe) that becomes unreachable on fresh clones after the squash-merge; the pre-cut render is now a vendored fixture. - A judge failure on one side no longer coerces substance to 0 (which fabricated DEGRADATION on POST-side failures and masked regressions on PRE-side failures): null substance = inconclusive, format still gates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: regression pin for the originConfigured guard vs laundering git shims On healthy hosts the guarded and unguarded paths behave identically, so a revert passes the suite; only a shim that makes 'git ls-remote' exit 0 with empty output (the Conductor wrapper's observed behavior) exposes it. Pins that the empty 'successful' probe is never trusted as an empty queue. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sandbox-doctor): missing /dev/shm no longer aborts the doctor under set -eu Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(touchfiles): close dep-list gaps for the new evals - arm-benchmark entries gain ship/SKILL.md (buildBehavioralSkill extracts sections from the rendered ship skill) - review-army-simplification entries gain their planted fixtures + test file - auq-repetition-cut-ab gains llm-judge.ts and the vendored PRE fixture Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: re-capture context-budget fixture — lock the WS6-3 reduction and Step 9 deltas Per the ratchet protocol: the AUQ repetition cut shrank per-skill eager tokens but the fixture was never re-captured, leaving the win unlocked. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(release): digest regen is an explicit --regen-digest opt-in, not presence-sniffed code exec Review (security) caught the cycle-1 fix executing any repo's scripts/gen-agents-digest.ts on plain 'write' — arbitrary code exec from a hostile clone on a routine bump, contradicting the binary's own containment posture. The regen still runs the TARGET repo's generator (a 'trusted' copy beside the binary would false-red the freshness gate on version drift), but only under the flag: /ship passes it deliberately, in a repo whose code the operator already executes (its test suite). Plain write is side-effect-free again. Also: uniform output shape (agentsDigest: null on the JSON-manifest branch), a REAL generator round-trip test replacing the misnamed lockstep check, and land-and-deploy's evidence gate gets the same digest allow-path as ship so the two grading surfaces agree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test-runner): flaky-retry vetoes on ANY unattributable failure evidence The gate equated 'some failure attributed' with 'all failures attributed': a shard with one attributed failure plus a headerless failure, an unhandled error between tests, or a truncated run (no terminal summary) qualified for retry — re-running only failingFiles and masking the rest as FLAKY-PASS, re-opening the silent-truncation hole the strict classifier closes. FreeShardOutcome now carries unattributedFailures; nonzero vetoes the retry. Pins: mixed shard, truncated-with-attributed shard, empty-shard field values. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(next-version): a configured origin advertising zero heads is never trusted The originConfigured guard covered only the no-origin laundering case. With origin configured (the normal Conductor worktree state), the laundering shim makes a failed ls-remote exit 0 with empty stdout — read as 'the queue is empty', the exact duplicate-allocation bug (#2545) one layer up. A reachable remote always advertises at least its default branch, so an exit-0 zero-head probe now falls back to local refs/remotes/origin with a laundering-specific warning. Regression test shims git for both configurations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sandbox-doctor): loud on git-shim patch drift; document the retry-contract override - The /conductor/bin/git patch was a silent no-op if the shim's bytes drift from the exact pattern — now warns that laundering is NOT fixed. - The bashrc block documents why GSTACK_FREE_RETRY_FLAKY=1 deliberately overrides the runner's default-OFF contract on this sandbox, and how to undo it. - Test pins the guarded shm form (missing /dev/shm must not abort set -eu). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(digest): pin the script-anchored explainer path; catch declaration-prefixed writers - Asserts $SOURCE_GSTACK_DIR/agents-digest path and forbids $(pwd)/agents-digest (the cycle-1 fix was revertible without failing anything). - The laundered-assignment arm now matches local/export/declare/readonly/typeset prefixed assignments — the likeliest in-function writer shape in setup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(evals): arm-benchmark selftest runs FREE on every PR The selftest lived inside the paid skill-e2e-* file, so fixture-integrity and plumbing pins executed weekly at best — a broken fixture would ship past every gating check and be discovered when the periodic run burned money on a dead instrument. Harness extracted to test/helpers/arm-benchmark-harness.ts, selftest to test/arm-benchmark-selftest.test.ts (free suite). Touchfiles: harness added to the three benchmark dep lists; the auq-repetition-cut-ab tier comment now states the MANUAL re-run obligation honestly (periodic runs force EVALS_ALL, so dep lists cannot auto-trigger it). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: re-capture context-budget fixture after cycle-2 template deltas Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sandbox-doctor): keep both heredoc bodies under the 512B pipe-deadlock window The cycle-2 additions pushed the python-patch and bashrc heredocs into the 512-65536B window test/heredoc-pipe-deadlock.test.ts guards (sh scripts get no BASH_COMPAT escape hatch). Same content, tighter prose; the drift warning now reuses the patch pattern variable instead of a second literal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(review): a gstack-shortcut marker only suppresses findings when its decision id resolves in the ledger Cross-model catch (Claude adversarial + Codex agreed): any diff author could fabricate a marker and silence Completeness review of that gap. Reviewers now resolve the dec-id via gstack-decision-search; an orphan marker is reported as a forged suppression, not honored as debt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(autoplan): define the B2 gate path — accepted premise challenges amend the plan and re-run Eng The final gate offered B2 (respond to User Challenges) but the option handler table omitted it, leaving accepted challenges with no amendment or Eng re-review path. B2 now walks challenges one at a time; an accepted one amends the plan and re-runs Eng (the gate always reviews the final plan), sharing D's 3-cycle cap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(evals): arm benchmark runs each fixture's functional oracle — correctness before LOC The plan's metric order is diff-quality FIRST, but cells never ran the fixtures' own run-tests.js, so a refusal, a broken implementation, and working code were indistinguishable in aggregates (Codex adversarial catch). Tasks with an oracle declare checkCmd; every cell records checks=pass|fail|none in the report line and eval store. Selftest pins the oracle declarations and that the planted bug fails its own check pre-fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ship): check the bump's agentsDigest result; state the --regen-digest trust envelope honestly A failed digest regen warned and moved on — ship now instructs re-running the generator and staging the digest with the bump (the freshness check stays red otherwise). The 'no-op everywhere else' phrasing oversold safety: the step now names what executes and why that is inside the envelope Step 5 already opened (the repo's own test suite). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test-runner): GSTACK_FREE_JOBS accepts digits only — parseInt truncation defeated the loud-failure contract '2abc' silently became 2 and '3.7' became 3 despite the error text claiming a positive-integer requirement. Strict /^\d+$/ pre-check; both shapes pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sandbox-doctor): atomic git-shim patch, :99-socket Xvfb check, dnf gate, non-interactive sudo - The /conductor/bin/git patch writes tmp-then-rename with a .orig backup — a concurrently spawned git can never exec a truncated shim. - Xvfb running-check looks for the :99 socket, not any-display pgrep. - Xvfb install is dnf-gated so non-dnf distros degrade to a warning instead of aborting the remaining fixes under set -eu. - The bashrc /dev/fd restore uses sudo -n || true — no password prompt at every shell start on non-passwordless machines. - BASH_COMPAT=50 keeps heredoc bodies off the bash pipe window. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(build): a failed agents-digest regen fails gen-skill-docs instead of deferring the red to CI Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(browse): an untrustable TMPDIR (/, $HOME, a cwd ancestor) never widens the local allowlist TEMP_DIRS honors os.tmpdir() at daemon start; a daemon launched with TMPDIR=/ would have trusted the whole filesystem for local path validation for its lifetime. Subprocess pins cover /, $HOME, cwd-ancestor rejection and that a benign distinct TMPDIR (the sandbox recipe's $HOME/tmp) stays honored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: zero-heads warning names the benign cause too; digest path declaration made load-bearing; ratchet re-capture - The ls-remote zero-heads warning no longer accuses an empty remote of running a laundering shim. - instructionTier.rulesFile now must equal the generator's DIGEST_RELPATH (and setup must print it) — the declaration fails with the real path instead of lying silently. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: file ship-time follow-ups in TODOS skillify HOME-override gate red (pre-existing, proven on main), the auq-verbose-vs-carved-ab branch-local ref, eval-store harvest union, evidence digest allow-path scoping, and the WS6-2 dead-frontmatter live-host verification deferral. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * v1.73.0.0 chore: version bump + CHANGELOG — ponytail import wave Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: raise ship skeleton parity ceiling — measured 75,592 after the v1.73 release-step prose The --regen-digest trust-envelope paragraph (Step 12) and the evidence-gate digest note (Step 16) grew the ship skeleton past the previous 75,420 ceiling. Re-measured per the deliberate-change protocol. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: update project documentation for v1.73.0.0 - README.md, docs/skills.md, AGENTS.md: /autoplan phase order corrected to CEO → design → DX → eng (eng always last); /review rows note the advisory simplification lens - docs/PROJECT_STRUCTURE.md: add agents-digest/, gen-agents-digest.ts, sandbox-doctor.sh, test-free-shards.ts to the annotated tree - CONTRIBUTING.md: document GSTACK_FREE_JOBS, GSTACK_FREE_RETRY_FLAKY, and the sandbox-doctor one-command fixer in the Tier 1 test section Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: apply cross-model doc-review fixes for v1.73.0.0 - README.md: host table gains the OpenClaw explainer arm row (setup has the arm; the table claimed to match setup) - docs/skills.md: /review completeness-gaps section documents the gstack-shortcut(dec-<id>) acknowledged-debt suppression and orphan-marker flagging; /autoplan deep-dive states the recommended-option default with the 6 principles as tie-breakers - CONTRIBUTING.md: host count 8 -> 10 (Hermes, GBrain), supported-hosts list completed - docs/TESTING_INTERNALS.md: sandbox recipe says to source ~/.bashrc after the doctor seeds it; GSTACK_FREE_JOBS wording fixed from "caps" to "overrides in either direction" (matches the un-clamped runner) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test): temp-dirs asymmetry pins are topology-aware; TMPDIR probes are POSIX-only CI exposed two wrong assumptions in the new temp-dirs tests, neither a product bug: - The remote-serving asymmetry test assumed a distinct os.tmpdir() lies OUTSIDE TEMP_DIR, but the free-shard runner nests each child's TMPDIR inside /tmp on CI — a file there is under TEMP_DIR, so serving it remotely is legitimate. The test now pins the actual exfil boundary on every topology (a cwd project file is locally readable, never remotely servable) and branches the os.tmpdir() case on nested-vs-outside. Reproduced locally with TMPDIR=/tmp/nested-tmp before fixing. - The untrustable-TMPDIR subprocess probes set TMPDIR, which Windows os.tmpdir() ignores (reads TEMP/TMP) — and on Windows TEMP_DIR is DEFINED as os.tmpdir(), so the fixed+movable two-dir topology the guard filters does not exist there. Probes now skip on Windows with that rationale; the benign-TMPDIR assertion compares realpaths. Verified under all three POSIX topologies: TMPDIR=$HOME/tmp (outside), TMPDIR=/tmp/nested-tmp (CI shard shape), TMPDIR unset (identical). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(build): DIGEST_RELPATH is a forward-slash literal on every platform path.join built it with backslashes on Windows, so the wiring test's string comparisons against setup and hosts/*.ts (which carry the forward-slash literal) could never match there — windows-free-tests red. path.join(root, DIGEST_RELPATH) at the write site normalizes fine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(sandbox-doctor): bashrc block re-heals the /dev/shm remount on sandbox restart The 4G remount does not survive restarts; a reverted 64M shm made the multi-tab browse handoff test fail consistently under suite concurrency (observed live: two consecutive full-run failures, green in isolation, green again after remounting). Same guarded arithmetic as the doctor body. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test): close the cross-shard porcelain race that failed Windows CI Two-part fix for the gen-skill-docs-out-dir isolation-pin failure: - cookie-import-browser built its scratch cookie DBs inside the TRACKED browse/test/fixtures/ dir (created in beforeAll, deleted in afterAll), so they flash as untracked files mid-run — a concurrent shard's porcelain snapshot caught the window on Windows. The DBs now live in a per-run tmpdir; zero source-tree writes. - gen-skill-docs-out-dir is the free suite's only LIVE porcelain-snapshot test, so it joins TREE_MUTATING (the serial quiet window): any concurrent transient tree-write can race it, and its own spawned render rewrites llms.txt/agents-digest in place (idempotent on a fresh tree). The race is pre-existing; this branch's +5 test files reshuffled shard composition and exposed it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * v1.75.0.0 chore: queue-advance rebump — perth-v2 landed v1.74.0.0 on main The v1.73.0.0 slot this branch claimed was superseded when #2721 merged; same MINOR level relative to main per the versioning invariant. CHANGELOG entry renumbered (1.73.0.0 was branch-internal and never landed on main), digest restamped via --regen-digest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test-runner): duration-packed walls keep the per-file floor — predictions don't transfer across machines The committed duration seed is recorded on fast CI; a syscall-supervised sandbox replays the same files 2-4x slower. Observed post-merge: a 253-file shard predicted ~242s was wall-killed at its predicted-x3 725s wall while genuinely progressing (the old count heuristic guaranteed 1265s). Packed walls may be looser than the count floor, never tighter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
714 lines
41 KiB
TypeScript
714 lines
41 KiB
TypeScript
/**
|
|
* Canonical carved-skill guard registry — the single source of truth for which
|
|
* skills are carved (skeleton SKILL.md + on-demand sections/*.md) and what each
|
|
* carve must guarantee.
|
|
*
|
|
* PURE LEAF DATA MODULE (codex outside-voice #1, refined-plan pass): this file
|
|
* has NO runtime imports — `import type` only. parity-harness.ts and
|
|
* skill-size-budget.test.ts derive their carved-skill lists FROM here (no
|
|
* parallel hand-maintained lists), so a runtime import back into either of them
|
|
* would create a cycle. Keep it data.
|
|
*
|
|
* Consumers:
|
|
* - test/carve-section-ordering.test.ts (E2, gate) → staticInvariants
|
|
* - test/carve-section-loading.test.ts (T2, periodic) → requiredReads + scenario
|
|
* - test/carve-guard-completeness.test.ts (E1, gate) → the set must equal the
|
|
* filesystem carved set
|
|
* - test/carve-guards-negative.test.ts (ET1, gate) → injects a broken fixture
|
|
* - test/helpers/parity-harness.ts → sectioned/maxSkeletonBytes/minBytes/mustContain
|
|
* - test/skill-size-budget.test.ts → SECTIONS_EXTRACTED = CARVED_SKILLS
|
|
*
|
|
* Adding a carve = add one entry here (atomically, in the same commit as the
|
|
* skeleton + manifest + sections — codex #4 — so E1's bidirectional parity never
|
|
* false-positives mid-commit).
|
|
*/
|
|
|
|
/** Static (skeleton-shape) invariants the per-PR ordering guard (E2) asserts. */
|
|
export interface CarveStaticInvariants {
|
|
/**
|
|
* Substrings that MUST remain in the always-loaded skeleton. Empty = skip
|
|
* (the skill has no distinctive pre-STOP anchor worth pinning beyond the
|
|
* universal STOP/section-index checks E2 already runs).
|
|
*/
|
|
mustStayInSkeleton: string[];
|
|
/**
|
|
* Substrings that MUST appear in the skeleton BEFORE the first STOP-Read
|
|
* (earliest-use, codex #6). For cso: mode-dispatch directives (## Arguments,
|
|
* ## Mode Resolution) must be resolved before any section is read — a dispatch
|
|
* directive stranded after the STOP can't govern which sections to read.
|
|
* Empty/undefined = skip (most skills).
|
|
*/
|
|
mustPrecedeStop?: string[];
|
|
/**
|
|
* Substrings that MUST be in the union (skeleton + sections) but MUST NOT be in
|
|
* the skeleton — i.e. the heavy body that the carve relocated. Empty = skip.
|
|
*/
|
|
mustMoveToSection: string[];
|
|
/**
|
|
* If set, this marker must appear in the skeleton AFTER the last STOP-Read
|
|
* directive (e.g. the EXIT PLAN MODE GATE that fires once section work returns).
|
|
* Undefined = the skill has no post-STOP gate (operational/conversational carve).
|
|
*/
|
|
gateAfterStop?: string;
|
|
}
|
|
|
|
export interface CarveGuard {
|
|
skill: string;
|
|
/** Section .md filenames the manifest lists and the skeleton must STOP-Read. */
|
|
expectedSections: string[];
|
|
/**
|
|
* Sections the behavioral test (T2) asserts the agent actually Read when driven
|
|
* by `scenario`. A non-empty subset of expectedSections — the ones the scenario
|
|
* is built to require. The registry owns this so "registered ⇒ asserted" is
|
|
* structural (codex #2), not policed.
|
|
*/
|
|
requiredReads: string[];
|
|
/**
|
|
* Fixture prompt that drives a real `claude -p` run down the STOP-Read path for
|
|
* this skill (codex #7). The behavioral test asserts the run reached the STOP
|
|
* (read requiredReads), not merely that nothing was read.
|
|
*/
|
|
scenario: string;
|
|
staticInvariants: CarveStaticInvariants;
|
|
/**
|
|
* How the behavioral guard (T2) exercises this skill:
|
|
* - 'plan' → write a PLAN.md fixture, run the review against it
|
|
* - 'prompt' → no fixture file; the scenario prompt alone drives the run
|
|
* - 'external' → covered by a dedicated bespoke test (complex fixtures, e.g.
|
|
* ship's git/VERSION/CHANGELOG state). The data-driven loop
|
|
* skips it; E1 asserts `externalTest` exists instead.
|
|
*/
|
|
behavioral: 'plan' | 'prompt' | 'external';
|
|
/** Required when behavioral === 'external': path (repo-relative) to the dedicated test. */
|
|
externalTest?: string;
|
|
/** Parity: max bytes for the always-loaded skeleton (asserts the carve shrank it). */
|
|
maxSkeletonBytes: number;
|
|
/** Parity: min bytes for the skeleton+sections union (total behavior preserved). */
|
|
minUnionBytes: number;
|
|
/** Parity: content phrases the union must preserve. */
|
|
mustContain: string[];
|
|
/**
|
|
* Parity: optional per-skill override for the union size-growth ceiling vs the
|
|
* v1.53.0.0 baseline (default 1.05). Bumped only when a deliberate cross-cutting
|
|
* preamble feature legitimately grows a smaller carved skeleton past 5%.
|
|
*/
|
|
maxSizeRatio?: number;
|
|
}
|
|
|
|
export const CARVE_GUARDS: Record<string, CarveGuard> = {
|
|
ship: {
|
|
skill: 'ship',
|
|
expectedSections: [
|
|
'apple-release.md',
|
|
'tests.md',
|
|
'test-coverage.md',
|
|
'plan-completion.md',
|
|
'review-army.md',
|
|
'greptile.md',
|
|
'adversarial.md',
|
|
'changelog.md',
|
|
'pr-body.md',
|
|
],
|
|
requiredReads: ['review-army.md', 'changelog.md'],
|
|
scenario:
|
|
'This is a FRESH version-changing ship: the branch has a real code change, VERSION still equals the base version (needs a bump), and CHANGELOG.md needs a new entry. Follow the skill flow for a version-changing ship: run the pre-landing review and prepare the CHANGELOG entry. Produce the ship plan / review report. Do NOT actually commit, push, or open a PR.',
|
|
staticInvariants: {
|
|
// The PR-title-version invariant MUST stay always-loaded: the v1.54.0.0
|
|
// carve stranded it in pr-body.md and PRs started landing with bare titles
|
|
// (CI backstop: test/pr-title-sync-workflow-safety.test.ts).
|
|
// Same carve also stranded the Step 18 /document-release dispatch out of
|
|
// sight — the skeleton never named it and the handoff "got lost" (#2666
|
|
// follow-up). Three NON-OVERLAPPING anchors pin the restored visibility,
|
|
// one per touchpoint (no anchor is a substring of another, so each is
|
|
// independently enforced — a subsumed anchor adds zero enforcement):
|
|
// gerund form → manifest trigger (renders 2x: section index + STOP)
|
|
// imperative → Step 17 handoff line
|
|
// 3rd person → hoisted doc-sync invariant
|
|
// Matching is case-sensitive String.includes — "dispatching the" does NOT
|
|
// contain "dispatch the" — so update anchors in lockstep with any
|
|
// touchpoint rewording.
|
|
mustStayInSkeleton: [
|
|
'v$NEW_VERSION',
|
|
'gstack-pr-title-rewrite',
|
|
'dispatching the /document-release subagent to sync docs',
|
|
'dispatch the /document-release subagent to sync docs',
|
|
'dispatches the /document-release subagent',
|
|
],
|
|
// ...while the full create/update procedure stays carved into pr-body.md
|
|
// (out of the skeleton, present in the union). Asserts BOTH PR paths
|
|
// survive: the create path and the idempotent update path. The Step 18
|
|
// dispatch imperative stays carved too — pasting that literal into the
|
|
// skeleton (correctly) fails this guard; the skeleton speaks of "the
|
|
// /document-release subagent", never the carved imperative.
|
|
mustMoveToSection: [
|
|
'gh pr create --base',
|
|
'gh pr edit --title',
|
|
'Dispatch /document-release as a subagent',
|
|
],
|
|
// ship is operational (multi-STOP, not a plan review); no single post-STOP gate.
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'external',
|
|
externalTest: 'test/skill-e2e-ship-section-loading.test.ts',
|
|
maxSkeletonBytes: 76_200, // + v1.73 --regen-digest trust-envelope + evidence-gate digest prose; measured 75_592
|
|
minUnionBytes: 181_000, // token-reduction Phases 1-2 (v1.69.x branch); measured union 201,464
|
|
mustContain: ['VERSION', 'CHANGELOG', 'review', 'merge', 'PR'],
|
|
// v1.58.5.0: pre-push-guard install (#2077) stacks on the shared first-run-guidance preamble.
|
|
// Fork port wave 2: multi-ecosystem test-detection evidence (Django/JVM
|
|
// markers, test-file census — e3259078 port) + the #1079 gh pr edit REST
|
|
// fallback grew the union to 1.090x; the third-party web-actions
|
|
// contract (consent-gated browser drive for API-key registration etc.)
|
|
// adds ~2.3KB inline judgment, measured 1.103x. The Apple release
|
|
// adapter (14.8KB carved section, 21 live releases of judgment — the
|
|
// wave's headline capability) grows the union to 1.195x. Deliberate:
|
|
// the section is on-demand (loads only for Apple store targets), so
|
|
// per-invocation cost for non-iOS ships is one manifest line.
|
|
maxSizeRatio: 1.22,
|
|
},
|
|
'plan-ceo-review': {
|
|
skill: 'plan-ceo-review',
|
|
expectedSections: ['review-sections.md'],
|
|
requiredReads: ['review-sections.md'],
|
|
scenario:
|
|
'Review the plan in PLAN.md. Hold the current scope (HOLD SCOPE mode) — do not challenge or expand scope. Run the full CEO review and produce the review report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: ['## Step 0: Nuclear Scope Challenge'],
|
|
mustMoveToSection: ['### Section 1: Architecture Review', '## Mode Quick Reference'],
|
|
gateAfterStop: 'EXIT PLAN MODE GATE',
|
|
},
|
|
behavioral: 'external',
|
|
externalTest: 'test/skill-e2e-plan-ceo-review-section-loading.test.ts',
|
|
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
|
|
// Fork port wave 2 (#703): the repo-doc-preference block in the design
|
|
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
|
|
maxSkeletonBytes: 74_830, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 74_221
|
|
minUnionBytes: 123_600, // token-reduction Phases 1-2 (v1.69.x branch): preamble bash -> bin/gstack-skill-start, onboarding -> gated emission; measured union 137,346
|
|
mustContain: ['SCOPE EXPANSION', 'SELECTIVE EXPANSION', 'HOLD SCOPE', 'SCOPE REDUCTION'],
|
|
// Default-on Codex outside-voice (codexPreflight block + CODEX_MODE branch
|
|
// prose replacing the smaller opt-in question) lands this ~5.2% over baseline.
|
|
maxSizeRatio: 1.08,
|
|
},
|
|
'plan-eng-review': {
|
|
skill: 'plan-eng-review',
|
|
expectedSections: ['review-sections.md'],
|
|
requiredReads: ['review-sections.md'],
|
|
scenario:
|
|
'Review the plan in PLAN.md. Accept the current scope. Run the full engineering review (architecture, code quality, tests, performance) and produce the review report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: ['### Step 0: Scope Challenge'],
|
|
mustMoveToSection: ['### 1. Architecture review'],
|
|
gateAfterStop: 'EXIT PLAN MODE GATE',
|
|
},
|
|
behavioral: 'plan',
|
|
// v1.2.0 activation lift (shared first-run-guidance preamble) + #2077 ask-first scope gate.
|
|
// +~1 KB: plan-mode auto-select-B scope-gate exceptions (2026-08).
|
|
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
|
|
// Fork port wave 2 (#703): the repo-doc-preference block in the design
|
|
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
|
|
// #2499 project-scope MCP jq in the brain-sync block grew every tier-2+
|
|
// skeleton ~1.5KB (entry resolution emitted once per SKILL.md).
|
|
maxSkeletonBytes: 52_710, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 52_104
|
|
minUnionBytes: 99_800, // token-reduction Phases 1-2 (v1.69.x branch); measured union 110,910
|
|
mustContain: ['Architecture', 'Code Quality', 'Test', 'Performance'],
|
|
// Cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback + the
|
|
// decision-memory nudge + the v1.57.4.0 Boil-the-Ocean rename) plus the
|
|
// default-on Codex outside-voice (codexPreflight block + CODEX_MODE branch
|
|
// prose, replacing the smaller opt-in question) land this at ~6.6% over the
|
|
// v1.53.0.0 baseline. Headroom for those intentional additions.
|
|
// 1.08 → 1.10: the scope-gate exceptions block (+ its adversarial-review
|
|
// hardening: host-anchored mode signal, precedence, passing-mention
|
|
// guards) and the plan-mode preamble reword land the union at 1.092.
|
|
maxSizeRatio: 1.12, // measured 1.103
|
|
},
|
|
'plan-design-review': {
|
|
skill: 'plan-design-review',
|
|
expectedSections: ['review-sections.md'],
|
|
requiredReads: ['review-sections.md'],
|
|
scenario:
|
|
'Review the plan in PLAN.md for design and UX. Accept the current scope. Run the full design review passes and produce the review report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [],
|
|
mustMoveToSection: ['### Pass 1: Information Architecture'],
|
|
gateAfterStop: 'EXIT PLAN MODE GATE',
|
|
},
|
|
behavioral: 'plan',
|
|
// +Conductor AUQ-default-prose rule + one-way/continuation safety in the
|
|
// always-loaded AskUserQuestion Format section.
|
|
// v1.2.0 activation lift (shared first-run-guidance preamble) + #2077 ask-first scope gate.
|
|
// +~1.3 KB: plan-mode auto-select-B scope-gate exceptions (2026-08).
|
|
// Fork port wave 2 (D1): evidence directive adds ~0.45KB to every
|
|
// tier-2+ skeleton (measured 89,184). Main's v1.64.0.0 adds ~340 B more
|
|
// (telemetry --error-message/--failed-step preamble prose, PR #769).
|
|
// Budget covers the sum of both waves.
|
|
maxSkeletonBytes: 72_690, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 72_082
|
|
minUnionBytes: 99_200, // token-reduction Phases 1-2 (v1.69.x branch); measured union 110,293
|
|
mustContain: ['design', 'visual'],
|
|
maxSizeRatio: 1.12, // D1 1.104 + main's ~0.008
|
|
},
|
|
'plan-devex-review': {
|
|
skill: 'plan-devex-review',
|
|
expectedSections: ['review-sections.md'],
|
|
requiredReads: ['review-sections.md'],
|
|
scenario:
|
|
'Review the plan in PLAN.md for developer experience. Accept the current scope. Run the full DX review passes and produce the review report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [],
|
|
mustMoveToSection: ['### Pass 1: Getting Started Experience'],
|
|
gateAfterStop: 'EXIT PLAN MODE GATE',
|
|
},
|
|
behavioral: 'plan',
|
|
// +Conductor AUQ-default-prose rule + one-way/destructive prose safety +
|
|
// continuation protocol in the always-loaded AskUserQuestion Format section.
|
|
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
|
|
// Fork port wave 2 (#703): the repo-doc-preference block in the design
|
|
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
|
|
// #2499 project-scope MCP jq in the brain-sync block grew every tier-2+
|
|
// skeleton ~1.5KB (entry resolution emitted once per SKILL.md).
|
|
maxSkeletonBytes: 64_420, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 63_817
|
|
minUnionBytes: 99_700, // token-reduction Phases 1-2 (v1.69.x branch); measured union 110,833
|
|
mustContain: ['developer experience', 'Getting Started'],
|
|
// Default-on Codex outside-voice (codexPreflight block + CODEX_MODE branch
|
|
// prose replacing the smaller opt-in question) lands this ~5.7% over baseline.
|
|
maxSizeRatio: 1.08,
|
|
},
|
|
'office-hours': {
|
|
skill: 'office-hours',
|
|
expectedSections: ['design-and-handoff.md', 'phase-2a-startup-diagnostic.md', 'phase-2b-builder-brainstorm.md'],
|
|
// Phase sections are mode-exclusive (a session runs exactly one of 2A/2B),
|
|
// so only the always-reached design/handoff section is a deterministic read.
|
|
requiredReads: ['design-and-handoff.md'],
|
|
scenario:
|
|
'Run office hours for this product idea through to the end: have the diagnostic conversation, explore alternatives, then write the design doc and run the relationship handoff (Phases 5-6).',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [],
|
|
mustMoveToSection: ['### The Six Forcing Questions', '### Pushback Patterns', 'Anti-Sycophancy Rules', 'Wild exemplar'],
|
|
mustPrecedeStop: ['**Mode mapping:**'],
|
|
gateAfterStop: '## Section self-check',
|
|
},
|
|
behavioral: 'prompt',
|
|
// v1.2.0 activation lift: first-run-guidance section in the shared preamble,
|
|
// plus the P1 office-hours closing handoff (AUQ that launches the next skill).
|
|
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
|
|
// Fork port wave 2: the third-party web-actions contract sits inline
|
|
// (judgment must be visible before the workflow directs the user to a
|
|
// vendor site), plus the #703 dual-write + repo-doc-preference block and
|
|
// the #538 opt-out + D1 evidence directive — ratio 1.104 measured.
|
|
// #2499 project-scope MCP jq in the brain-sync block grew every tier-2+
|
|
// skeleton ~1.5KB (entry resolution emitted once per SKILL.md).
|
|
maxSkeletonBytes: 72_120, // ponytail-import wave + v1.72 Aside third-party-actions contract (merged); measured 71_511
|
|
minUnionBytes: 115_800, // Phase 4 wave 4; measured union 118,175
|
|
mustContain: ['design doc', 'problem statement'],
|
|
maxSizeRatio: 1.12,
|
|
},
|
|
'document-release': {
|
|
skill: 'document-release',
|
|
expectedSections: ['release-body.md'],
|
|
requiredReads: ['release-body.md'],
|
|
scenario:
|
|
'A PR has shipped a new CLI flag and touched README.md and CHANGELOG.md. Skip the git pre-flight shell commands (assume the diff adds --new-flag and updates those two docs). Run the documentation workflow: build the coverage map, then audit the docs, apply updates, and polish the CHANGELOG voice. Produce the documentation health summary.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: ['## Step 1: Pre-flight', '## Step 1.5: Coverage Map'],
|
|
mustMoveToSection: ['## Step 2: Per-File Documentation Audit', '## Step 5: CHANGELOG Voice Polish'],
|
|
// Operational skill (no plan-mode review gate).
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
// +Conductor AUQ-default-prose rule + one-way/continuation safety in the
|
|
// always-loaded AskUserQuestion Format section.
|
|
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
|
|
maxSkeletonBytes: 38_070, // token-reduction Phases 1-2 (v1.69.x branch): preamble bash -> bin/gstack-skill-start, onboarding -> gated emission; measured 37,469
|
|
minUnionBytes: 56_700, // token-reduction Phases 1-2 (v1.69.x branch): preamble bash -> bin/gstack-skill-start, onboarding -> gated emission; measured union 63,018
|
|
mustContain: ['CHANGELOG', 'Diataxis', 'coverage'],
|
|
// Two intentional additions stack on this small skill: the AUQ-failure prose
|
|
// fallback (v1.57.2.0, ~2KB to every preamble) AND the new default-on Codex
|
|
// documentation-review section (codexPreflight + prompt + apply-gate, carved
|
|
// into release-body so the SKELETON stays under maxSkeletonBytes). On a ~55KB
|
|
// baseline that whole new capability is ~18.6% of union bytes. The doc review
|
|
// is a deliberate new feature, not preamble creep; the union ceiling is raised
|
|
// to match while the skeleton budget (50_000) still holds the always-loaded
|
|
// cost flat.
|
|
maxSizeRatio: 1.20,
|
|
},
|
|
'design-consultation': {
|
|
skill: 'design-consultation',
|
|
expectedSections: ['proposal-and-preview.md'],
|
|
requiredReads: ['proposal-and-preview.md'],
|
|
scenario:
|
|
'The user gave product context (a B2B analytics dashboard for ops teams) and declined the research phase. Skip browser/design tool setup. Proceed to build the complete design-system proposal, then write DESIGN.md. Produce the proposal and the DESIGN.md content.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: ['## Phase 0: Pre-checks', '## Phase 1: Product Context', '## Phase 2: Research'],
|
|
mustMoveToSection: ['## Phase 3: The Complete Proposal', '## Phase 6: Write DESIGN.md'],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
// +Conductor AUQ-default-prose rule + one-way/continuation safety in the
|
|
// always-loaded AskUserQuestion Format section.
|
|
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
|
|
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
|
|
// v1.64.1.0: shared-preamble prose from the two parallel v1.64 waves lands
|
|
// the skeleton at 69,022 B; +~1 KB headroom.
|
|
maxSkeletonBytes: 52_340, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 51_739
|
|
minUnionBytes: 65_000, // token-reduction Phases 1-2 (v1.69.x branch): preamble bash -> bin/gstack-skill-start, onboarding -> gated emission; measured union 72,252
|
|
mustContain: ['Typography', 'Color', 'Aesthetic Direction'],
|
|
// Cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback ~2KB +
|
|
// the cross-session decision-memory nudge) lands this carved skeleton just over
|
|
// the strict 1.05; headroom for the shared preamble additions.
|
|
// v1.64+v1.65 merge sums both waves' preamble growth; measured 1.073.
|
|
maxSizeRatio: 1.08,
|
|
},
|
|
cso: {
|
|
skill: 'cso',
|
|
expectedSections: ['audit-phases.md'],
|
|
requiredReads: ['audit-phases.md'],
|
|
scenario:
|
|
'Run a security audit on this repository in --owasp mode (OWASP Top 10 only). Resolve the mode, do the Phase 0 stack detection and Phase 1 attack-surface census, then run the scoped audit phases and produce the findings report. Skip any step that needs network access.',
|
|
staticInvariants: {
|
|
// Dispatch + always-run + FP-filtering phases are ALWAYS loaded (security).
|
|
mustStayInSkeleton: [
|
|
'## Arguments',
|
|
'## Mode Resolution',
|
|
'### Phase 0',
|
|
'### Phase 1',
|
|
'### Phase 12',
|
|
'### Phase 13',
|
|
'### Phase 14',
|
|
],
|
|
// Earliest-use: mode must be resolvable before any section is read (codex #6).
|
|
mustPrecedeStop: ['## Arguments', '## Mode Resolution'],
|
|
// Scope-dependent audit detail moved to the section.
|
|
mustMoveToSection: [
|
|
'### Phase 2: Secrets Archaeology',
|
|
'### Phase 9: OWASP Top 10 Assessment',
|
|
'### Phase 10: STRIDE Threat Model',
|
|
],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
// +Conductor AUQ-default-prose rule + one-way/continuation safety in the
|
|
// always-loaded AskUserQuestion Format section.
|
|
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
|
|
maxSkeletonBytes: 57_390, // token-reduction Phases 1-2 (v1.69.x branch); measured 56,789
|
|
minUnionBytes: 64_200, // token-reduction Phases 1-2 (v1.69.x branch); measured union 71,379
|
|
mustContain: ['OWASP', 'STRIDE', 'daily', 'comprehensive', 'verif'],
|
|
// cso keeps its mode-dispatch + FP-filtering phases always-loaded, so the
|
|
// cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback ~2KB + the
|
|
// decision-memory nudge) lands it just over 1.05; headroom for the shared additions.
|
|
// v1.64+v1.65 merge sums both waves' preamble growth; measured 1.073.
|
|
maxSizeRatio: 1.08,
|
|
},
|
|
// ── Token-reduction Phase 4 wave 1 (v1.69.x branch) ──────────────────────
|
|
review: {
|
|
skill: 'review',
|
|
expectedSections: ['plan-completion.md', 'review-army.md', 'adversarial.md'],
|
|
requiredReads: ['plan-completion.md', 'review-army.md'],
|
|
scenario:
|
|
"The working tree has a real diff against the base branch (assume Step 1's git checks passed; the diff implements the PLAN.md cache layer). Run the /review flow: the scope-drift and plan-completion deep pass against PLAN.md, then the critical pass, then the Review Army specialist dispatch — apply the specialist checklists yourself instead of launching subagents. Produce the review report. Do NOT commit, push, or create a PR.",
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## Step 0: Detect platform and base branch',
|
|
'## Step 1: Check branch',
|
|
'## Step 1.5: Scope Drift Detection',
|
|
'## Step 4: Critical pass (core review)',
|
|
'## Confidence Calibration',
|
|
'## Step 5: Fix-First Review',
|
|
'## Important Rules',
|
|
'Persist Eng Review result',
|
|
],
|
|
mustPrecedeStop: ['## Step 0: Detect platform and base branch'],
|
|
mustMoveToSection: [
|
|
'Plan File Discovery',
|
|
'MULTI-SPECIALIST CONFIRMED',
|
|
'Cross-model synthesis',
|
|
'codex review --base',
|
|
],
|
|
gateAfterStop: undefined, // operational multi-STOP skill, like ship
|
|
},
|
|
behavioral: 'plan',
|
|
maxSkeletonBytes: 57_660, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 57_053
|
|
minUnionBytes: 89_000, // Phase 4 wave 1; measured union 93,357
|
|
mustContain: ['confidence', 'P1', 'P2', 'Review Army', 'adversarial'],
|
|
},
|
|
codex: {
|
|
skill: 'codex',
|
|
expectedSections: ['review-mode.md', 'challenge-mode.md', 'consult-mode.md'],
|
|
requiredReads: ['review-mode.md', 'consult-mode.md'],
|
|
scenario:
|
|
"Run the /codex skill twice: first Review mode against this branch's diff (produce the GATE verdict), then Consult mode with the follow-up 'is the strongest finding worth fixing before ship?'. Follow the Step 1 dispatch and read each selected mode's section before executing it; if the codex CLI is unavailable, still walk the mode instructions and report what you would run.",
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## Step 1: Detect mode',
|
|
'## Filesystem Boundary',
|
|
'Synthesis recommendation (REQUIRED)',
|
|
'Recommendation: <action> because',
|
|
'UNDER_CODEX',
|
|
],
|
|
mustPrecedeStop: ['## Step 1: Detect mode', '## Filesystem Boundary'],
|
|
mustMoveToSection: [
|
|
'The gate FAILS CLOSED',
|
|
'Think like an attacker and a chaos engineer',
|
|
'codex exec resume',
|
|
],
|
|
gateAfterStop: 'EXIT PLAN MODE GATE',
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 57_800, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 57_198
|
|
minUnionBytes: 83_400, // Phase 4 wave 1; measured union 84,304
|
|
mustContain: ['GATE: PASS', 'CROSS-MODEL ANALYSIS', 'codex exec resume', 'sandbox_mode="read-only"', 'mktemp'],
|
|
maxSizeRatio: 1.06, // measured 1.040 vs the v1.64.1.0 parity baseline
|
|
},
|
|
'land-and-deploy': {
|
|
skill: 'land-and-deploy',
|
|
expectedSections: ['first-run-validation.md', 'readiness-gate.md', 'merge-and-deploy.md'],
|
|
requiredReads: ['readiness-gate.md', 'merge-and-deploy.md'],
|
|
scenario:
|
|
'This project has a confirmed prior /land-and-deploy run (treat the Step 1.5 check as CONFIRMED). A PR exists for this branch and CI is green. Simulate — do not run gh or actually merge: run the pre-merge readiness gate and produce the readiness report, then walk the merge and deploy-strategy steps, stating which merge path and deploy strategy you would take. Do NOT use AskUserQuestion.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'land-deploy-confirmed',
|
|
'## Step 3.4: VERSION drift detection',
|
|
'## Step 6: Wait for deploy',
|
|
],
|
|
mustPrecedeStop: ['land-deploy-confirmed'],
|
|
mustMoveToSection: [
|
|
'PRE-MERGE READINESS REPORT',
|
|
'gh pr merge --squash --auto --delete-branch',
|
|
'DEPLOY INFRASTRUCTURE VALIDATION',
|
|
],
|
|
gateAfterStop: undefined, // operational skill
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 60_980, // ponytail-import wave + v1.72 Aside third-party-actions contract (merged); measured 60_377
|
|
minUnionBytes: 91_000, // Phase 4 wave 1; estimated union ~94.9KB
|
|
mustContain: ['readiness', 'merge', 'canary', 'revert', 'staging'],
|
|
},
|
|
// ── Token-reduction Phase 4 wave 2 (v1.69.x branch) ──────────────────────
|
|
autoplan: {
|
|
skill: 'autoplan',
|
|
expectedSections: ['ceo-phase.md', 'design-phase.md', 'eng-phase.md', 'dx-phase.md', 'tasks-aggregator.md'],
|
|
requiredReads: ['ceo-phase.md', 'eng-phase.md', 'tasks-aggregator.md'],
|
|
scenario:
|
|
'Run the /autoplan pipeline against the plan in PLAN.md. Codex and subagent tools are unavailable — note both voices unavailable (single-reviewer mode) and keep going. The plan has no UI scope and no developer-facing scope, so Phase 2 and Phase 2.5 are skipped (do not read their sections). Execute Phase 1 (CEO) and Phase 3 (Eng) at full depth, run the Phase 4 aggregator step, and produce the Final Approval Gate summary as the report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## The 6 Decision Principles',
|
|
'## Sequential Execution — MANDATORY',
|
|
'## Decision Classification',
|
|
'## Filesystem Boundary — Codex Prompts',
|
|
'## Phase 0.5: Codex auth + version preflight',
|
|
'## Pre-Gate Verification',
|
|
'## Phase 2: Design Review (conditional — skip if no UI scope)',
|
|
'## Phase 2.5: DX Review (conditional — skip if no developer-facing scope)',
|
|
'- Scope gate (the plan under review is already the target)',
|
|
],
|
|
mustPrecedeStop: ['## The 6 Decision Principles', '## Sequential Execution — MANDATORY', '## Decision Classification'],
|
|
mustMoveToSection: [
|
|
'CEO DUAL VOICES — CONSENSUS TABLE:',
|
|
'CODEX SAYS (design — UX challenge)',
|
|
'ENG DUAL VOICES — CONSENSUS TABLE:',
|
|
'DX DUAL VOICES — CONSENSUS TABLE:',
|
|
'## Implementation Tasks aggregator',
|
|
],
|
|
gateAfterStop: 'AskUserQuestion options:',
|
|
},
|
|
behavioral: 'external',
|
|
externalTest: 'test/skill-e2e-autoplan-chain.test.ts', // phase-complete markers live ONLY in sections — its assertions ARE section-read proof
|
|
maxSkeletonBytes: 62_610, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 62_006
|
|
minUnionBytes: 85_000, // measured union 86,926
|
|
mustContain: ['6 Decision Principles', 'TASTE DECISION', 'USER CHALLENGE', 'consensus', 'Restore Point'],
|
|
},
|
|
spec: {
|
|
skill: 'spec',
|
|
expectedSections: ['gate-and-file.md'],
|
|
requiredReads: ['gate-and-file.md'],
|
|
scenario:
|
|
"The user already completed Phases 1-4 of /spec for the request 'add a --json output flag to the CLI status command'. Treat the five Phase 1 answers, the scope lock, and the technical interrogation as settled, and the Phase 4 draft as CONFIRMED by the user. Continue from that point in file-only mode (--no-execute is set): run the Phase 4.5 sequence and Phase 5, simulating every external command (codex, gh, the redaction bin) by stating what you would run and the expected outcome instead of executing it. Do NOT use AskUserQuestion.",
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'HARD GATE',
|
|
'### Phase 1: Understand the "Why"',
|
|
'### Phase 3: Technical Interrogation',
|
|
'### Phase 4: Draft Review',
|
|
'gstack-issue-guard',
|
|
'## Issue Structure Templates',
|
|
],
|
|
mustPrecedeStop: ['## Flag Reference', '### Phase 1: Understand the "Why"'],
|
|
mustMoveToSection: [
|
|
'<<<USER_SPEC>>>',
|
|
'SEMANTIC_REVIEW: clean',
|
|
'gh issue create --title',
|
|
'PIN_SHA=$(git rev-parse HEAD)',
|
|
],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 55_660, // ponytail-import wave + v1.72 Aside third-party-actions contract (merged); measured 55_053
|
|
minUnionBytes: 64_500, // measured union 67,430
|
|
mustContain: ['HARD GATE', 'dedupe', 'quality gate', 'acceptance criteria', 'archive'],
|
|
},
|
|
'setup-gbrain': {
|
|
skill: 'setup-gbrain',
|
|
expectedSections: ['engine-remediation.md', 'brain-init.md', 'transcript-gate.md', 'claude-md-persist.md'],
|
|
requiredReads: ['brain-init.md', 'claude-md-persist.md'],
|
|
scenario:
|
|
"Walk /setup-gbrain in SIMULATION — do not execute any bash, install anything, or register MCP; for each step state the exact commands you WOULD run. Treat Step 1 detect as: gbrain_on_path=false, gbrain_local_status=missing-config, no shortcut flags. Treat Path 3 (PGLite local) as already picked at Step 2 — do not use AskUserQuestion. Walk Steps 3, 4 (Path 3 init), 5, 5a, and 8: read each step's pointed section before doing it, and write out the exact CLAUDE.md block Step 8 would persist. Skip Steps 6, 7, 7.5, 9, 9.5, and 10. End with a one-paragraph setup summary.",
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## Step 2: Pick a path (AskUserQuestion)',
|
|
'## Step 1: Detect current state',
|
|
'gbrain_mcp_mode=remote-http',
|
|
'claude mcp add --scope user --transport http gbrain',
|
|
'SKIP entirely on Path 4 (Remote MCP)',
|
|
'<YOUR_TOKEN>',
|
|
],
|
|
mustPrecedeStop: ['## Step 1: Detect current state'],
|
|
mustMoveToSection: [
|
|
'### Path 1 (Supabase, existing URL)',
|
|
'read_secret_to_env GBRAIN_MCP_TOKEN',
|
|
'Mode: remote-http',
|
|
'gstack-memory-ingest.ts --probe',
|
|
],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 58_950, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 58_344
|
|
minUnionBytes: 78_300, // measured union 79,139
|
|
mustContain: ['PGLite', 'Supabase', 'claude mcp add', 'read_secret_to_env', 'pooler'],
|
|
maxSizeRatio: 1.07, // measured 1.051 vs the branch monolith: index + stubs + 4 STOP pointers
|
|
},
|
|
// ── Token-reduction Phase 4 wave 3 (v1.69.x branch) ──────────────────────
|
|
qa: {
|
|
skill: 'qa',
|
|
expectedSections: ['test-bootstrap.md', 'qa-patterns.md'],
|
|
requiredReads: ['qa-patterns.md'],
|
|
scenario:
|
|
'Walk /qa in SIMULATION — do not launch a browser, run any $B command, or execute bash; treat the working tree as clean, the tier as Quick, and the target app as http://localhost:3000 with a small feature-branch diff touching one page. Skip the test-framework bootstrap (assume CLAUDE.md documents the test command). Read each pointed section before doing its step, then produce the QA plan as the report: the mode you selected and why, the Phase 1-6 steps you would run, and a worked health-score computation from the rubric. Do NOT use AskUserQuestion.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## Setup',
|
|
'## SETUP (run this check BEFORE any browse command)',
|
|
'## Phases 1-6: QA Baseline',
|
|
'## Phase 7: Triage',
|
|
'## Phase 8: Fix Loop',
|
|
'8e.5. Regression Test',
|
|
'WTF-LIKELIHOOD',
|
|
'## Additional Rules (qa-specific)',
|
|
'## Output Structure',
|
|
],
|
|
mustPrecedeStop: ['## Setup'],
|
|
mustMoveToSection: [
|
|
'## Test Framework Bootstrap',
|
|
'BOOTSTRAP_DECLINED',
|
|
'## Health Score Rubric',
|
|
'### Diff-aware (automatic when on a feature branch with no URL)',
|
|
'Never refuse to use the browser',
|
|
],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 50_800, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 50_194
|
|
minUnionBytes: 69_500, // measured union 70,385
|
|
mustContain: ['bug', 'browse', 'fix', 'Health Score Rubric', 'regression'],
|
|
},
|
|
browse: {
|
|
skill: 'browse',
|
|
expectedSections: ['command-list.md'],
|
|
requiredReads: ['command-list.md'],
|
|
scenario:
|
|
'QA a static page: before driving it, plan the full audit — enumerate which browse commands and snapshot flags you would use, including extraction/tab/dialog commands beyond the Most-Used table, reading the full command reference first. Do not launch the browser or run any $B command; produce the command plan as the report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: ['## SETUP', '## Core QA Patterns', '## CSS Inspector', '## Most-Used Commands'],
|
|
mustPrecedeStop: ['## SETUP'],
|
|
mustMoveToSection: ['## Full Command List', '## Snapshot Flags', '### Navigation'],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 27_500, // Phase 4 wave 3; measured 26,875
|
|
minUnionBytes: 39_500, // measured union 41,115
|
|
// 'BEGIN/END UNTRUSTED EXTERNAL' pins the untrusted-content warning; the full
|
|
// envelope phrase wraps across lines in the rendered blockquote, so the
|
|
// contiguous-substring check needs the single-line prefix form.
|
|
mustContain: ['BEGIN/END UNTRUSTED EXTERNAL', 'snapshot -i', '@e refs', 'deviceScaleFactor', 'handoff'],
|
|
},
|
|
retro: {
|
|
skill: 'retro',
|
|
expectedSections: ['report-format.md'],
|
|
requiredReads: ['report-format.md'],
|
|
scenario:
|
|
'Run the repo-scoped weekly retrospective for the last 7 days on this repo. There is no origin remote — proceed with the local branch per the guard disclosure rules. The gstack-retro-metrics script is not installed, so follow the degraded path (compute the metrics manually with git). Skip any AskUserQuestion calls — this is non-interactive. Produce the full narrative retrospective report.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: ['gstack-retro-metrics', '### Step 2: Compute Metrics', '### Step 13: Save Retro History'],
|
|
mustPrecedeStop: ['### Step 2: Compute Metrics'],
|
|
mustMoveToSection: ['## Engineering Retro: [date range]', '### Team Breakdown', 'Plan Completion This Period'],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 71_620, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 71_020 (retro also gained the Step 11.5 shortcut-debt harvest)
|
|
minUnionBytes: 66_000, // measured union 73,496
|
|
mustContain: ['retrospective', '45-minute gap', 'Ship of the week', 'Praise'],
|
|
},
|
|
|
|
// ── Token-reduction Phase 4 wave 4 (v1.69.x branch): design doctrine carve ──
|
|
// (D3A: read-on-demand doctrine, requiredReads-guarded + loading eval)
|
|
'design-html': {
|
|
skill: 'design-html',
|
|
expectedSections: ['doctrine.md', 'pretext-patterns.md'],
|
|
requiredReads: ['doctrine.md', 'pretext-patterns.md'],
|
|
scenario:
|
|
'Walk /design-html in SIMULATION — do not run bash, start servers, launch a browser, or take screenshots. Treat Step 0 as already resolved: no CEO plan, no approved mockup, no variants, no DESIGN.md, no prior finalized.html — freeform mode (Case C option D), screen name "pricing", the user wants a pricing page for a developer-tools SaaS (dark, dense, three tiers, monospace-leaning). Do NOT use AskUserQuestion — proceed with the stated assumptions. Read each pointed section before doing its step, then execute Steps 1-3: produce the implementation spec, state the chosen Pretext tier and why, and generate the complete Pretext-native HTML — include the HTML in your report instead of writing files. Stop there: skip Step 3.5, Step 4, and Step 5.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## Step 0: Input Detection',
|
|
'## Step 2: Smart Pretext API Routing',
|
|
'### HTML Generation',
|
|
'AI slop blacklist',
|
|
'## Step 4: Preview + Refinement Loop',
|
|
'## Important Rules',
|
|
],
|
|
mustPrecedeStop: ['## DESIGN SETUP'],
|
|
mustMoveToSection: [
|
|
'### The Three Laws of Usability',
|
|
'### The Goodwill Reservoir',
|
|
'### Pretext Wiring Patterns',
|
|
'### Pretext API Reference',
|
|
],
|
|
gateAfterStop: undefined, // operational skill, no plan-mode gate
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 51_140, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 50_536
|
|
minUnionBytes: 57_500, // Phase 4 wave 4; measured union 58,682
|
|
mustContain: ["Don't make me think", "Users scan, they don't read", 'The Goodwill Reservoir', 'PRETEXT API CHEATSHEET', 'Pattern 3: Text around obstacles'],
|
|
},
|
|
'design-shotgun': {
|
|
skill: 'design-shotgun',
|
|
expectedSections: ['doctrine.md'],
|
|
requiredReads: ['doctrine.md'],
|
|
scenario:
|
|
'Walk /design-shotgun in SIMULATION — do not run bash, launch a browser, call the design binary, or spawn agents. Treat Step 0 as NO_PREVIOUS_SESSIONS and Step 1 context as fully gathered: a landing page for an open-source CLI tool, audience = developers evaluating it from a GitHub README link, no DESIGN.md, no taste profile or prior approved.json (Step 2 finds nothing). Do NOT use AskUserQuestion — proceed with the stated assumptions. Read each pointed section before doing its step, then run Step 3a at full depth: write three distinct variant concepts with their full variant-specific generation briefs, apply the anti-convergence check, and produce the concept list plus briefs as the report. Stop before Step 3b.',
|
|
staticInvariants: {
|
|
mustStayInSkeleton: [
|
|
'## Step 0: Session Detection',
|
|
'## Step 2: Taste Memory',
|
|
'Anti-convergence directive',
|
|
'### Step 3b: Concept Confirmation',
|
|
'## Important Rules',
|
|
],
|
|
mustPrecedeStop: ['## DESIGN SETUP'],
|
|
mustMoveToSection: [
|
|
'### The Three Laws of Usability',
|
|
'### The Goodwill Reservoir',
|
|
"Users scan, they don't read",
|
|
],
|
|
gateAfterStop: undefined,
|
|
},
|
|
behavioral: 'prompt',
|
|
maxSkeletonBytes: 51_850, // ponytail-import wave: reuse ladder + bounded closer + shortcut trail (AUQ repetition cut netted -236B, gated); measured 51_248
|
|
minUnionBytes: 53_200, // Phase 4 wave 4; measured union 54,290
|
|
mustContain: ["Don't make me think", "Users scan, they don't read", 'trunk test', '44px minimum'],
|
|
},
|
|
};
|
|
|
|
/** Sorted carved-skill names. Consumers derive their lists from this — no parallel lists. */
|
|
export const CARVED_SKILLS: readonly string[] = Object.freeze(
|
|
Object.keys(CARVE_GUARDS).sort(),
|
|
);
|