Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
219 commits
Select commit Hold shift + click to select a range
ff5fbd0
docs: approved severe fix wave plan (Oct 2026)
garrytan Oct 3, 2026
7372769
D0: keep a project's .env and bunfig.toml out of compiled binaries an…
garrytan Oct 3, 2026
7e2edf2
A9: --no-write is a dry run and leaves ingest state untouched
garrytan Oct 3, 2026
e64930d
H #2885 #2827: vector geometry is not phone or card PII
garrytan Oct 3, 2026
85e8a7a
D1: pin the terminal-agent /ws Origin to the gstack extension (#1324)
garrytan Oct 3, 2026
606bfcb
H #2899: env.kv skips a function call assigned to a credential name
garrytan Oct 3, 2026
907717d
H #2962: per-machine config filenames are not internal hostnames
garrytan Oct 3, 2026
5999ee3
H #2784: four-part versions need a version declaration, not a shape
garrytan Oct 3, 2026
1787240
H #2913: postgres:postgres is exempt only on a loopback host
garrytan Oct 3, 2026
6ac92d1
G1: ship without a version when no version source is configured
garrytan Oct 3, 2026
e6676ea
H #2949: eval credential screen checks every name segment
garrytan Oct 3, 2026
1cd1911
H #2915: cover chunked scanning of large multi-file push diffs
garrytan Oct 3, 2026
f20cd9a
A3: keep a project's DATABASE_URL away from a PGLite brain
garrytan Oct 3, 2026
a0c0668
C9: guard destructive gstack-upgrade and spec fences against unset or…
garrytan Oct 3, 2026
bd1d7d0
F4: keep every paid design variant across regenerate rounds
garrytan Oct 3, 2026
96f473a
A2: stage dot-leading slugs gbrain can collect; network errors are db…
garrytan Oct 3, 2026
b34cc82
D2: one address classifier for navigation literals, DNS answers, redi…
garrytan Oct 3, 2026
b141b10
C4: external hosts point at carved sections relative to the installed…
garrytan Oct 3, 2026
9aba7d9
INV-1: gate outcome contract for outside reviews
garrytan Oct 3, 2026
214cf0b
G1: quote the base placeholder in document-release title sync
garrytan Oct 3, 2026
3e55fb8
G3: give every logging-bin mktemp a ${TMPDIR:-/tmp} template
garrytan Oct 3, 2026
6f5eb60
B1b: structured outside-review gate fails on P0 as well as P1
garrytan Oct 3, 2026
fb4d298
E1: freeze normalizes boundary and target the same way on Windows; ho…
garrytan Oct 3, 2026
6167731
G4: keep CLI-to-daemon loopback calls off HTTP_PROXY (#494)
garrytan Oct 3, 2026
e99c1fc
F1: bind the plan audit to this branch's plan, never the newest file
garrytan Oct 3, 2026
5015a93
G5: browse type --selector <sel> <text> (#2936)
garrytan Oct 3, 2026
998f116
F2: design-doc discovery reads docs/designs, never a root DESIGN.md
garrytan Oct 3, 2026
b4f1bd9
C4: rename the external carve test (typecheck:test union-order artifact)
garrytan Oct 3, 2026
c050f18
C1: every env-var host fence resolves its own gstack root
garrytan Oct 3, 2026
46f4f52
E8: headless browse honors GSTACK_CHROMIUM_PATH; extensions load in n…
garrytan Oct 3, 2026
467c7d9
C2: link design/dist and make-pdf/dist into every host runtime root a…
garrytan Oct 3, 2026
d059805
C3: install router and nested SKILL.md files as real copies; back up …
garrytan Oct 3, 2026
f89c5bc
INV-3: install-level host conformance checks (no symlinked SKILL.md, …
garrytan Oct 3, 2026
2482825
B11: auto-update tracks pull, setup and migrations; announces only on…
garrytan Oct 3, 2026
f2838fd
D1: gstack-config key browse_extension_id for forks and self-built ex…
garrytan Oct 3, 2026
3731187
G2: key the sticky slug cache on the git common dir
garrytan Oct 3, 2026
82a79be
C5: OpenCode /gstack-* commands load the skill by its frontmatter name
garrytan Oct 3, 2026
5f38b93
E4: Windows node-server bundle keeps sharp and socks external; CLI re…
garrytan Oct 3, 2026
0642559
B1: Codex reviews whose sandbox could not start are unavailable, not …
garrytan Oct 3, 2026
68cabd0
C6: gstack-relink discovers skills structurally, so /browse survives …
garrytan Oct 3, 2026
bc5b08e
C4: carve ship and plan-ceo-review on every host; enforce the 160 KB …
garrytan Oct 3, 2026
85c9d4c
B5: learnings and timeline reads fail loudly when bun is missing
garrytan Oct 3, 2026
ee70bec
B2: a retired-model 404 reports MODEL_UNUSABLE, not CODEX_MODE: ready
garrytan Oct 3, 2026
aa90e52
B6: rank learnings by matched query tokens and disclose truncation
garrytan Oct 3, 2026
8e4bb7d
C7: required team mode also blocks Copilot CLI's lowercase skill tool
garrytan Oct 3, 2026
ebab87b
B3: Codex auth probe accepts custom providers' env_key credentials
garrytan Oct 3, 2026
3f712a4
E8: keep the extensions profile under the state dir at a path lock cl…
garrytan Oct 3, 2026
11b1a96
B10: plan-tune never reports CALIBRATED with zero signal events
garrytan Oct 3, 2026
97d4e58
A1: verify gbrain landing before stamping transcripts, plus --reconcile
garrytan Oct 3, 2026
0e9b2c5
B4: arm64 re-sign keeps a backup, restores it when codesign fails, an…
garrytan Oct 3, 2026
64638f3
D3: treat design docs and handoff notes as data in plan reviews
garrytan Oct 3, 2026
0d9ebd2
D4: setup-deploy reports Render API key presence only
garrytan Oct 3, 2026
88b480e
D5: per-project headed Chromium profiles; never kill a live profile o…
garrytan Oct 3, 2026
645e39e
F5: installed Claude skills serve the rendered sections, not the chec…
garrytan Oct 3, 2026
427322d
F1: ratchet /ship's parity union-size cap for this lane's content
garrytan Oct 3, 2026
e2f9e14
E5: feed every Codex prompt on stdin instead of argv
garrytan Oct 3, 2026
5bcc4b5
G6: prettyscreenshot --hide keeps a trailing image path as the output…
garrytan Oct 3, 2026
25638ad
INV-3: render-level host conformance and generated-bash lint on every…
garrytan Oct 3, 2026
8051efc
G6: analytics averages quoted duration_s values (#1728)
garrytan Oct 3, 2026
2ffeba5
G6: gstack-ios-qa-daemon --help prints usage instead of starting the …
garrytan Oct 3, 2026
0977717
G1: tighten /ship's NO_VERSION wording to fit the union-size cap
garrytan Oct 3, 2026
5ee77d2
G6: rejected taste preferences gain confidence (#1777)
garrytan Oct 3, 2026
57cdf93
E2: Windows /cso build disables only C5105, and a failed MSVC compile…
garrytan Oct 3, 2026
4bc9b06
E6: gbrain-refresh hands the detection file to Python on stdin
garrytan Oct 3, 2026
e2cf27f
G6: context-save computes session duration on Linux (#2704)
garrytan Oct 3, 2026
605f49d
Q2: one-time notice naming the Codex provider and account for outside…
garrytan Oct 3, 2026
313d0c8
Q1: validate browser output paths the way the kernel resolves them (#…
garrytan Oct 3, 2026
104aac9
G6: retro test census counts non-JS suites, skips generated output
garrytan Oct 3, 2026
e6f4d0f
Q3: setup stops auto-installing the AskUserQuestion preference hook i…
garrytan Oct 3, 2026
4b983a0
E5: watchdog stdin test feeds the wrapper through a redirect
garrytan Oct 3, 2026
34799b8
F4: type the variant-round fetch stub like the existing stubs
garrytan Oct 3, 2026
d02c8ef
A4: import transcripts into per-repository, non-federated gbrain sources
garrytan Oct 3, 2026
358d91e
F3: load the taste profile, and report a failed slug lookup
garrytan Oct 3, 2026
79bfc02
B4: DESIGN_READY only when the design binary actually starts
garrytan Oct 3, 2026
ac5cf21
C2: name the runtime root every way a generated preflight may read it…
garrytan Oct 3, 2026
16aed1c
A5: brain-sync stage fails loud when the artifacts source indexed zer…
garrytan Oct 3, 2026
71c231a
B1: state the effective read-only sandbox in /codex review prose
garrytan Oct 3, 2026
ce651c2
A6: report deleted-worktree gbrain sources; prune only with proof, on…
garrytan Oct 3, 2026
ae86d10
D0: pass the Bun child flags after 'run' so wrappers that rewrite 'bu…
garrytan Oct 3, 2026
10eac64
E8: count the BROWSE_EXTENSIONS_DIR persistent launch in the signal-f…
garrytan Oct 3, 2026
3995f0e
D2: give the memory-leak reproducer's fake request isNavigationRequest()
garrytan Oct 3, 2026
76bf72d
A7: run only the resolve_symbol_edges dream phase, detected first
garrytan Oct 3, 2026
4c04363
D0: keep the dotenv isolation test runnable on the Windows lane
garrytan Oct 3, 2026
a05965f
B9: read cycle_freshness from a doctor run that includes it
garrytan Oct 3, 2026
3882efb
B4: compact the launch probe (cache keyed on inode, valid while newer…
garrytan Oct 3, 2026
f238001
C4: migrate the ship docs-dispatch test to the carved external ship
garrytan Oct 3, 2026
f69f831
B5: learnings callers report a failed search instead of reading as empty
garrytan Oct 3, 2026
4034a55
F1: ship and review count unverified/unavailable outside reviews as m…
garrytan Oct 3, 2026
c612f28
A8: rename the artifacts repo with OWNER/REPO, rewrite the remote onl…
garrytan Oct 3, 2026
6c0917a
B8: read gbrain JSON with bun instead of jq in install and wireup
garrytan Oct 3, 2026
07c2e8c
B4: shorter probe messages (design-consultation parity budget)
garrytan Oct 3, 2026
6de595e
B5: shorter capture variable names (parity budget)
garrytan Oct 3, 2026
4492199
E7: find the Aside CLI in ~/.local/bin when it is not on PATH (#2902)
garrytan Oct 3, 2026
7a04d4c
A2: key the dot-slug catalog entry on the message users actually saw
garrytan Oct 3, 2026
7da1c3c
E1: cmd.exe-safe investigate freeze hook
garrytan Oct 3, 2026
9eda423
F4: design resolver reads per-round variant paths
garrytan Oct 3, 2026
a1969d9
E4: generators tolerate Bun's spurious EEXIST on Windows (#2329)
garrytan Oct 3, 2026
8ae92b2
C7: keep the required-mode hook's exit-2 deny
garrytan Oct 3, 2026
4527c9b
C3: guard Kiro's router copies on a present source; give the QA point…
garrytan Oct 3, 2026
5526fca
Q3: office-hours asks open-ended questions in a Q<N> prose form (#2719)
garrytan Oct 3, 2026
3f3655b
A2: render db-unreachable like timeout
garrytan Oct 3, 2026
8d1b6dc
A2: treat db-unreachable like timeout in gbrain-refresh
garrytan Oct 3, 2026
dc7a95a
C8: a render given disabled skills drops them from the router (#3018)
garrytan Oct 3, 2026
93742a1
Merge lane wave/inv1-codex
garrytan Oct 3, 2026
44e03d5
Merge lane wave/memory
garrytan Oct 3, 2026
5302d7a
Merge lane wave/browse-platform
garrytan Oct 3, 2026
67d5685
Merge lane wave/ship-review
garrytan Oct 3, 2026
c05c796
Merge lane wave/redaction
garrytan Oct 3, 2026
8857089
Merge lane wave/setup
garrytan Oct 3, 2026
b8d08f1
G2/G3/INV-1: skill-start former-bucket notice and visible learnings f…
garrytan Oct 3, 2026
b94288d
C9: Step 2 falls back to the install registry's source checkout (DX-7)
garrytan Oct 3, 2026
d3640f2
B4: design --version prints the version, and the probe uses it
garrytan Oct 3, 2026
ea0b484
C4: no external render points at a section file that is not installed
garrytan Oct 3, 2026
424214a
C1: skillify finds the browse SDK under its own host's install root
garrytan Oct 3, 2026
ac8e30c
C4: rewrite section refs on hosts whose root stays a literal ~/<globa…
garrytan Oct 3, 2026
e6096a5
Merge lane wave/generator
garrytan Oct 3, 2026
f76974b
Integrator: outside-voice fences use the shared runtime prelude; TMPD…
garrytan Oct 3, 2026
f7efb26
Integrator: C8 router omits disabled skills on every render (relink r…
garrytan Oct 3, 2026
b2c3e15
Q1 (#2971 salvage): bound iOS proxy responses
garrytan Oct 3, 2026
aab8009
I1: grade the AUQ matrix's (recommended) marker on option labels, the…
garrytan Oct 3, 2026
d98b7c1
Q1: type the proxy-transport test doubles (typecheck:test ratchet)
garrytan Oct 3, 2026
c545d4e
INV-1: gate outcome rows and troubleshooting sections for every lane'…
garrytan Oct 3, 2026
3b03df8
Release v1.91.19.0 (next free patch in the queue: #3022 holds 1.91.17…
garrytan Oct 3, 2026
94c1645
v1.91.19.0 docs and metadata: CHANGELOG, TODOS, README troubleshootin…
garrytan Oct 3, 2026
ed5260a
I1: give hermetic Codex runs a temp dir beside CODEX_HOME so Codex ca…
garrytan Oct 3, 2026
3a13b6d
I1: Codex evals fail a review whose commands never ran and stop readi…
garrytan Oct 3, 2026
ec97187
I1: run paid eval containers with seccomp unconfined so Codex's sandb…
garrytan Oct 3, 2026
ed27163
I1: shared-libs plan actor reads one exclusion grammar for scope lists
garrytan Oct 3, 2026
406d012
Parity caps: measured v1.91.19.0 union/skeleton sizes for ship, revie…
garrytan Oct 3, 2026
c43326b
Regenerate generated output for v1.91.19.0 (gen:skill-docs --host all…
garrytan Oct 3, 2026
303cdd0
I1: plan-eng-review writes the Test Plan Artifact even while test cho…
garrytan Oct 3, 2026
c7a24ec
I3: plan-eng-review states when findings first enter the report and t…
garrytan Oct 3, 2026
6c0fe85
I3: plan-ceo-review defines the closing sequence's cleanup step
garrytan Oct 3, 2026
5299cda
I3: /qa-only's value-card rule names only its own card location
garrytan Oct 3, 2026
bc8e218
test-of-test ratchet: a repo script or setup read by path counts as p…
garrytan Oct 3, 2026
76f1581
I1: DX floor actor strips the editor hint from the footer line only (…
garrytan Oct 3, 2026
7eb85e0
I4: attribute every census testcase; deselections never count as SKIPPED
garrytan Oct 3, 2026
239d9c8
I5: split the deploy file per case; guard PR-lane shard walls at 600 s
garrytan Oct 3, 2026
cebc517
TODOS: /review fingerprint under Codex's read-only .git sandbox (foun…
garrytan Oct 3, 2026
091f48a
Free-suite repairs from the first integrated Ubicloud run
garrytan Oct 3, 2026
f9c416f
Regenerate generated output after the outside-voice prelude repair
garrytan Oct 3, 2026
7ae7776
I1: revert the seccomp-only eval container option; it does not let Co…
garrytan Oct 3, 2026
dd9e4e7
I1: a Codex review eval needs a completed command, not just review-sh…
garrytan Oct 3, 2026
a71fbf9
Merge lane wave/evals
garrytan Oct 3, 2026
c0e08a4
Evals lane follow-ups: close the skillify gate TODO (I2 green), file …
garrytan Oct 3, 2026
554d84a
Regenerate generated output after merging wave/evals
garrytan Oct 3, 2026
6a2c1e5
D2: bound the navigation guard's tab reset (commit, 5 s)
garrytan Oct 3, 2026
950cff3
I1: run Codex paid slices on a host-run job where bubblewrap can start
garrytan Oct 3, 2026
34854c2
I1: the /codex review eval passes only when Codex executed
garrytan Oct 3, 2026
9c889a9
TODOS: characterize the free-suite timing reds from Ubicloud run 4
garrytan Oct 3, 2026
ba50f75
I1: QA evidence names the probes to rerun after an input change, befo…
garrytan Oct 3, 2026
4e7447e
I1: the eng batching counter reads records under "Section N — <review…
garrytan Oct 3, 2026
814fc15
I1: plan-eng-review-artifact names its report file without making it …
garrytan Oct 3, 2026
8676dcd
browse: close returns when Chromium exits; Xvfb cleanup does not wait…
garrytan Oct 3, 2026
a818a99
I1: office-hours-brain-writeback reads the long skill with Read and s…
garrytan Oct 3, 2026
3ece23b
Merge origin/main (v1.91.17.0) into the severe fix wave
garrytan Oct 3, 2026
914b3a0
CI: no credential-shaped URLs in added lines (quality scan); release …
garrytan Oct 3, 2026
4752dca
qa-evidence: hold the stdout-pipe cases on a FIFO, not on a paused ch…
garrytan Oct 3, 2026
5832c09
TODOS/CHANGELOG: the three run-4 timing reds are fixed at their cause…
garrytan Oct 3, 2026
dee7ba9
I1: a QA helper call bun could not load is checked at the installed p…
garrytan Oct 3, 2026
e2f65ab
I1: plan-eng-review's final self-check names its three outputs
garrytan Oct 4, 2026
4de4432
I1: revert the plan-eng-review self-check wording; it did not change …
garrytan Oct 4, 2026
9244437
I1: seed the Codex files' periodic durations from their first executi…
garrytan Oct 4, 2026
916c46b
Refresh scripts/free-test-durations.json (bun run test:ubicloud --rec…
garrytan Oct 4, 2026
d756a21
Merge lane wave/evals2
garrytan Oct 4, 2026
9a96fb3
evals2 follow-ups: outside-voice-evidence helper in five case touchfi…
garrytan Oct 4, 2026
82d3658
fix(browse): take the next free X display when a concurrent allocator…
garrytan Oct 4, 2026
488fc72
test(ci): read the host-run Codex eval job's docker env, mounts and u…
garrytan Oct 4, 2026
dc09764
I1: plan-eng-review-artifact runs the real interactive review in a PT…
garrytan Oct 4, 2026
10fdb81
Merge commit 'dc09764' into garrytan/severe-fix-wave-oct3
garrytan Oct 4, 2026
2896722
evals2 final: plan-eng-review-artifact touchfiles point at its PTY fi…
garrytan Oct 4, 2026
364f0f3
TODOS/CHANGELOG: close plan-eng-review-artifact (real PTY review, 498…
garrytan Oct 4, 2026
9d37bb4
test: plan-eng-review-artifact is a PTY runner consumer (selected by …
garrytan Oct 4, 2026
dfaf154
test(windows): spawn cmd.exe hooks verbatim, use a .invalid UNC host,…
garrytan Oct 4, 2026
a05a01e
eval(plan-design-with-ui): the Step 0D focus title may spell the seve…
garrytan Oct 4, 2026
1ffd38e
eval(ship-docsync): git check-ignore is a declared read in the docs o…
garrytan Oct 4, 2026
6290edd
fix(browse): read Xvfb's own startup error to classify a lost display…
garrytan Oct 4, 2026
8e2beec
Merge origin/main v1.91.18.0 (#3023) into the v1.91.19.0 wave
garrytan Oct 4, 2026
feaa28d
test: merged-main fixtures (E6 copies the Claude render library gstac…
garrytan Oct 4, 2026
933fdb9
qa: materialize runs once per PROBE_DIR, and qa-only says §1 reuses t…
garrytan Oct 4, 2026
a90d80a
Regenerate generated output for the qa materialize/REPORT_DIR wording
garrytan Oct 4, 2026
1597dcc
eval: three detector defects from run 37170610789 (feaa28d)
garrytan Oct 4, 2026
c219d8e
fix(test:free): a browser record removed mid-read by a shutting-down …
garrytan Oct 4, 2026
b2f729b
test(windows): the 2>&1 wrapper regression uses relative reads (no na…
garrytan Oct 4, 2026
efca3fa
test(plan-seed): wait for the fixture CLI's slash event instead of a …
garrytan Oct 4, 2026
a8ace39
eval(plan-design-with-ui): recognize the Step 0D focus question by me…
garrytan Oct 4, 2026
54c5b6b
eval(shared-libs-read-only): curl answers the provider rate-limit pro…
garrytan Oct 4, 2026
98a3d6c
eval(shared-libs-plan-callers): an exclusion may combine states (unch…
garrytan Oct 4, 2026
307ba98
paid: --case plan-eng-review-artifact selects its PTY test by its reg…
garrytan Oct 4, 2026
7249f01
eval(plan-eng-review-artifact): periodic checkpoint resumes at Test r…
garrytan Oct 4, 2026
55c2751
setup-deploy: say which deploy fields count as confirmed, how to reso…
garrytan Oct 4, 2026
af4da06
Regenerate generated output for the setup-deploy wording
garrytan Oct 4, 2026
8d2d269
TODOS: census data for the skipped CEO mode handoff (mode-routing, au…
garrytan Oct 4, 2026
65d94f2
fix(browse): a blocked navigation that fails at once leaves the tab b…
garrytan Oct 4, 2026
23cb754
qa: the checkpoint note is created for browser runs and composed for …
garrytan Oct 4, 2026
8b920ef
Regenerate generated output for the qa checkpoint wording
garrytan Oct 4, 2026
db91607
eval(section-loading): byte-range prints of a section count as a comp…
garrytan Oct 4, 2026
d603a63
test(plan-design-review): count design terms the review wrote into th…
garrytan Oct 4, 2026
b33caad
fix(aside): probe names the platform (GSTACK_PLATFORM override) so th…
garrytan Oct 4, 2026
e3546d9
fix(plan-ceo-review): Step 0E mode handoff runs gstack-ceo-mode-hando…
garrytan Oct 4, 2026
755c14e
chore: refresh context-budget fixture
garrytan Oct 4, 2026
a8ecc71
test(auto-decide): accept Step 0E's documented AUTO_DECIDE line with …
garrytan Oct 4, 2026
bb93bff
docs: CHANGELOG and TODOS for the CEO mode handoff and platform line
garrytan Oct 4, 2026
44ef18c
test(plan-design-review): plan-term credit needs a rated summary; ada…
garrytan Oct 4, 2026
d89dc32
test(auto-decide): the printed handoff may precede Step 0E's provenan…
garrytan Oct 4, 2026
27d4fd7
test(plan-ceo-section-loading): read the skill's ledger and currentDe…
garrytan Oct 4, 2026
b24b6d8
test: $B counts as a browser call only in command position; qa functi…
garrytan Oct 4, 2026
fcb4024
test(shared-libs-plan-callers): a verbless unchanged-scope list is an…
garrytan Oct 4, 2026
8895ed7
fix(settings-hook): retry a lock released between mkdir and the exist…
garrytan Oct 4, 2026
8e04fab
test(ship-docsync): the child's reply to a parent SendMessage counts …
garrytan Oct 4, 2026
a66bc3e
test(browse): Xvfb stub-failure tests allocate from ranges no other a…
garrytan Oct 4, 2026
9f357d9
perf(ship): documentation gate snapshots and compares its candidate w…
garrytan Oct 4, 2026
4128700
fix(review): unverified Codex mode runs the passes in the mode summar…
garrytan Oct 4, 2026
2a6b766
test(shared-libs-plan-callers): judge scope by forbidden verb+object …
garrytan Oct 4, 2026
5c47c26
test(shared-libs-plan-callers): type the brief-line parameter
garrytan Oct 4, 2026
fd6854b
test(ship-docsync): an inline-code status quote is not a false curren…
garrytan Oct 4, 2026
9466944
fix(review,ship): Codex challenge and structured-review bodies run in…
garrytan Oct 4, 2026
86d5a8f
docs(TODOS): overlay-harness control-arm error and format-approach pr…
garrytan Oct 4, 2026
37dc8e5
docs(TODOS): qa-only workflow judge data point
garrytan Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
153 changes: 144 additions & 9 deletions .github/workflows/evals-periodic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ jobs:
contents: read
outputs:
periodic_slices: ${{ steps.periodic-matrix.outputs.slices }}
periodic_codex_slices: ${{ steps.periodic-matrix.outputs.codex_slices }}
periodic_timeout_minutes: ${{ steps.periodic-matrix.outputs.timeout_minutes }}
gate_slices: ${{ steps.gate-matrix.outputs.slices }}
gate_timeout_minutes: ${{ steps.gate-matrix.outputs.timeout_minutes }}
Expand All @@ -113,13 +114,18 @@ jobs:
- name: Emit run manifest (ALL periodic tests minus reasoned excludes)
env:
EVALS_ALL: "1"
run: EVALS_TIER=periodic bun --no-install run scripts/test-paid-shards.ts --tier periodic --emit-plan /tmp/paid-plan/manifest.json --slice-budget 540 --jobs 2 --max-parallel 25
run: EVALS_TIER=periodic bun --no-install run scripts/test-paid-shards.ts --tier periodic --emit-plan /tmp/paid-plan/manifest.json --slice-budget 540 --jobs 2 --max-parallel 26

# Codex-only slices run on the host-run eval-codex-slices job; the
# container executor runs every other slice.
- name: Derive the periodic executor matrix from the plan
id: periodic-matrix
run: |
echo "slices=$(jq -c '[range(1; .sliceCount + 1)]' /tmp/paid-plan/manifest.json)" >> "$GITHUB_OUTPUT"
echo "timeout_minutes=$(jq -e '.plan.ciTimeoutMinutes' /tmp/paid-plan/manifest.json)" >> "$GITHUB_OUTPUT"
{
echo "slices=$(jq -c '[range(1; .sliceCount + 1)] - .plan.codexSlices' /tmp/paid-plan/manifest.json)"
echo "codex_slices=$(jq -c '.plan.codexSlices' /tmp/paid-plan/manifest.json)"
echo "timeout_minutes=$(jq -e '.plan.ciTimeoutMinutes' /tmp/paid-plan/manifest.json)"
} >> "$GITHUB_OUTPUT"

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
Expand Down Expand Up @@ -166,7 +172,7 @@ jobs:
fail-fast: false
# Every planned slice starts at once; test/evals-workflow-wiring.test.ts
# fails when the live plan outgrows this cap.
max-parallel: 25
max-parallel: 26
matrix:
slice: ${{ fromJSON(needs.plan-slices.outputs.periodic_slices) }}
steps:
Expand Down Expand Up @@ -280,6 +286,135 @@ jobs:
if-no-files-found: ignore
retention-days: 30

# Codex shards on the host. Codex runs every shell command inside a
# bubblewrap sandbox, which needs an unprivileged user namespace. A job
# container cannot get one: Docker's default seccomp and AppArmor profiles
# block it, and Ubuntu 24.04 hosts set
# kernel.apparmor_restrict_unprivileged_userns=1, which no container option
# can change. This job runs on the runner VM itself (ephemeral, one job),
# lifts that host restriction, and runs the same CI image with both
# profiles unconfined. Only the planner's Codex slices run here
# (scripts/lib/paid-plan.ts codexSlicesOf); slice artifacts use the same
# names as eval-slices, so the report reconciles one manifest.
eval-codex-slices:
runs-on: ubicloud-standard-8
needs: [build-image, plan-slices]
if: ${{ needs.plan-slices.outputs.periodic_codex_slices != '[]' }}
env:
EVALS_RUN_ID: ci-${{ github.run_id }}-${{ github.run_attempt }}-eval-slices-${{ matrix.slice }}
timeout-minutes: ${{ fromJSON(needs.plan-slices.outputs.periodic_timeout_minutes) }}
permissions:
contents: read
packages: read
strategy:
fail-fast: false
max-parallel: 26
matrix:
slice: ${{ fromJSON(needs.plan-slices.outputs.periodic_codex_slices) }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
persist-credentials: false

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: paid-plan
path: ${{ runner.temp }}/paid-plan

- name: Let Codex's bubblewrap sandbox create user namespaces
run: |
if [ -e /proc/sys/kernel/apparmor_restrict_unprivileged_userns ]; then
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
fi

- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# The same steps as eval-slices (bun temp, deps, build, Codex login,
# slice run) inside the CI image. The container's home is a fresh
# runner-temp directory, so logs and captures upload from there.
- name: Run periodic Codex slice ${{ matrix.slice }}
shell: bash
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
EVAL_IMAGE: ${{ needs.build-image.outputs.image-tag }}
SLICE: ${{ matrix.slice }}
EVALS_JOBS: "2"
run: |
mkdir -p "$RUNNER_TEMP/eval-home" "$RUNNER_TEMP/paid-slice-results"
docker run --rm --user "$(id -u):$(id -g)" \
--security-opt seccomp=unconfined --security-opt apparmor=unconfined \
-e HOME=/home/runner -e ANTHROPIC_API_KEY -e OPENAI_API_KEY -e GEMINI_API_KEY -e SLICE -e EVALS_JOBS \
-e EVALS_RUN_ID -e EVALS_PROFILE -e EVALS_FRESH -e EVALS_CACHE_PURPOSE -e CI -e GITHUB_ACTIONS \
-e GITHUB_RUN_ID -e GITHUB_RUN_ATTEMPT -e GITHUB_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REPOSITORY \
-e GITHUB_EVENT_NAME -e GITHUB_BASE_REF -e GITHUB_HEAD_REF \
-e PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers -e EVALS_CONCURRENCY=2 -e GSTACK_EVAL_DIR=/tmp/paid-slice-results \
-v "$GITHUB_WORKSPACE:/workspace/gstack" -w /workspace/gstack \
-v "$RUNNER_TEMP/eval-home:/home/runner" \
-v "$RUNNER_TEMP/paid-plan:/tmp/paid-plan:ro" \
-v "$RUNNER_TEMP/paid-slice-results:/tmp/paid-slice-results" \
"$EVAL_IMAGE" bash -c '
set -euo pipefail
mkdir -p "$HOME/.cache/bun"
export BUN_INSTALL_CACHE_DIR="$HOME/.cache/bun" BUN_TMPDIR="$HOME/.cache/bun" TMPDIR="$HOME/.cache"
if diff -q /opt/node_modules_cache/.bun.lock bun.lock >/dev/null 2>&1; then
rm -rf node_modules && cp -r /opt/node_modules_cache node_modules
else
bun install --frozen-lockfile
fi
bun run build
codex="${GSTACK_CI_CODEX_BIN_DIR:?}/codex"
export CODEX_HOME="$HOME/.gstack-ci-codex"
mkdir -p "$CODEX_HOME"
if [ -n "${OPENAI_API_KEY:-}" ]; then
printenv OPENAI_API_KEY | "$codex" login --with-api-key
"$codex" login status >/dev/null 2>&1
else
echo "::warning::OPENAI_API_KEY is unavailable; Codex eval cases cannot authenticate and will fail."
fi
export GSTACK_CI_CODEX_HOME="$CODEX_HOME"
unset CODEX_HOME
EVALS_TIER=periodic bun run scripts/test-paid-shards.ts --tier periodic --plan /tmp/paid-plan/manifest.json --slice "$SLICE"
'

- name: Upload slice results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: paid-slice-${{ matrix.slice }}-a${{ github.run_attempt }}
path: ${{ runner.temp }}/paid-slice-results
retention-days: 90

- name: Upload native capture evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: native-captures-${{ env.EVALS_RUN_ID }}
include-hidden-files: true
path: |
${{ runner.temp }}/eval-home/.gstack/projects/*/e2e-runs
${{ runner.temp }}/eval-home/.gstack/projects/*/evals/qa-callers
${{ runner.temp }}/eval-home/.gstack-dev/e2e-runs
${{ runner.temp }}/eval-home/.gstack-dev/evals/qa-callers
if-no-files-found: ignore
retention-days: 90

- name: Upload shard logs
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: paid-logs-slice-${{ matrix.slice }}-a${{ github.run_attempt }}
include-hidden-files: true
path: ${{ runner.temp }}/eval-home/.cache/gstack-paid-shard-*.log
if-no-files-found: ignore
retention-days: 30

# Weekly EVALS_ALL gate-tier census: PR lanes are diff-billed, so without
# this the full gate census might never execute anywhere and the selector's
# blind spots rot invisibly. Census health, not selector correctness —
Expand Down Expand Up @@ -389,7 +524,7 @@ jobs:

report:
runs-on: ubicloud-standard-2
needs: [plan-slices, eval-slices, gate-census]
needs: [plan-slices, eval-slices, eval-codex-slices, gate-census]
# !cancelled(): the report must run (and FAIL) when an executor died — a
# missing slice artifact reading as green is the class this lane kills —
# but a cancelled run stops here.
Expand Down Expand Up @@ -521,7 +656,7 @@ jobs:
# issue (never a new issue per week) with the headline and failure block
# of both lanes, and close it on the next green run.
- name: Upsert tracking issue on failure
if: always() && (steps.reconcile.outputs.exit != '0' || steps.gate-reconcile.outputs.exit != '0' || steps.pass-rates.outputs.exit != '0' || needs.eval-slices.result != 'success' || needs.gate-census.result != 'success')
if: always() && (steps.reconcile.outputs.exit != '0' || steps.gate-reconcile.outputs.exit != '0' || steps.pass-rates.outputs.exit != '0' || needs.eval-slices.result != 'success' || !contains(fromJSON('["success","skipped"]'), needs.eval-codex-slices.result) || needs.gate-census.result != 'success')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REDISPATCH: ${{ steps.verdict.outputs.redispatch }}
Expand All @@ -536,7 +671,7 @@ jobs:
if [ -n "$REDISPATCH_OF" ]; then echo; echo "This run is the one INFRA/INCOMPLETE re-dispatch of run ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${REDISPATCH_OF}; both runs are reported."; fi
if [ "$REDISPATCH" = "true" ]; then echo; echo "Every red verdict is machine-classified INFRA/INCOMPLETE: re-dispatching once as a new run (EVAL_POLICY.infraRedispatch). This run stays red and reported."; fi
echo
echo "- periodic reconciliation exit: ${{ steps.reconcile.outputs.exit }} (slices job: ${{ needs.eval-slices.result }})"
echo "- periodic reconciliation exit: ${{ steps.reconcile.outputs.exit }} (slices job: ${{ needs.eval-slices.result }}, Codex slices job: ${{ needs.eval-codex-slices.result }})"
echo "- gate census reconciliation exit: ${{ steps.gate-reconcile.outputs.exit }} (census job: ${{ needs.gate-census.result }})"
echo "- pass-rate history gate exit: ${{ steps.pass-rates.outputs.exit }}"
echo
Expand Down Expand Up @@ -573,7 +708,7 @@ jobs:
fi

- name: Close the tracking issue on a green run
if: always() && steps.reconcile.outputs.exit == '0' && steps.gate-reconcile.outputs.exit == '0' && steps.pass-rates.outputs.exit == '0' && needs.eval-slices.result == 'success' && needs.gate-census.result == 'success'
if: always() && steps.reconcile.outputs.exit == '0' && steps.gate-reconcile.outputs.exit == '0' && steps.pass-rates.outputs.exit == '0' && needs.eval-slices.result == 'success' && contains(fromJSON('["success","skipped"]'), needs.eval-codex-slices.result) && needs.gate-census.result == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REDISPATCH_OF: ${{ inputs.redispatch_of }}
Expand All @@ -588,7 +723,7 @@ jobs:
fi

- name: Fail the workflow when reconciliation failed
if: always() && (steps.reconcile.outputs.exit != '0' || steps.gate-reconcile.outputs.exit != '0' || steps.pass-rates.outputs.exit != '0' || needs.eval-slices.result != 'success' || needs.gate-census.result != 'success')
if: always() && (steps.reconcile.outputs.exit != '0' || steps.gate-reconcile.outputs.exit != '0' || steps.pass-rates.outputs.exit != '0' || needs.eval-slices.result != 'success' || !contains(fromJSON('["success","skipped"]'), needs.eval-codex-slices.result) || needs.gate-census.result != 'success')
run: exit 1

# The one INFRA/INCOMPLETE re-dispatch (UC-E1). Its own job so the report
Expand Down
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,5 +289,7 @@ bun run skill:check # health dashboard for all skills
- Browse daemon HTTP routes are entries in `browse/src/routes/table.ts` (its header shows how to add one); never dispatch on `url.pathname` in `server.ts`.
- Both test lanes run shards through `scripts/lib/shard-engine.ts`; the free and paid runners hold lane policy only. PTY harness code lives in `test/helpers/pty/*` behind the `claude-pty-runner.ts` barrel.
- Outside-voice failure prose (auth, timeout, empty, fallback) comes only from `outsideVoiceFailurePolicy()` in `scripts/resolvers/outside-voice.ts`.
- Every env-var-host fence starts with the shared prelude from `scripts/resolvers/runtime-root.ts` (inserted by its post-render pass); never resolve gstack's root by hand in a template.
- Every Codex run's verdict goes through `lib/outside-review-result.ts`; its reason codes live in `lib/gate-outcomes.ts`, each with a `docs/troubleshooting.md` anchor.
- `test/module-size-ratchet.test.ts` keeps refactored owner modules at or under 800 lines (150 per function) and residual files from growing.
- The `claude` CLI binary resolves via `lib/claude-bin.ts` (re-exported from `browse/src/claude-bin.ts` for browse internals; `Bun.which()` + `GSTACK_CLAUDE_BIN` override). Set `GSTACK_CLAUDE_BIN=wsl` plus `GSTACK_CLAUDE_BIN_ARGS='["claude"]'` to run Claude through WSL on Windows.
12 changes: 11 additions & 1 deletion BROWSER.md
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ from `snapshot`, or `@c` refs from `snapshot -C`. Full table:
| `fill <sel> <val>` | Fill input |
| `select <sel> <val>` | Select dropdown option (value, label, or visible text) |
| `hover <sel>` | Hover element |
| `type <text>` | Type into focused element |
| `type [--selector <sel>] [--] <text>` | Type into the focused element, or into `<sel>` with `--selector`; put text that starts with `--` after `--`. Bare `type` hints when its first word looks like a selector |
| `press <key>` | Playwright keyboard key (case-sensitive: Enter, Tab, ArrowUp, Shift+Enter, Control+A, ...) |
| `scroll [sel\|@ref]` | Scroll element into view, or jump to page bottom if no selector |
| `viewport [<WxH>] [--scale <n>]` | Set viewport size + optional `deviceScaleFactor` 1-3 (retina screenshots) |
Expand Down Expand Up @@ -647,6 +647,8 @@ Storage stays intact by default. With explicit approval on a Chromium target, `-
| `status` | Daemon health + mode (headless / headed / cdp) |
| `stop` | Shut down daemon (succeeds even if the daemon already died — never boots one just to stop it; reaps a surviving recorded headless Chromium after identity checks) |
| `restart` | Restart daemon |
| `profiles [list]` | List the per-project headed Chromium profiles: size, last use, and which browser holds each |
| `profiles prune [--days N]` | Remove headed profiles idle for N days (default 30); never one a live browser holds |
| `connect` | Launch headed GStack Browser with Side Panel extension |
| `disconnect` | Close headed Chrome, return to headless |
| `focus [@ref]` | Bring headed Chrome to foreground (macOS); `@ref` also scrolls into view |
Expand Down Expand Up @@ -886,6 +888,14 @@ with your tabs and bookmarks stays untouched.
- **Demos** where you're sharing your screen
- **Pair-agent** sessions (the remote agent drives your local browser)

Headed browse keeps one Chromium profile per project, at
`<project>/.gstack/chromium-profile` (`CHROMIUM_PROFILE` still wins). The first
headed start copies your logins from `~/.gstack/chromium-profile` when no browser
is using it, and otherwise starts fresh and prints how to import. If a live
browser already holds the project's profile, browse names it and stops instead
of killing it. `browse profiles` lists the profiles; `browse profiles prune
--days 30` removes idle ones.

### Aside and third-party drives (v1.72.0.0+)

For third-party website moments (registering an API key, configuring a vendor
Expand Down
Loading
Loading