Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/windows-free-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ jobs:
# red here because it's genuinely POSIX-bound, add it to the curation
# exclusions — don't resurrect a hand list in this file.
env:
GSTACK_FREE_JOBS: '2'
# Point os.tmpdir() at the runner temp so the shard logs land
# somewhere the artifact step below can glob.
TEMP: ${{ runner.temp }}
Expand Down
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
# Changelog

## [1.90.2.0] - 2026-09-24

**Spend less time waiting for tests.**
**Merge with clearer safeguards.**

The local test runner uses available CPUs and removes repeated setup without removing test scenarios. Independent question checks run concurrently rather than waiting for one another. `/land-and-deploy` ties your approval to the selected PR, head and destination branch, checks server state before a merge fallback, and keeps missing deployment evidence visible.

### The three numbers that matter

Source: matched Linux component benchmarks in [docs/TEST_PORTFOLIO.md](docs/TEST_PORTFOLIO.md), which names the test files, workload and coverage. The live comparison runs both periodic AUQ files with five independent captures. These are separate component measurements, not a complete paid-suite or CI speedup.

| Workload | Before | After | Δ |
|---|---:|---:|---:|
| Nine synthetic-terminal test files | 165.87s | 72.98s | −56% |
| Publication polling and watchdog tests | 56.57s | 9.63s | −83% |
| Two independent-question test files | 325.09s | 136.40s | −58% |

The synthetic-terminal checks save about 93 seconds of repeated waiting. Question checks retain every independent trial and their original grading rules; parallel execution is not permission to substitute one successful answer for several samples.

### What this means for developers

Use `bun run test` for complete free validation; the quick subset is still only a feedback lane. When landing a PR, a changed target requires fresh readiness and approval. A staging check after merge no longer implies production is held, and a healthy old page does not prove the new revision deployed. Run your checks, then use `/land-and-deploy` to review the evidence before merging.

### Itemized changes

#### Changed

- Local free-test workers follow available CPU affinity, with a minimum of one and the existing maximum of six. Explicit worker overrides and the separate CI matrix retain their behavior; Windows CI explicitly keeps its two-worker budget.
- Deployment reports distinguish deployment status, production health, staging verification and completed rollback. Requests to stage before production stop before merge with a handoff to the configured pipeline.

#### Fixed

- Browser-consent checks distinguish a promised new consent question from an immediate drive offer, while still rejecting conditional drive permission before Aside is ready.
- Review fixtures accept explicit no-change answers and coverage-reporting statements without authorizing source edits or index-flag changes.
- Merge fallback requires authoritative confirmation that neither an auto-merge request nor a queue entry exists. Confirmed merges are never replayed, and changed heads or destination branches invalidate earlier approval.
- Rollback distinguishes true merge commits, squash merges and rebase ranges. Failed or unverified deployment and canary checks remain visible rather than becoming success labels.

#### For contributors

- Repository release guidance defaults to autonomous patch bumps, including queue collisions. Merge approval remains separate.
- Synthetic terminals signal readiness; publication tests advance a scoped clock through the original polling sequence; watchdog scenarios share compilation but retain isolated executables and state.
- Free-only dependency exemptions are explicit, mapped dependencies take precedence, and unknown changes retain conservative paid selection. The portfolio document assigns separate responsibilities to structural tests, quality judges, native behaviors, simulations and platform integrations.
- Native question, shared-code review and design-detector fixtures validate their actual supported interactions and executed evidence. Source-detector assertion failures are recorded after validation, with attempt-specific diagnostics retained beyond cleanup.

## [1.90.0.0] - 2026-09-24

Cookie imports now keep the chosen browser, profile, and destination explicit, show partial failures, and distinguish copying cookies from proving that you are signed in.
Expand Down
42 changes: 18 additions & 24 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,30 +514,24 @@ package.json (npm rejects it). Rationale and translation rules live in the
`lib/version-source.ts` header; `test/gstack-version-bump.test.ts` pins the
contract.

