diff --git a/AGENTS.md b/AGENTS.md index ac84585d1..b49cc15a4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,6 +64,7 @@ Invoke them by name (e.g., `/office-hours`). | `/learn` | Manage what gstack learned across sessions. | | `/retro` | Weekly retro with per-person breakdowns and shipping streaks. | | `/health` | Code quality dashboard (type checker, linter, tests, dead code). | +| `/captain` | Run a crew from one controller: READY contract, merge trains, digest, approvals shapes, daily flaky pass. Also `/crew`. Templates in `captain/templates/`, team guide in `docs/captain.md`. | | `/benchmark` | Performance regression detection (page load, Core Web Vitals). | | `/benchmark-models` | Cross-model benchmark for skills (Claude, GPT, Gemini side-by-side). | | `/eval-plan` | Preregister a paid eval (bars, arms, decoys, stop rules), dry-run it for $0, pilot three priced items, then approve the spend. | diff --git a/CHANGELOG.md b/CHANGELOG.md index bb401fab0..f67c5f462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## [1.91.254.0] - 2026-10-26 **Pregate ergonomics for a repository that is not gstack (Lane D, GSTA-112; plan harness-codify E4–E6; Captain issues 6, 11, 12).** Three Captains lost their first `/ship` pass to `PREGATE_NO_LANE` in a repo that had no `.gstack/pregate.json` yet (FOUN #292, harness-evals #81/#82); the non-downgradable `secrets` check refused 1,800 dummy per-trial tokens, 11-digit Actions run ids read as phone numbers and a public Firebase key every bundle rebuild re-adds (harness-evals #81/#83, GSTA-102, GSTA-106); a lane whose runner could not start read as the diff's failure and was waived by test name (truther #617); and pregate's logs under `os.tmpdir()` were shared between parallel runs and wiped by a Capy wake (gbrain 16). @@ -23,6 +23,79 @@ - `test/pregate-environment.test.ts`: the classifier's vocabulary; a missing runner binary, a network error with no summary, a quota refusal from the remote gate (obligation uncleared) and a missing guard binary are `PREGATE_ENVIRONMENT` with their kinds and `verify` says so; a counted test failure beside an `ECONNREFUSED` line and a guard that exits 2 stay `cause: "diff"`. Red before: `PREGATE_LANE_FAILED` with no cause. - `test/pregate-scratch.test.ts`: two `--run` ids get two directories under the fixture's state root, logs and the record name them, an unnamed run is unique, the secrets copies are gone after the scan, and prune keeps fresh runs and the current one. Red before: logs under `/tmp/gstack-pregate-lanes-*` and no `scratch` field. +## [1.91.253.0] - 2026-10-26 + +**`/captain` (also `/crew`): the crew operating model that keeps many agents merging into one base branch without turning it red, as a gstack skill with templates and a team guide.** Teams running a controller agent over worker threads had the model only in one crew's private notes. It now ships generic: one controller merges and lanes never merge; a READY block (full head SHA, base, CI counts, pregate, gate evidence, `SHIP_RECEIPT` at the pin, screen choice with justification, receipt path, logged flaky cases) is the only merge trigger, and a green PR page or a cheap test tier never is; merge trains (build, verdict, per-slot stamp on call, verify, merge with the expected head, verify again, prune), the red-train rules (in-run flaky rerun once, bisect on the red cases, exactly one unchanged rebuild, one infra re-dispatch), the tree rule, the backstop and the freeze, and the post-merge babysit; the digest shape (Needs you / New / In progress with ages); the three approval shapes (the per-thread record, the plan ask with before → after and a "do it" reply, the merge ask with captioned before/after images); and the daily flaky-fix pass (ledger format, the gate runs' flake records and the free suites' retries as sources, red-before-green fix PRs, one named infra rerun allowance, never thresholds, trials or kinds). Where crews that run this model disagree (squash or merge, lane or controller stamps, gate-ahead, the severe race, a gate run id in the READY) the skill ships both as options for the crew rules file. Every repo-specific name is a parameter (`REPO`, `BASE`, `REQUIRED_CHECKS`, `FULL_GATE_CHECK`, `MERGE_METHOD`, `STAMP_FILES`, `KNOWN_INFRA_FLAKES`). + +### Added +- **`captain/SKILL.md.tmpl`**: the skill, tier 2, routed from the root router on "captain", "crew", a merge train, a slot call, a READY block or the crew digest; its own triggers add "validate this ready" and "flaky pass". +- **`captain/templates/`**: `CREW.md` (the 23 lane rules as one-line pointers into gstack's docs and skills, plus the crew's parameters and its standing-approval table), `AGENTS.md` (the controller's standing rules with the owner's dated words), `NOTES.md` (the append-only timestamped log), `DIGEST.md`, `flaky-ledger.md`, `report.md` (Outcome, PR, Needs, Cost, Lesson, Approvals), `READY.md` (the block, the optional lines, the refusal list), `slot-call.md`, `plan-ask.md`, `merge-ask.md` and `automation-flaky-pass.md` (the schedule, what it reads, what it starts). +- **`docs/captain.md`**: how a team sets up a Captain crew on Capy with gstack: the roles, the drive layout, the crew rules file, the READY contract, the lane's /ship sequence before READY, trains with the slot-2 recipe, approvals, the digest, the flaky pass, the owner's device, the lessons loop, and the setup steps; linked from the README docs table, `docs/skills.md`, `docs/capy-install.md` and the skill. +- **`test/captain-skill.test.ts`**: pins the contract the skill teaches, the template set, the generic wording (no crew codes, names or repository literals) and the registration points. + +### Changed +- **`gstack-owner-brief render --captain`** closes "What we need from you" with the **do it** reply (every recommendation at full scope, the plan's follow-ons included, carried through with no further ask) and invites `rec` or `do it`; `capy/skill/gstack/captain.md` documents it as step 6 and points at the controller's side. +- `README.md` (power tools), `AGENTS.md`, `docs/skills.md`, `docs/PROJECT_STRUCTURE.md`, the root router and the doctor component table register the skill; `test/fixtures/context-budget.json` gains the `captain` ceiling and the router's, grown by its one new rule; `test/catalog-budget.test.ts`, `CLAUDE.md`, `CONTRIBUTING.md` and `docs/CONTRIBUTOR_REFERENCE.md` carry the catalog ceiling the new skill ratchets to; `gstack-autoplan answer` accepts `do it` as a `rec` alias. + +## [1.91.252.0] - 2026-10-26 + +**`/retro` can now say whether the factory is getting better, and a new team has one page that takes it from zero to its first merged train on gstack + Capy.** `bin/gstack-factory-scorecard` reads one window (default 7 days) from GitHub through `gh` and prints a Markdown table plus a CSV: merged PRs (crew vs outside contributors), lead time (PR created → merged, and first READY comment → merged), gate runs green / red / cancelled with their known cost, cost per merge, the red-train rate, flaky events from the same two sources the daily flaky pass reads, issues opened vs closed, and releases cut. Each line carries its counting rule and what one of the best software factories would show on it; a line whose input cannot be read says `unavailable ()`, never 0. `docs/recommended-harness.md` is the adoption guide: install, the Captain and its Drive, the first train, the daily flaky pass, the weekly release, the scorecard with gstack's own numbers against the bar, what is Capy-specific, the options where two crews differ, and the known Capy limits as of 2026-10-26. + +### Added +- **`bin/gstack-factory-scorecard`** (`lib/factory-scorecard.ts`): `--repo`, `--base`, `--since-days`, `--crew login,login` (else author association OWNER/MEMBER/COLLABORATOR), `--gate-workflow`, `--gate-event`, `--free-workflow`, `--train-prefix`, `--ready-marker`, `--pass-marker` and `--pass-cap` (review passes per PR: median, p90 and how many PRs sat at the cap, from the ship receipt's `"passes"` in the PR body or a `passes=N` / `REVIEW_PASSES: N` comment), `--max-artifact-runs`, `--out-dir`, `--csv`, `--json`, `--fixtures` (recorded gh responses, no network) and `--now`. `--repo` defaults to the origin remote's owner/name and is required without one; every run appends its rows to `trend.csv` in `--out-dir`. Gate cost comes from the run's `report-verdict-a*` artifact (`collector-outcomes.json` `.verdict.costUsd`), else the `**$N** rule/judge cost` or `cost=$N` line of the PR's verdict comment; flaky events from `flake-records-a*` (paid) and `flake-ledger-*` (free) artifacts. A READY comment posted after the merge is ignored, a PR's verdict-comment cost backs one gate run, and a run whose artifacts cannot be read is counted and named rather than scored 0. Read-only; exits 0 with the table even when an input is unavailable, 2 on bad usage. +- **`/retro` Step 7.5 (Factory scorecard, optional)**: the report format gains a **Factory scorecard** slot; the step runs the bin for the retro window when `gh` is authenticated and pastes the table, third column included, into the report. +- **`docs/recommended-harness.md`**, linked from the README docs table; `docs/standalone-binaries.md` lists the new CLI. + +### Tests +- `test/factory-scorecard.test.ts`: the recorded window (`test/fixtures/factory-scorecard/recorded.json`) yields the expected merges, lead times, gate kinds and outcomes, artifact and comment cost sources, flake counts, free retries, issues and releases; a crew login list overrides the association rule; runs older than the window, non-dispatch events and draft releases are left out; the artifact cap leaves later runs without cost or flake data; a missing input marks only its lines unavailable; the markdown and CSV carry every row; gate classification, READY-marker matching, verdict-cost and flake-record parsing and nearest-rank percentiles; `--gate-event any` keeps non-dispatch runs; an empty window prints n/a instead of NaN; a failed merged-PR read leaves the gate rows standing; the bin end to end with `--fixtures`, `--crew`, `--out-dir`, `--csv`, `--ready-marker`, bad usage (including `--now`) and `--help`; the retro template pins the fence. +- `test/host-conformance.test.ts` C3 ("--status names a symlinked router and a broken section link per host") deletes a named section (`scope.md`) instead of the first `.md` that `readdirSync` returns: two gstack-qa sections are referenced only in table form, which `setup --status` does not count as links, so on an ext4 directory order that listed one of them first the case failed deterministically on remote-gate VMs while passing on Actions (#3479). + +## [1.91.251.0] - 2026-10-26 + +**A free, deterministic design lint ships with gstack: `bin/gstack-design-lint` checks a page's HTML, CSS and components for the tells that make it read as machine-made, in under a second, and with `--render` measures what only a browser can.** Until now gstack's only mechanical design check was the opt-in impeccable engine most users never install, plus `gstack-design-craft`'s seventeen copy and ship-floor regexes; everything else in the Slop Gate was prose the model judged itself. The lint ports the roughly fifty-five machine-checkable gates of [Nutlope/hallmark](https://github.com/Nutlope/hallmark)'s `sloplint` (MIT; see NOTICE.md) into TypeScript under `lib/design-lint/`, rewritten in gstack's voice and mapped onto gstack's severity words. This release is the tool alone (Phase 1 of the hallmark absorption plan, approved by Garry on 2026-10-26); /design-html and /design-review start calling it in Phase 2, so no skill prose changes here. + +### Added +- **`bin/gstack-design-lint [--render] [--url] [--scope page|component] [--job ] [--json] [--rules]`**: reads `.html`, `.css`, `.jsx`, `.tsx`, `.vue`, `.svelte` and `.astro` (Tailwind class strings included, `cn()`/`clsx()`/`cva()` calls too), links each page to the stylesheets it reaches through `` and `@import`, resolves CSS variables, converts colours to OKLCH and computes contrast, and prints one line per finding: `LINT: : | fix: `, then `LINT_SUMMARY: blocks=N ask=N waived=N polish=N render=`. Exit 2 on blocks, 1 on an unanswered ask, 0 otherwise. `docs/design-lint.md` is the contract and lists every rule. +- **Three tiers in gstack's words, no fourth scale.** `blocks` (hallmark's Floor: contrast, focus rings, reduced motion, a card in a card, a purple-blue gradient, content hidden until JavaScript runs; never waivable), `ask` (hallmark's Reflex: three equal cards, Inter as the display, the centred-stack hero; waivable on the record) and `polish` (hallmark's Finish: straight quotes, a lonely last grid item; never blocks). Blocking and waived counts are never summed, so `blocks=0` is always a true sentence about the Floor. Three house rules hallmark holds at Floor stay at ask here: the eyebrow above a heading, the 80-word screen and the dash. +- **Waivers on the record.** `` (or the `/* */` and `//` comment forms; `impeccable-disable : ` is an alias) answers an ask or polish finding when the reason is about this page: 24 characters or more, not boilerplate, not reused on another waiver, sharing a word with the page's own text. A waiver of a blocking rule is refused and the rule still fires; more than three waivers on one page is reported as a house style that belongs in DESIGN.md. +- **The render tier** (`--render`, or `--url` for a dev server) runs on the same engine `gstack-render` picks, Aside first and gstack's own headless browser otherwise, with nothing to install: the hero fits at 1280x800 (the headline's bottom and the first action; the lede and the visual are not measured), about 80 words per 900px window, contrast against the painted pixels, focus rings found by focusing every control, headings crowded against the section above, text painted under another element, horizontal scroll between 320 and 1920, wrapping button labels, a hero offering more than two actions, section gaps under 120px or all alike and more than nine sections, thin sections, dead bands, drawn illustrations, empty picture slots, counting marks and photographs covering more than a third of the page. Without a browser the summary says `render=skipped: ` and the static tier still runs. +- `lib/aside-render.ts`: an eval step takes an optional viewport (`width`, `height`, `deviceScaleFactor`, `mobile`), set before the eval and cleared after it the way the screenshot step already does, and a spec's `file` may be an http(s) URL, opened as it is with no loopback server. Both engines take the size; `deviceScaleFactor` and `mobile` on an eval step reach Aside only (the browse daemon's `viewport` takes a size alone). Nothing else in the file changes. +- **The copy tier**: `gstack-design-craft`'s content-realism and ship-floor tells (placeholder names, lorem, buzzwords, round numbers, `[Needs proof]`, dead links, images without alt, the missing title, description, skip link and `aria-current`) report under the same contract and ids, so one command prints one list. `bin/gstack-design-craft` itself is unchanged until Phase 2 swaps the call. +- Fixtures under `test/fixtures/design-lint/` (hallmark's `slopped.html`, eyebrow and Tailwind pass/fail pairs and the waiver page, MIT-attributed, plus a clean page every rule family must leave alone); `licenses/MIT-hallmark.txt`; a NOTICE.md entry. + +### Tests +- `test/design-lint.test.ts`: the parsers (nested CSS, tokens, var() fallbacks, colour spaces, JSX pseudo-HTML), the rule table against `docs/design-lint.md`, the output lines and exit codes, waiver acceptance and every refusal reason, the waiver fixture. One test per rule family (`test/design-lint-.test.ts`) holds a negative control and a planted positive for every rule id. `test/design-lint-render.test.ts` drives the browse daemon when it is built and skips with a named reason otherwise. `test/design-lint-recorded.test.ts` lints the repository's recorded design slop page (the review eval's ground truth) and pins which rule answers each annotated issue, the same gate set hallmark's sloplint reports on the same files. + +### Gate integrity +- No threshold, budget, timeout, trial count or assertion was weakened. No template, catalog or eval changed. Gate edits in the diff: `test/fixtures/module-size-ratchet.json` registers the 27 new `lib/design-lint` modules under the existing 800-line cap, and `test/helpers/free-fixtures-data.ts` maps `test/fixtures/design-lint/**` to the design-lint test files; `lib/aside-render.ts` gains the viewport on eval steps and http(s) `file`, described above. + +## [1.91.250.0] - 2026-10-26 + +**Three free-tier fixtures stop racing themselves (GSTA-107 daily flaky pass).** Two tests polled for a result file's existence while its writer created it with a plain `writeFileSync`, so a poll between create and write read an empty file; a third copied a shared template repository with `fs.cpSync` and threw once inside the directory walk. + +### Fixed +- **`browse/test/dotenv-isolation.test.ts`** (Free Tests 39902683183 and 40322888041, shard 2, "JSON Parse error: Unexpected EOF" at the `agent-env.json` read): the probe writes its result to a temp file and renames it into place, and `waitForFile` waits for content, not only for the file. A new test feeds the old race (an empty file filled 150 ms later) and runs the probe source itself. +- **`test/claude-code-runner.test.ts`** (Free Tests 39694715116, shard 13, `running(pid)` false at the timeout case): the descendant publishes `descendant.pid` by rename, and the test polls `publishedPid()`, a positive integer, instead of the file's existence, so an empty read can no longer become pid 0. +- **`test/cso-git-hardening.test.ts`** (Free Tests 40288142343, shard 17, `fs.cpSync` threw in `fixture()` with an empty message and passed on the serial retry): every fixture builds its own repository with Git instead of copying a shared template, with auto-maintenance off (`maintenance.auto=false`, `gc.auto=0`) so the detached `git maintenance run` a commit starts no longer touches `.git` while a test walks or removes it; the `beforeAll` still pays the cold macOS Git spawns once, on a throwaway repository. No timeout changed. + +## [1.91.249.0] - 2026-10-26 + +**Five paid-case flakes from the 2026-10-26 train gates, repaired at their causes (GSTA-107 daily flaky pass).** The "ship-docsync family" was three distinct slips, not one shared cause: a mistyped `--help` path the detector refused although the usage had already been read, an undeclared refusal of gstack's own state directory as an artifact location, and a fixture that did not install the shared preamble a generated skill requires. tpa-present's consent question paraphrased "defer" as "wait for now", and qa-functional-webhook-fix ran the probe's `--help` bare before its first capture. + +### Fixed +- **ship-docsync-store (gate 40323989742 slice 3):** a candidate `--help` typed at a wrong, non-existent path (exit 127) is ignored when the declared binary's `--help` ran anywhere in the transcript, before or after, since a help probe reads nothing the agent still has to recover (`test/helpers/docsync-observer.ts` `candidateNotFound`); snapshot and compare still need the declared retry after the slip, and a wrong path that exists, a failed declared run, or no declared run at all still fail. +- **ship-docsync-completion (gate 40290033102 slice 2):** the parent put its snapshot `--out`, saved section and report insert under `/state`, gstack's own state directory (GSTACK_HOME), which the authority refuses but the fixture interface never named. The interface now says a private artifact lives directly under the fixture home or in a new directory there, and names every refused root: the repository, the installed skills, the Claude config dir, `/state` and `/remote.git` (`test/helpers/docsync-interface.ts`). The authority is unchanged. +- **docsync-spawned (PR #3434 screen 40269992077 slice 13):** `fixtureDocs` installs `/sections/preamble.md` beside the required sections when the generated skill has one, so a spawned child whose SKILL.md names the shared preamble as a required asset no longer blocks on its absence (`test/helpers/docsync-fixture.ts`). A generated skill without one installs exactly the files it did before. +- **tpa-present (gate 40290033102 slice 14):** the defer-option detector accepts "wait for now" and "hold off (on this) for now" as the option's own opening or sentence (`test/helpers/third-party-actions.ts` `offersDefer`); a drive option that waits while the user signs in, a "do not wait for now", or the phrase outside a lettered option still does not count. +- **qa-functional-webhook-fix (gate 40290033102 slice 9):** the fixture interface states that the evidence helper's `--help` is the only one it grants and that a bare `bun run probe` with `--help` or any argument outside a capture is a bypass (`test/helpers/qa-functional-eval.ts`); the grammar and the bypass detector are unchanged. + +### Tests +- `test/docsync-lifecycle-interface.test.ts` replays the captured store run (`test/fixtures/docsync-help-not-found-public.json`) as a pass, with controls for no declared `--help`, a failed one, and a wrong-path compare that only an earlier declared run precedes. +- `test/docsync-authority.test.ts` pins the interface sentence that names each refused root and replays the captured state-dir calls (`test/fixtures/docsync-state-dir-artifacts-public.json`): four refused commands and one refused write, all accepted once relocated to a new directory under the home. +- `test/ship-document-release-dispatch.test.ts` builds a generated root with and without a document-release preamble and checks the fixture installs it in the first case only. +- `test/third-party-actions.test.ts` adds the 40290033102 tpa-present render to the Opus consent captures (29 consent questions, 5 paraphrased defers) with new positive and negative wordings. +- `test/qa-functional-prompt.test.ts` pins the helper-only `--help` sentence before the observation forms and keeps `bun run probe -- --help` outside the grammar. + ## [1.91.248.0] - 2026-10-26 **`$B` in direct mode no longer lets Chromium pick a proxy from the environment (#3440 item 8).** `BROWSE_PROXY_URL=direct` (and an unparseable `HTTPS_PROXY`) only stopped gstack from configuring a proxy. The daemon inherits the whole environment and the launch passed no proxy switch, so Chromium read `HTTPS_PROXY`, `HTTP_PROXY` or `ALL_PROXY` itself and every `goto` still went through that proxy while `$B` reported a direct connection. That made the BROWSER.md precedence list false and any certificate check on a proxied machine unreliable. Reproduced on Linux with Playwright 1.62.1: a logging CONNECT proxy in `HTTPS_PROXY` received `CONNECT :443` with `BROWSE_PROXY_URL=direct` set. diff --git a/CLAUDE.md b/CLAUDE.md index 095a8d7b9..3b874a2ab 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -146,7 +146,7 @@ a skill's own bash. **Size budgets:** generated SKILL.md files warn above 160KB (~40K tokens); `test/catalog-budget.test.ts` caps the always-loaded skill catalog at -`CATALOG_BUDGET_TOKEN_EQUIVALENTS` (1,197 today; each new skill ratchets it); and +`CATALOG_BUDGET_TOKEN_EQUIVALENTS` (1,251 today; each new skill ratchets it); and `test/context-budget-ratchet.test.ts` pins per-skill token ceilings against `test/fixtures/context-budget.json` (for legitimate growth or a landed reduction, re-run `bun test/helpers/capture-context-budget.ts` and commit the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3a9220eb..44aa2d71c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -427,7 +427,7 @@ eval files, and misses the strict classifier. No API keys needed. - **Generator tests** (`test/gen-skill-docs.test.ts`) — Tests the template system: verifies placeholders resolve correctly, output includes value hints for flags (e.g. `-d ` not just `-d`), enriched descriptions for key commands (e.g. `is` lists valid states, `press` lists key examples). - **Design detector, catalog, and DESIGN.md** (`test/gstack-design-detect.test.ts`, `test/design-detect-contract.test.ts`, `test/design-catalog.test.ts`, `test/design-checklist-sync.test.ts`, `test/design-md.test.ts`, `test/frontend-scope.test.ts`, `test/impeccable-fixtures.test.ts`) — Drive `bin/gstack-design-detect.ts` through the fake engine in `test/fixtures/fake-impeccable.ts` (probe order, the never-execute-a-repository-file rule, the `--changed` target allow-list, `design_detector: off`, analytics lines, output sanitizing), pin the catalog invariants and the generated `review/design-checklist.md`, round-trip the open DESIGN.md reader/writer, and check the real engine captures (`test/fixtures/impeccable-*.json`, engine 0.1.3) against the contract. `test/dom-dump-hygiene.test.ts` runs `lib/dom-dump.js` in a real Chromium page through the built browse binary; it self-skips without the binary and is opt-in outside CI (`GSTACK_DOM_DUMP_HYGIENE=1`). - **Tier-alignment invariant** (`test/e2e-tier-alignment.test.ts`) — For every self-gated `test/skill-e2e-*.test.ts` named in a touchfiles dep list, the file's `EVALS_TIER` self-gate must match its declared tier in `E2E_TIERS`. Kills the "inert demotion" class where a test is re-tiered in `touchfiles.ts` but the file still gates on the old tier and keeps running in the wrong lane. Unmapped or mixed-tier files are reported, never silently skipped. -- **Catalog budget** (`test/catalog-budget.test.ts`) — Caps the aggregate discovery surface: the sum of every skill's frontmatter `name` + `description` (what every host loads at discovery, every session) must stay under 1,171 token-equivalents, with a 260-byte per-skill cap. Counting goes through the shared census in `test/helpers/skill-census.ts` (physical files vs authored skills vs registry entries — three deliberately different counts). Adding a skill? The failure message carries the re-measure + ratchet protocol. +- **Catalog budget** (`test/catalog-budget.test.ts`) — Caps the aggregate discovery surface: the sum of every skill's frontmatter `name` + `description` (what every host loads at discovery, every session) must stay under 1,251 token-equivalents, with a 260-byte per-skill cap. Counting goes through the shared census in `test/helpers/skill-census.ts` (physical files vs authored skills vs registry entries — three deliberately different counts). Adding a skill? The failure message carries the re-measure + ratchet protocol. - **Context-budget ratchet** (`test/context-budget-ratchet.test.ts`) — CI ceilings on the two token ledgers the catalog budget doesn't cover: the always-on full-frontmatter aggregate and each skill's per-invocation eager tokens (SKILL.md + forced-read references), graded against `test/fixtures/context-budget.json` via `lib/context-bill.ts`. New skills fail until they have a ceiling; ceilings for removed skills must be pruned. Legitimate growth or a landed reduction: re-run `bun test/helpers/capture-context-budget.ts` and commit the refreshed fixture in the same commit, so the change is a visible decision in the diff. - **Dependency security regressions** (`test/dependency-security.test.ts`) — Run `bun test test/dependency-security.test.ts` to check the resolved `sharp` and `adm-zip` version floors, load Sharp, verify ordinary ZIP extraction, and reject extraction through destination-file and destination-directory symlinks. The symlink cases skip Windows. These checks complement the OSV scan; they do not change its existing exceptions. diff --git a/NOTICE.md b/NOTICE.md index 831e0162a..2c9acedc8 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -50,6 +50,24 @@ signature components are not carried over): ship-floor tells, turned into a free check. - `design-shotgun/SKILL.md.tmpl`: page archetypes as a variant axis. +## hallmark — Copyright (c) 2026 Hallmark contributors — MIT License + +https://github.com/Nutlope/hallmark (`skills/hallmark/scripts/sloplint.mjs`, +`sloplint-render.mjs`, `references/gates.md`, `scripts/fixtures/`, at 7ec8682). +License text: `licenses/MIT-hallmark.txt`. + +Derived, modified (every gate rewritten in TypeScript and in gstack's voice, +mapped onto gstack's severity words; hallmark's theme stamp, genres, posture +guards, photo index and judged gates are not carried over): + +- `lib/design-lint/` and `bin/gstack-design-lint`: the static tier's parsers + (CSS rules and tokens, HTML and component pseudo-HTML, Tailwind class + strings), the colour maths, the waiver record, and the rule families under + `lib/design-lint/rules/`; the render tier in `lib/design-lint/render*.ts`, + driving gstack's own browser instead of puppeteer. +- `test/fixtures/design-lint/{slopped.html,eyebrow-pass,eyebrow-fail,tailwind-pass,tailwind-fail,waiver}`: + the fixtures, with their waiver comments rewritten to the lint's form. + ## DESIGN.md specification — Copyright Google LLC — Apache License 2.0 https://github.com/google-labs-code/design.md diff --git a/README.md b/README.md index eea86d521..75f85a9d0 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ The same `/qa` and `/qa-only` commands test CLIs, APIs, jobs, workers and webhoo | `/setup-gbrain` | **GBrain Onboarding** — from zero to running gbrain in under 5 minutes. PGLite local, Supabase existing URL, or auto-provision a new Supabase project via Management API. MCP registration for Claude Code + per-repo trust triad (read-write/read-only/deny). [Full guide](USING_GBRAIN_WITH_GSTACK.md). | | `/sync-gbrain` | **Keep Brain Current** — re-index this repo's code into gbrain via `gbrain sources add` + `gbrain sync --strategy code`, refresh the `## GBrain Search Guidance` block in CLAUDE.md, and auto-remove guidance when the capability check fails. `--incremental` (default), `--full`, `--dry-run`. Idempotent; safe to re-run. | | `/gstack-upgrade` | **Self-Updater** — upgrade gstack to latest. Detects global vs vendored install, syncs both, shows what changed. | +| `/captain` | **Crew Controller** — run many coding agents from one controller: lanes send a READY block and never merge, the controller merges through trains (stamp on call, verify, merge with the expected head), keeps the digest, relays approvals in a fixed shape and runs a daily flaky-fix pass. Also answers to `/crew`. [Team guide](docs/captain.md). | | `/ios-qa` | **iOS Live-Device QA (v1.43.0.0+)** — drive a real iPhone or iPad over USB CoreDevice via an embedded `StateServer` in the app. Read Swift source, codegen typed `@Observable` accessors, run the agent loop. Optional `--tailnet` flag exposes the device to OpenClaw or any HTTP-capable agent on your Tailscale tailnet so remote agents can run iOS QA without ever touching the hardware. Capability-tier allowlist (observe/interact/mutate/restore), per-device session lock, audit log. | | `/ios-fix`, `/ios-design-review`, `/ios-clean`, `/ios-sync` | iOS bug-fix loop, designer's-eye HIG audit, debug-bridge cleanup, and accessor resync. See `docs/skills.md`. End-to-end walkthrough: [docs/howto-ios-testing-with-gstack.md](docs/howto-ios-testing-with-gstack.md). | @@ -234,6 +235,7 @@ On Windows without Developer Mode (MSYS2 / Git Bash), `setup` falls back to file | Doc | What it covers | |-----|---------------| | [Skill Deep Dives](docs/skills.md) | Philosophy, examples, and workflow for every skill (includes Greptile integration) | +| [The recommended harness](docs/recommended-harness.md) | gstack + Capy from zero to the first merged train: install, the Captain and its Drive, trains, the daily flaky pass, the weekly release, the factory scorecard, what is Capy-specific, known Capy limits | | [Why gstack](docs/why-gstack.md) | The story, the productivity numbers and their caveats, Karpathy's failure modes, parallel sprints | | [Install details](docs/install.md) | Setup timing, requirements in detail, team mode, the hooks setup registers | | [Other agents](docs/hosts.md) | OpenClaw and ClawHub, per-host notes, the Codex profile and model tiers, outside-review providers, the design binary's models | @@ -252,6 +254,7 @@ On Windows without Developer Mode (MSYS2 / Git Bash), `setup` falls back to file | [Contributing](CONTRIBUTING.md) | Dev setup, testing, contributor mode, and dev mode | | [Memorable recall bridge](docs/memorable-workflow-memory.md) | Opt-in third-party workflow memory through gstack: two consents, what gstack hands over and can attest, removal, troubleshooting | | [Troubleshooting](docs/troubleshooting.md) | Every `not run` / `unavailable` message, what it means, and the fix | +| [Running a Captain crew](docs/captain.md) | One controller, many lanes on Capy: the drive layout, CREW.md, the READY contract, merge trains, approvals, the digest and the daily flaky pass, with templates | | [Changelog](CHANGELOG.md) | What's new in every version | ## Privacy & Telemetry diff --git a/SKILL.md b/SKILL.md index 1e879554f..a03f92690 100644 --- a/SKILL.md +++ b/SKILL.md @@ -214,6 +214,7 @@ quality gates that produce better results than answering inline. - User asks to update docs after shipping → invoke `/document-release` - User asks to write docs from scratch, generate documentation, "document this feature/module" → invoke `/document-generate` - User asks for a weekly retro, what did we ship, "how'd we do" → invoke `/retro` +- User asks to run a crew of agents, coordinate lanes, build a merge train, call a slot, validate a READY block, write the crew digest, "set up a captain", "run the crew" → invoke `/captain` Generic “second opinion”, “outside review”, or “cross-model review” requests use `/codex` (namespaced: `/gstack-codex`). This selection follows the **claude harness**, independently of model configuration. Explicit provider requests take precedence: Codex means `/codex`; Claude Code means `/claude-code`. Never silently substitute another provider. If that provider is the current harness, report that no outside invocation ran and suggest the other wrapper only as a separate user choice. Wrapper availability: Claude Code installs only /codex; Codex installs only /claude-code; other harnesses install both. Repair stale installations with `setup --host claude`. There is no /claude compatibility alias. - User asks for safety mode, careful mode → invoke `/careful` or `/guard` - User asks to restrict edits to a directory → invoke `/freeze` or `/unfreeze` diff --git a/SKILL.md.tmpl b/SKILL.md.tmpl index f2885faf5..0c7baa07f 100644 --- a/SKILL.md.tmpl +++ b/SKILL.md.tmpl @@ -90,6 +90,7 @@ quality gates that produce better results than answering inline. - User asks to update docs after shipping → invoke `/document-release` - User asks to write docs from scratch, generate documentation, "document this feature/module" → invoke `/document-generate` - User asks for a weekly retro, what did we ship, "how'd we do" → invoke `/retro` +- User asks to run a crew of agents, coordinate lanes, build a merge train, call a slot, validate a READY block, write the crew digest, "set up a captain", "run the crew" → invoke `/captain` {{OUTSIDE_VOICE_ROUTING}} - User asks for safety mode, careful mode → invoke `/careful` or `/guard` - User asks to restrict edits to a directory → invoke `/freeze` or `/unfreeze` diff --git a/VERSION b/VERSION index e035a9e84..515e9323d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.91.248.0 +1.91.254.0 diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md index c881b7de6..2bbd84735 100644 --- a/agents-digest/gstack-AGENTS.md +++ b/agents-digest/gstack-AGENTS.md @@ -1,4 +1,4 @@ -# gstack digest v1.91.248.0 — regenerate/re-copy after upgrading gstack +# gstack digest v1.91.254.0 — regenerate/re-copy after upgrading gstack Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed for agent hosts without a full skill install. The full skills add workflows, diff --git a/autoplan/DRIVER.md b/autoplan/DRIVER.md index aaaca6b2c..ad88c3d4e 100644 --- a/autoplan/DRIVER.md +++ b/autoplan/DRIVER.md @@ -109,7 +109,7 @@ RESULT FORMAT (required by gstack-autoplan; the parent binds your file by this c A reply binds to the `gate_rev` you read (`--gate-rev`). Bare `yes`/`no` is unparsed, never guessed. -- `rec`: every item takes its recommendation, plan changes included (each prints APPLY:); `all` is an alias. +- `rec`: every item takes its recommendation, plan changes included (each prints APPLY:); `all` and `do it` are aliases. - `as-is`: keep every direction; no plan change. - `d3b uc1a`: one