Merge remote-tracking branch 'origin/main' into flaky-2026-10-28-judges

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
garrytan committed 2026-10-29 02:00:01 +00:00
commit d11765dd73
80 files changed
+2544 -5021

No files matched your search

+11 -5
View File
@@ -975,8 +975,8 @@ with `GSTACK_FREE_RETRY_FLAKY=0`.
A stock Ubuntu 24.04 VM differs from a GitHub-hosted runner in three ways that
the scripts correct: the login umask is `002` (group-writable directories fail
the CSO private-state checks), AppArmor blocks the unprivileged user
namespaces Chromium's sandbox needs, and `clang` and `python3-venv` are absent
(required by the Dia readiness and Python runner tests).
namespaces Chromium's sandbox needs, and `python3-venv` is absent (required by
the Python runner tests).
VMs are named `ubirun-<owner>-<epoch>-<hex>`, plus a `-t<hours>` TTL suffix
(below); `<owner>` is `UBI_OWNER` (set it to the thread id on a Capy machine;
@@ -1435,7 +1435,13 @@ Free-suite flake rules:
every shard child's `GIT_CONFIG_*` pairs as a backstop, so it covers fixtures
that inherit the environment, and `bun run scripts/ship-measure.ts free
--backend local` measures with that environment; a fixture with its own
replacement env never sees the backstop.
replacement env never sees the backstop. Neither does the receiving side of
a push to a local path: git's local transport drops `GIT_CONFIG_*` from the
`receive-pack` it starts, so every push into a fixture's bare origin still
leaves a detached maintenance run in that origin. A fixture that clones such
an origin passes `--no-local` (`coordinatorClone` in
`test/helpers/ship-queue-fixture.ts`), so the clone reads it through git's
transport instead of copying `objects/` entry by entry.
To reproduce a ledger entry, take the shard's exact file list from the CI run's
`free-plan` artifact, then rerun it with the flaky retry off on a CI-mirrored VM:
@@ -1531,10 +1537,10 @@ on win32, drives a POSIX signal path) leaves it through a
the file moved.
Native qualification campaigns (Windows cookie extraction, Windows launch
diagnostics, Dia on macOS) run only on dispatch of `native-qualification.yml`:
diagnostics) run only on dispatch of `native-qualification.yml`:
```bash
gh workflow run native-qualification.yml --ref <branch> -f mode=<cookie-native|windows-native-diagnostics|dia-native|dia-launch-comparison|dia-gui-readiness>
gh workflow run native-qualification.yml --ref <branch> -f mode=<cookie-native|windows-native-diagnostics>
```
### Real-setup install fixture
+1 -1
View File
@@ -60,7 +60,7 @@ depends on measured duration or an explicit `QUICK_CORE` entry, not this table.
| CLI/API/webhook QA without browser setup | `qa-functional-fixture`, `qa-functional-evidence`, `qa-lazy-sections` | `skill-e2e-qa-functional`: CLI and webhook report sessions | Linux/macOS free; selected PR gate; Windows only where curated |
| Report-only preserves local and remote authority | `qa-only-capability`, `qa-functional-observer`, `qa-functional-observer-atomic`, `qa-caller-authority` | Independent report-only sessions with synthetic owned endpoints/auth | Linux kernel observation; free callback controls plus selected PR gate |
| Repair reproduces the defect, adds a failing regression and rechecks adjacent behavior | `qa-fix-loop-fixture`, `qa-functional-evidence` | `skill-e2e-qa-functional-fix`: CLI and webhook repair sessions | Free controls plus selected PR gate |
| Review and Ship actually explore | `qa-exploratory-callers`, `qa-caller-report-observer`, `qa-checkpoint-evidence` | `skill-e2e-qa-callers`: actual Review/Ship callers | Free captures plus selected PR gate |
| Review and Ship actually explore | `qa-exploratory-callers`, `qa-caller-report-observer`, `qa-caller-review-plan`, `qa-checkpoint-evidence` | `skill-e2e-qa-callers`: actual Review/Ship callers | Free captures plus selected PR gate |
| Smoke expiry preserves required plan checks | `qa-deadline`, `qa-deadline-selection`, `qa-browser-deadline-evidence` | `ship-exploratory-plan-checks` | Free deadline/dispatch controls plus selected PR gate |
| Late changes invalidate affected results | `qa-caller-freshness-order`, `qa-deadline-publication-observer`, `shared-libs-revalidation-prompt` | `ship-exploratory-late-input` and the existing late-input documentation handoff | Free stale-input controls plus selected PR gate |
| Documentation completes before publication and respects protected files | `docsync-authority`, `docsync-atomic-writes`, `docsync-report-interface`, `docsync-lifecycle-interface` | `skill-e2e-ship-docsync`, `skill-e2e-docsync-spawned` | Free state/permission controls; registered gate/periodic scenarios retain their tiers |
+2 -2
View File
@@ -63,7 +63,7 @@ The plan-ceo-review-plan-mode (:89, :108), plan-devex-review-plan-mode (:181-222
| auq-format-gate | test/skill-e2e-ask-user-question-format-compliance.test.ts:58 | question ~ `options differ in kind` | AUQ tool input | yes | (c) |
| auq-format-gate | test/skill-e2e-ask-user-question-format-compliance.test.ts:61, :68 | recommendation substance ≥ 4 | — | — | judge |
| plan-tune-inspect | test/skill-e2e-plan-tune.test.ts:167-169, :185 | output names ≥2 of 3 seeded question IDs or aliases | question-log is seeded fixture input | yes (inspection report) | (c) |
| plan-review-report | test/skill-e2e-plan.test.ts:463-491 | plan.md `## GSTACK REVIEW REPORT`, CEO/Eng/Design rows, ends with `NO UNRESOLVED DECISIONS` or a bullet | rows come from the seeded review log; the table is rendered | yes | (c) |
| plan-review-report | test/skill-e2e-plan.test.ts:472-500 | plan.md `## GSTACK REVIEW REPORT`, CEO/Eng/Design rows, ends with `NO UNRESOLVED DECISIONS` or a bullet | rows come from the seeded review log; the table is rendered | yes | (c) |
### test/skill-e2e-design.test.ts (gate cases)
@@ -89,7 +89,7 @@ The plan-ceo-review-plan-mode (:89, :108), plan-devex-review-plan-mode (:181-222
|---|---|---|---|---|---|
| shared-libs-read-only | test/skill-e2e-shared-libs.test.ts:113-120 | report ~ uncommitted/overlay/raw, tip and branch SHAs, retry-worker/route, no blob link for branch-only file | none (read-only by contract) | yes | (c) |
| shared-libs-unsupported-git | test/skill-e2e-shared-libs.test.ts:136, :144 | report ~ unavailable/unsupported/limited; not "no commits/PRs found" | none | yes | (c) |
| shared-libs-review-path-eligibility | test/skill-e2e-shared-libs-paths.test.ts:133-134 | `trace + output` ~ submodule/160000, check-ignore/ignored (output alone satisfies) | Bash command trace (first operand) | no | (b) |
| shared-libs-review-path-eligibility | test/skill-e2e-shared-libs-paths.test.ts:134-135 | `trace + output` ~ submodule/160000, check-ignore/ignored (output alone satisfies) | Bash command trace (first operand) | no | (b) |
### test/skill-e2e-ship-docsync.test.ts, test/skill-e2e-docsync-spawned.test.ts
+24
View File
@@ -195,6 +195,30 @@ Two stages with separate clocks, both printed:
no lane, and a workspace-only Cargo.toml or Cargo.lock needs a `dependencies` entry),
transitively through
non-test files; deleted and renamed files select the tests that named them.
A removed test (a deleted one, or a rename's old name) that no remaining
test selects owes no lane, and prints `removed (no lane owed): <path> —
<why>` (the `lanes` detail adds `N removed path(s)`), when it is a JS, TS,
Python, Dart or bats test and no remaining file imports it (directly or
through a directory it reads; otherwise `still imported by …`). It runs
the tests of each remaining non-Markdown file that mentions its name
without the final extension anywhere (`alpha.test`, `test_alpha`:
a path with or without the extension, or a dotted module), such as a curation list (`files naming it run: …`), and fails closed when
such a file has no test (`still named by …, which no test covers`). A test
renamed to another test path then defers to its new name (`old name of
<new>`). A deleted test, or one renamed to a non-test path, also runs its
owning suite, the remaining tests that directly exercise the files its
merge-base text exercised (`owning suite runs: …`; test helpers and
fixtures are not subjects), and names each file left with no test at all
(`coverage removed: <file> has no remaining test`, and `M subject(s) lost
their last test` in the detail). Every other removal owes what an edit
owes, as before: a deleted or renamed Go or Ruby test (it may define
helpers its package still uses), a deleted test whose merge-base text
cannot be read (a symlink, invalid UTF-8, over 1 MiB), and any removed
non-test path, a renamed source file's old name included, are still
`PREGATE_NO_LANE` until a test or a `dependencies` entry covers them. A
modified file whose only test the branch deleted still has no lane, and a
remaining test that reads a deleted file or directory is selected. /review
lists a deleted test as a gate edit (RH-1) either way.
An extensionless JS/TS import (relative, a tsconfig/jsconfig `paths` alias or
`baseUrl`) tries the exact path, then `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`,
`.cjs`, `.mts`, `.cts`, then `index.ts`, `index.tsx`, `index.js`, `index.jsx`
+2 -2
View File
@@ -31,7 +31,7 @@ Detailed guides for every gstack skill — philosophy, workflow, and examples.
| [`/document-generate`](#document-generate) | **Technical Writer** | Generate Diataxis docs (tutorial / how-to / reference / explanation) for a feature from code. |
| [`/retro`](#retro) | **Eng Manager** | Team-aware weekly retro. Per-person breakdowns, shipping streaks, test health trends, growth opportunities. |
| [`/browse`](#browse) | **QA Engineer** | Give the agent eyes. Drives your Aside browser first — real sessions, real clicks, real screenshots — through deterministic `aside repl` scripts, and falls back to gstack's own Chromium (~100ms per command) when Aside isn't there. |
| [`/setup-browser-cookies`](#setup-browser-cookies) | **Session Manager** | Copy selected cookies from Chrome, Chromium, Brave, Edge, Windows-only Opera and Opera GX, or macOS-only Comet, Arc, and Dia into the fallback browser. Choose your profile and domains; check sign-in separately. Unnecessary on Aside, which already has your sessions. |
| [`/setup-browser-cookies`](#setup-browser-cookies) | **Session Manager** | Copy selected cookies from Chrome, Chromium, Brave, Edge, Windows-only Opera and Opera GX, or macOS-only Comet and Arc into the fallback browser. Choose your profile and domains; check sign-in separately. Unnecessary on Aside, which already has your sessions. |
| [`/autoplan`](#autoplan) | **Review Pipeline** | One command, fully reviewed plan. Runs CEO → design → DX → eng review automatically (eng always last, so the shipping gate reviews the final amended plan) with encoded decision principles. Surfaces only taste decisions for your approval. |
| [`/plan-devex-review`](#plan-devex-review) | **DX Reviewer** | Plan-stage DX review. TTHW (time-to-hello-world), magical moments, friction points, persona traces, and error messages scored for the agents that read them ([agent-ready errors](agent-ready-errors.md)). Three modes: Expansion, Polish, Triage. |
| [`/devex-review`](#devex-review) | **DX Reviewer (live)** | Live developer experience audit. Walks the actual onboarding flow, measures TTHW, catches the docs lies, and triggers CLI errors the way an agent meets them (no terminal, contained, redacted) through `gstack-error-capture`. |
@@ -1179,7 +1179,7 @@ This is my **session manager mode** — for the fallback browser. With Aside ope
For authenticated testing on gstack's own browser, `/setup-browser-cookies` copies selected cookies from your daily browser. Sites may also need storage or a fresh login, so copying cookies is not proof that the session works.
The picker detects Chrome, Chromium, Brave, Edge, Windows-only Opera and Opera GX, and macOS-only Comet, Arc, and Dia. Choose the browser, account/profile, and domains. Profile labels use the current `Local State` name with a directory discriminator, so renamed profiles and duplicate names are distinguishable. No cookie values are displayed; source/profile labels are still sensitive.
The picker detects Chrome, Chromium, Brave, Edge, Windows-only Opera and Opera GX, and macOS-only Comet and Arc. Choose the browser, account/profile, and domains. Profile labels use the current `Local State` name with a directory discriminator, so renamed profiles and duplicate names are distinguishable. No cookie values are displayed; source/profile labels are still sensitive.
```
You: /setup-browser-cookies
+12
View File
@@ -3211,6 +3211,18 @@ versions, line endings or any non-version byte changed, one under a test,
fixture, golden, `.gstack/` or workflow tree, or one added, deleted, renamed
or re-moded, is still this error; `--explain` prints `not version-stamp-only (<reason>)`
for it.
A test the branch removed is usually not this error either: a deleted or
renamed JS, TS, Python, Dart or bats test that nothing remaining imports prints
`removed (no lane owed): <path> — <why>` instead. It runs the tests of files
that still name it, and a deleted test runs its owning suite or says
`coverage removed: <file> has no remaining test`. These are still this error:
a removed test that remaining code imports or that a file with no test still
names, a deleted or renamed Go or Ruby test, a deleted test whose merge-base
text cannot be read (a symlink, invalid UTF-8, over 1 MiB), any other removed
path (a renamed source file's old name included), and a modified file whose
only test the branch deleted. `--explain` prints the reason as `<path>:
removed, but …` (`<path>: removed test whose merge-base text could not be
read …` for an unreadable deleted test).
**Fix.** Add a test that names the file, or declare its lane (an explicit `[]`
for files with no behaviour) under `dependencies` in `.gstack/pregate.json` (or the user-owned file the message names).