**Scale-aware bumps — use common sense.** When the diff is big, bump MINOR (or
MAJOR), not PATCH. PATCH is for bug fixes and small additions; MINOR is for
substantial new capability or substantial reduction; MAJOR is for breaking
changes. Rough guideposts (don't treat as rules, treat as smell-checks):

- **PATCH (X.Y.Z+1.0)**: bug fix, doc tweak, small additive change, single
test/file added. Net diff under ~500 lines, no new user-facing capability.
- **MINOR (X.Y+1.0.0)**: new capability shipped (skill, harness, command, big
refactor), substantial code reduction (compression, migration), or coordinated
multi-file change. Net diff over ~2000 lines added/removed, OR a user-visible
feature you'd put in a tweet.
- **MAJOR (X+1.0.0.0)**: breaking change to public surface (CLI flag rename,
skill removed, config format changed), OR a release big enough to be the
headline of a blog post.

If you find yourself debating "is 10K added + 24K removed really a PATCH?" — it
isn't. Bump MINOR. Same for "this adds a whole new test harness with 6 new E2E
tests + helper utilities" — MINOR. The bump level is communication to the user
about what kind of release this is; don't undersell it.

When merging origin/main brings a higher VERSION, re-evaluate the bump level
against the SCALE of your branch's work, not just whether main moved forward.
If main bumped MINOR and your branch is also a substantial change, you bump
MINOR again on top (e.g., main at v1.14.0.0, your branch lands v1.15.0.0).
**Choose versions autonomously; default to PATCH.** Garry delegates release
version decisions to the agent. Do not ask him to choose or approve a version,
including when an already-approved version collides with another PR. This policy
overrides generic version-approval prompts in `/ship` and `/document-release`.

Prefer **PATCH (X.Y.Z+1.0)** for ordinary releases, including fixes, additions,
refactors, test infrastructure and coordinated multi-file work. Diff size alone
is not a reason to choose MINOR. Choose **MINOR (X.Y+1.0.0)** or **MAJOR
(X+1.0.0.0)** only when calling the release a patch would be plainly misleading
("ridiculous"), such as an incompatible public-interface change or a genuinely
new product-scale release. Make that judgment without another approval question.

Use `bin/gstack-next-version` to check the live release queue before publishing.
If a slot is claimed, advance to the next available version at the chosen bump
level and use `bin/gstack-version-bump` to synchronize release metadata. A higher
base version does not itself require a MINOR bump. Keep the PR ready for Garry to
merge; autonomous version decisions do not authorize merging, deploying or
skipping required validation.

**VERSION and CHANGELOG are branch-scoped.** Every feature branch that ships gets its
own version bump and CHANGELOG entry. The entry describes what THIS branch adds —
Expand Down
13 changes: 9 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,16 @@ unknown-input results cannot be reused.
Timing goals are under one minute for edit feedback, 3–5 minutes for typical PR
checks, and 60–90 seconds for complete free test execution across isolated CI
machines. They are targets, not timeout reductions or guarantees. The complete
local suite keeps six workers and currently takes roughly 4–5 minutes; use
`test:quick` for the shorter edit loop. CI setup, build and queue time are reported
local suite uses available CPU affinity, up to six workers; use `test:quick` for
the shorter edit loop. The historical six-worker result below and the
[four-CPU portfolio comparison](docs/TEST_PORTFOLIO.md#measurement-contract)
are machine-specific measurements. CI setup, build and queue time are reported
separately. Refresh measurements with `bun run test:free --record-durations`;
the required free CI lane packs the complete inventory across isolated runners,
then checks every shard's receipt before reporting success. Local worker counts
remain bounded to avoid browser/process contention.

Measurements from this PR on 2026-09-21:
Historical measurements from 2026-09-21:

| Run | Coverage | Elapsed |
|---|---|---|
Expand All @@ -226,7 +228,10 @@ Measurements from this PR on 2026-09-21:
The [Linux CI run](https://github.com/garrytan/gstack/actions/runs/35642667809)
on `25030d68` included one recorded successful retry. Its slowest test step was 77 seconds;
staggered starts made the complete test span longer. Typical PR paid-gate timing
still needs measurement on a small change; test-runner changes use the full fallback.
still needs measurement on a small change. Explicitly exempt free-only runner
changes do not select paid work; mapped dependencies take precedence, and unknown
dependencies retain the broad fallback. See the
[coverage boundaries](docs/TEST_PORTFOLIO.md#repeated-work-removed).

Follow [Validation discipline in AGENTS.md](AGENTS.md#validation-discipline):
reproduce known failures with focused checks, verify adjacent source and
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.90.0.0
1.90.2.0
2 changes: 1 addition & 1 deletion agents-digest/gstack-AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gstack digest v1.90.0.0 — regenerate/re-copy after upgrading gstack
# gstack digest v1.90.2.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,
Expand Down
12 changes: 11 additions & 1 deletion docs/TESTING_INTERNALS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ reported separately. See [Overlay benchmark contract v2](OVERLAY_BENCHMARK_CONTR
for exact correctness requirements, retired fanout cases, immutable evidence,
and the limits of a passing result.

## Coverage ownership

[The test portfolio audit](TEST_PORTFOLIO.md) separates deterministic harness
checks, prompt judges, live first-question captures, completed workflows and
platform integrations. Shared setup is reusable; evidence with different
scenario or independent-trial requirements is not. It records the preserved
coverage and measured component savings from the test-speed refactor.

## Runners: how the suites execute (2026-08 overhaul)

**Aside-only E2E tests self-skip without a live Aside; browser-driving tests
Expand Down Expand Up @@ -153,7 +161,9 @@ load-sensitive on a busy dev box, runs only in CI or on explicit opt-in

**Free suite (`bun run test:free`).** `scripts/test-free-shards.ts` runs N
concurrent shard processes (serial within each) with strict-output
classification per shard. Full-suite shards are packed by RECORDED PER-FILE
classification per shard. Local defaults use the available CPU affinity,
floored at one and capped at six; `GSTACK_FREE_JOBS` remains an explicit override.
This does not change the separate CI machine count. Full-suite shards are packed by RECORDED PER-FILE
DURATIONS (LPT, `packShardsByDuration`) when the committed seed
`scripts/free-test-durations.json` exists — refresh it occasionally with
`bun run test:free --record-durations` (each file timed in its own child;
Expand Down
Loading
Loading