Skip to content

Commit d8581a4

Browse files
Merge remote-tracking branch 'origin/main' into stevenbarragan/pin-chromium-launch-headed
* origin/main: (35 commits) v1.58.1.0 feat: hermetic local E2E + Conductor prose AskUserQuestion (garrytan#2004) v1.58.0.0 feat: diagram + multi-format document engine (mermaid, excalidraw, single-file HTML, DOCX) (garrytan#1990) v1.57.10.0 feat: Codex review default-on across review/ship/plan/docs (garrytan#1966) v1.57.9.0 feat: source-clean gbrain render (dev-setup --out-dir + machine-wide gbrain-refresh) (garrytan#1951) v1.57.8.0 feat: browse js/eval --out render-to-file (canonical Chromium for offline rendering) (garrytan#1929) v1.57.7.0 feat: GSTACK REVIEW REPORT always declares unresolved decisions (garrytan#1916) v1.57.6.0 fix wave: 8 community bugs (4 security guards failing open) (garrytan#1911) v1.57.5.0 feat: cross-session decision memory + gbrain dream-stage call graph (garrytan#1910) v1.57.4.0 refactor(ethos): rename Boil the Lake principle to Boil the Ocean (garrytan#1912) v1.57.3.0 fix(ship): always-loaded PR-title-version rule + fork-PR title-sync backstop (garrytan#1909) v1.57.2.0 feat: AskUserQuestion prose fallback when the tool fails at runtime (garrytan#1908) v1.57.0.0 feat: carve-guard system + carve cso/document-release/design-consultation (garrytan#1907) v1.56.1.0 fix(sync): staging-dir ownership guard + resume-correctness fixes (garrytan#1802) (garrytan#1856) v1.56.0.0 Token-reduction Phase B + AUQ paranoid safety net (garrytan#1849) v1.55.1.0 fix: telemetry consent accuracy + gstack-slug cache sanitization (garrytan#1848) v1.55.0.0 fix wave: gbrain data-loss guards + browser crash-loop + 6 more (garrytan#1808) fix(setup): add missing gen:skill-docs:user script (garrytan#1807) v1.54.0.0 feat: carve /ship into skeleton + on-demand sections (-59% always-loaded) (garrytan#1806) v1.53.1.0 fix: non-interactive-safe plan-tune hook install (flags + smart defaults) (garrytan#1805) v1.53.0.0 feat: smarter redaction — PII/secrets/legal guard across /spec, /ship, /cso, /document-* (garrytan#1797) ...
2 parents b54a00d + c7ae632 commit d8581a4

590 files changed

Lines changed: 95702 additions & 18354 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,9 @@ bin/* text eol=lf
3737
*.gif binary
3838
*.ico binary
3939
*.pdf binary
40+
41+
# The committed diagram-render bundle is hash-pinned (BUILD_INFO sha256);
42+
# a CRLF rewrite on Windows checkout would break the drift test and change
43+
# the content-addressed staged filename.
44+
lib/diagram-render/dist/*.html text eol=lf
45+
lib/diagram-render/dist/*.json text eol=lf

.github/workflows/evals.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ jobs:
162162
permissions:
163163
contents: read
164164
pull-requests: write
165+
# The comment upsert below calls the REST `/issues/{n}/comments` endpoints
166+
# (gh api ... issues/comments). With GITHUB_TOKEN those are gated by the
167+
# `issues` permission, not `pull-requests` — without it the GET returns 401
168+
# on every PR that produces eval artifacts (PRs with no artifacts exit
169+
# early and never hit it, which is why this stayed hidden). See #1802 CI fix.
170+
issues: write
165171
steps:
166172
- uses: actions/checkout@v4
167173
with:

.github/workflows/make-pdf-gate.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ on:
44
branches: [main]
55
paths:
66
- 'make-pdf/**'
7+
- 'lib/diagram-render/**'
8+
- 'test/diagram-render-drift.test.ts'
79
- 'browse/src/meta-commands.ts'
810
- 'browse/src/write-commands.ts'
911
- 'browse/src/commands.ts'
@@ -51,6 +53,15 @@ jobs:
5153
if: matrix.os == 'ubicloud-standard-8'
5254
run: sudo apt-get update && sudo apt-get install -y poppler-utils
5355

56+
# Install a color-emoji font BEFORE Chromium launches so the emoji render
57+
# gate has a fallback font. macOS ships Apple Color Emoji already.
58+
- name: Install color-emoji font (Ubuntu)
59+
if: matrix.os == 'ubicloud-standard-8'
60+
run: |
61+
sudo apt-get install -y fonts-noto-color-emoji
62+
fc-cache -f || true
63+
fc-match -f '%{family[0]}\t%{color}\n' ':lang=und-zsye:charset=1F600' || true
64+
5465
- name: Install Playwright Chromium
5566
run: bunx playwright install chromium
5667

@@ -72,9 +83,9 @@ jobs:
7283
which pdftotext && pdftotext -v 2>&1 | head -1 || true
7384
7485
- name: Run make-pdf unit tests
75-
run: bun test make-pdf/test/*.test.ts
86+
run: bun test make-pdf/test/*.test.ts test/diagram-render-drift.test.ts
7687

77-
- name: Run combined-features copy-paste gate (P0)
88+
- name: Run E2E gates (combined-features copy-paste + emoji render)
7889
env:
7990
BROWSE_BIN: ${{ github.workspace }}/browse/dist/browse
80-
run: bun test make-pdf/test/e2e/combined-gate.test.ts
91+
run: bun test make-pdf/test/e2e/

.github/workflows/pr-title-sync.yml

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
name: PR Title Sync
22

3+
# WHY pull_request_target (not pull_request): the default GITHUB_TOKEN is
4+
# READ-ONLY on fork PRs under `pull_request`, so the title-sync backstop could
5+
# never `gh pr edit` a fork/agent PR. `pull_request_target` runs in the base-repo
6+
# context with a write token, which fixes fork coverage.
7+
#
8+
# WHY this is SAFE (pull_request_target is the most dangerous trigger):
9+
# - We check out the BASE repo (no `ref:`), so the only code we execute is
10+
# trusted base-repo infra (bin/gstack-pr-title-rewrite.sh). We NEVER check
11+
# out or run PR-head/fork code.
12+
# - Every attacker-controlled PR field (title, head repo, head sha) arrives via
13+
# `env:` and is referenced as a shell-quoted "$VAR". We NEVER inline a
14+
# `${{ github.event.pull_request.* }}` expression inside the run: script
15+
# (that would execute a crafted title as shell).
16+
# - The PR-head VERSION is read as DATA via the API (raw media type), from the
17+
# head repo at the head sha — never by checking out the head.
18+
# test/pr-title-sync-workflow-safety.test.ts is the static tripwire for all of
19+
# the above and fails CI if any of it regresses.
20+
321
on:
4-
pull_request:
22+
pull_request_target:
523
types: [opened, synchronize, edited]
624
paths:
725
- 'VERSION'
@@ -19,25 +37,62 @@ jobs:
1937
pull-requests: write
2038
if: github.actor != 'github-actions[bot]'
2139
steps:
22-
- name: Checkout PR head
40+
# Base repo only — trusted infra (the rewrite helper). No PR-head checkout.
41+
- name: Checkout base repo (trusted)
2342
uses: actions/checkout@v4
2443
with:
2544
fetch-depth: 1
26-
ref: ${{ github.event.pull_request.head.sha }}
2745

2846
- name: Rewrite PR title to match VERSION
2947
env:
3048
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3149
PR_NUM: ${{ github.event.pull_request.number }}
50+
# Attacker-controlled on fork PRs — env-only, never inlined into run:.
3251
OLD_TITLE: ${{ github.event.pull_request.title }}
52+
BASE_REPO: ${{ github.repository }}
53+
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
54+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
3355
run: |
3456
set -euo pipefail
3557
chmod +x ./bin/gstack-pr-title-rewrite.sh
36-
VERSION=$(cat VERSION | tr -d '[:space:]')
37-
NEW_TITLE=$(./bin/gstack-pr-title-rewrite.sh "$VERSION" "$OLD_TITLE")
58+
59+
if [ "$HEAD_REPO" = "$BASE_REPO" ]; then IS_FORK=0; else IS_FORK=1; fi
60+
61+
# Read the PR-head VERSION as data (raw bytes), from the head repo at
62+
# the head sha. Guard the assignment itself: under `set -e` a bare
63+
# `VERSION=$(...)` would abort the step before any later [ -z ] check.
64+
if ! VERSION=$(gh api -H "Accept: application/vnd.github.raw" \
65+
"repos/$HEAD_REPO/contents/VERSION?ref=$HEAD_SHA" 2>/dev/null | tr -d '[:space:]'); then
66+
VERSION=""
67+
fi
68+
69+
if [ -z "$VERSION" ]; then
70+
# Same-repo read failure should never happen — fail loudly so we
71+
# notice. A fork miss (public-contents quirk, private fork) is a
72+
# convenience gap, not a gate — warn and skip so the check stays green.
73+
if [ "$IS_FORK" = "0" ]; then
74+
echo "::error::Could not read VERSION from same-repo PR head ($HEAD_SHA)."
75+
exit 1
76+
fi
77+
echo "::warning::Could not read VERSION from fork $HEAD_REPO ($HEAD_SHA); skipping title sync."
78+
exit 0
79+
fi
80+
81+
# The helper rejects a malformed VERSION (exit 2). Same policy: loud for
82+
# same-repo, soft for forks. Never echo the raw (attacker-controlled)
83+
# title — Actions still parses ::workflow-command:: from stdout.
84+
if ! NEW_TITLE=$(./bin/gstack-pr-title-rewrite.sh "$VERSION" "$OLD_TITLE"); then
85+
if [ "$IS_FORK" = "0" ]; then
86+
echo "::error::Could not compute title for VERSION '$VERSION' on PR #$PR_NUM."
87+
exit 1
88+
fi
89+
echo "::warning::Could not compute title for fork PR #$PR_NUM; skipping."
90+
exit 0
91+
fi
92+
3893
if [ "$NEW_TITLE" = "$OLD_TITLE" ]; then
39-
echo "Title already correct; no change."
94+
echo "PR #$PR_NUM title already correct; no change."
4095
exit 0
4196
fi
42-
echo "Rewriting: $OLD_TITLE -> $NEW_TITLE"
4397
gh pr edit "$PR_NUM" --title "$NEW_TITLE"
98+
echo "PR #$PR_NUM title synced to VERSION."

.github/workflows/windows-free-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ jobs:
116116
test/setup-windows-fallback.test.ts \
117117
test/build-script-shell-compat.test.ts \
118118
test/docs-config-keys.test.ts \
119+
test/brain-sync-windows-paths.test.ts \
119120
make-pdf/test/browseClient.test.ts \
120121
make-pdf/test/pdftotext.test.ts
121122
shell: bash

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ dist/
44
browse/dist/
55
design/dist/
66
make-pdf/dist/
7+
# diagram-render ships its built bundle (offline-at-install premise, eng-review D2)
8+
!lib/diagram-render/dist/
9+
!lib/diagram-render/dist/**
710
bin/gstack-global-discover*
811
.gstack/
912
.claude/skills/
13+
.claude/gstack-rendered/
1014
.claude/scheduled_tasks.lock
1115
.claude/*.lock
1216
.agents/
@@ -37,3 +41,6 @@ supabase/.temp/
3741

3842
# Throughput analysis — local-only, regenerate via scripts/garry-output-comparison.ts
3943
docs/throughput-*.json
44+
45+
# gbrain local source-staging dir (capability checks, source clones) — runtime artifact
46+
.sources/

AGENTS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Invoke them by name (e.g., `/office-hours`).
2121
| `/plan-tune` | Self-tune AskUserQuestion sensitivity per question. |
2222
| `/autoplan` | One command runs CEO → design → eng → DX review. |
2323
| `/design-consultation` | Build a complete design system from scratch. |
24+
| `/spec` | Turn vague intent into a precise, executable spec in five phases. Files a GitHub issue, optionally spawns a Claude Code agent in a fresh worktree, and lets `/ship` close the source issue on merge. |
2425

2526
### Implementation + review
2627

@@ -75,6 +76,25 @@ Invoke them by name (e.g., `/office-hours`).
7576
| `/setup-browser-cookies` | Import cookies from your real browser for authenticated testing. |
7677
| `/pair-agent` | Pair a remote AI agent (OpenClaw, Codex, etc.) with your browser. |
7778

79+
### iOS QA — drive real iPhones over USB or Tailscale (v1.43.0.0+)
80+
81+
| Skill | What it does |
82+
|-------|-------------|
83+
| `/ios-qa` | Live-device iOS QA via USB CoreDevice tunnel + embedded StateServer. Optionally exposes the device over Tailscale so remote agents can drive it. |
84+
| `/ios-fix` | Autonomous iOS bug fixer with regression snapshot capture. |
85+
| `/ios-design-review` | Designer's-eye QA on a real iPhone — 10-dimension Apple HIG rubric. |
86+
| `/ios-clean` | Convenience: strip DebugBridge + #if DEBUG wiring before a Release build. |
87+
| `/ios-sync` | Regenerate the iOS debug bridge against the latest upstream templates. |
88+
89+
Companion CLIs (run on the Mac that's plugged into the device):
90+
91+
| Command | What it does |
92+
|---------|-------------|
93+
| `gstack-ios-qa-daemon` | Mac-side broker. Loopback by default; `--tailnet` adds a Tailscale-facing listener with capability tiers and audit logging. |
94+
| `gstack-ios-qa-mint` | Owner-grant CLI for the tailnet allowlist (`grant`/`revoke`/`list`). |
95+
96+
End-to-end walkthrough: [docs/howto-ios-testing-with-gstack.md](docs/howto-ios-testing-with-gstack.md).
97+
7898
### Safety + scoping
7999

80100
| Skill | What it does |
@@ -84,6 +104,7 @@ Invoke them by name (e.g., `/office-hours`).
84104
| `/guard` | Activate both careful + freeze at once. |
85105
| `/unfreeze` | Remove directory edit restrictions. |
86106
| `/make-pdf` | Turn any markdown file into a publication-quality PDF. |
107+
| `/diagram` | English in, diagram out: mermaid source + editable .excalidraw + SVG/PNG, offline. |
87108

88109
## Build commands
89110

BROWSER.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ from `snapshot`, or `@c` refs from `snapshot -C`. Full table:
212212

213213
| Command | Description |
214214
|---------|-------------|
215-
| `js <expr>` | Run inline JavaScript expression in page context, return as string |
216-
| `eval <file>` | Run JS from a file (path under /tmp or cwd; same sandbox as `js`) |
215+
| `js <expr> [--out <file>] [--raw]` | Run inline JavaScript expression in page context, return as string. With `--out <file>` the result is written to disk instead of returned (a `data:*;base64,...` result is decoded to raw bytes unless `--raw`). `--out` makes the invocation a WRITE (needs `write` scope, never allowed over the tunnel). |
216+
| `eval <file> [--out <file>] [--raw]` | Run JS from a file (path under /tmp or cwd; same sandbox as `js`). `--out`/`--raw` behave as for `js`. |
217217
| `css <sel> <prop>` | Computed CSS value |
218218
| `attrs <sel\|@ref>` | Element attributes as JSON |
219219
| `is <prop> <sel\|@ref>` | State check: visible, hidden, enabled, disabled, checked, editable, focused |
@@ -317,6 +317,7 @@ from `snapshot`, or `@c` refs from `snapshot -C`. Full table:
317317
| `disconnect` | Close headed Chrome, return to headless |
318318
| `focus [@ref]` | Bring headed Chrome to foreground (macOS); `@ref` also scrolls into view |
319319
| `state save\|load <name>` | Save or load browser state (cookies + URLs) |
320+
| `memory [--json]` | Snapshot Bun heap + per-tab JS heap + Chromium process tree + bounded buffer sizes. Use `--json` for programmatic consumers; text mode renders sorted top-10 tabs with "and N more" tail. |
320321

321322
### Handoff
322323

0 commit comments

Comments
 (0)