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: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ extension/.auth.json
.gstack-worktrees/
/tmp/
*.log
bun.lock
*.bun-build
.env
.env.local
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## [0.13.3.0] - 2026-03-28 — Lock It Down

Six fixes from community PRs and bug reports. The big one: your dependency tree is now pinned. Every `bun install` resolves the exact same versions, every time. No more floating ranges pulling fresh packages from npm on every setup.

### Fixed

- **Dependencies are now pinned.** `bun.lock` is committed and tracked. Every install resolves identical versions instead of floating `^` ranges from npm. Closes the supply-chain vector from #566.
- **`gstack-slug` no longer crashes outside git repos.** Falls back to directory name and "unknown" branch when there's no remote or HEAD. Every review skill that depends on slug detection now works in non-git contexts.
- **`./setup` no longer hangs in CI.** The skill-prefix prompt now auto-selects short names after 10 seconds. Conductor workspaces, Docker builds, and unattended installs proceed without human input.
- **Browse CLI works on Windows.** The server lockfile now uses `'wx'` string flag instead of numeric `fs.constants` that Bun compiled binaries don't handle on Windows.
- **`/ship` and `/review` find your design docs.** Plan search now checks `~/.gstack/projects/` first, where `/office-hours` writes design documents. Previously, plan validation silently skipped because it was looking in the wrong directories.
- **`/autoplan` dual-voice actually works.** Background subagents can't read files (Claude Code limitation), so the Claude voice was silently failing on every run. Now runs sequentially in foreground. Both voices complete before the consensus table.

### Added

- **Community PR guardrails in CLAUDE.md.** ETHOS.md, promotional material, and Garry's voice are explicitly protected from modification without user approval.

## [0.13.2.0] - 2026-03-28 — User Sovereignty

AI models now recommend instead of override. When Claude and Codex agree on a scope change, they present it to you instead of just doing it. Your direction is the default, not the models' consensus.
Expand Down
18 changes: 18 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,24 @@ Examples of good bisection:
When the user says "bisect commit" or "bisect and push," split staged/unstaged
changes into logical commits and push.

## Community PR guardrails

When reviewing or merging community PRs, **always AskUserQuestion** before accepting
any commit that:

1. **Touches ETHOS.md** — this file is Garry's personal builder philosophy. No edits
from external contributors or AI agents, period.
2. **Removes or softens promotional material** — YC references, founder perspective,
and product voice are intentional. PRs that frame these as "unnecessary" or
"too promotional" must be rejected.
3. **Changes Garry's voice** — the tone, humor, directness, and perspective in skill
templates, CHANGELOG, and docs are not generic. PRs that rewrite voice to be
more "neutral" or "professional" must be rejected.

Even if the agent strongly believes a change improves the project, these three
categories require explicit user approval via AskUserQuestion. No exceptions.
No auto-merging. No "I'll just clean this up."

## CHANGELOG + VERSION style

**VERSION and CHANGELOG are branch-scoped.** Every feature branch that ships gets its
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.13.2.0
0.13.3.0
22 changes: 12 additions & 10 deletions autoplan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,9 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION.
- All 10 review sections: run fully, auto-decide each issue, log every decision.
- Dual voices: always run BOTH Claude subagent AND Codex if available (P6).
Run them simultaneously (Agent tool for subagent, Bash for Codex).
Run them sequentially in foreground. First the Claude subagent (Agent tool,
foreground — do NOT use run_in_background), then Codex (Bash). Both must
complete before building the consensus table.

**Codex CEO voice** (via Bash):
```bash
Expand All @@ -674,7 +676,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
5. What's the competitive risk — could someone else solve this first/better?
For each finding: what's wrong, severity (critical/high/medium), and the fix."

**Error handling:** All non-blocking. Codex auth/timeout/empty → proceed with
**Error handling:** Both calls block in foreground. Codex auth/timeout/empty → proceed with
Claude subagent only, tagged `[single-model]`. If Claude subagent also fails →
"Outside voices unavailable — continuing with primary review."

Expand All @@ -696,10 +698,10 @@ Step 0 (0A-0F) — run each sub-step and produce:
- 0E: Temporal interrogation (HOUR 1 → HOUR 6+)
- 0F: Mode selection confirmation

Step 0.5 (Dual Voices): Run Claude subagent AND Codex simultaneously. Present
Codex output under CODEX SAYS (CEO — strategy challenge) header. Present subagent
output under CLAUDE SUBAGENT (CEO — strategic independence) header. Produce CEO
consensus table:
Step 0.5 (Dual Voices): Run Claude subagent (foreground Agent tool) first, then
Codex (Bash). Present Codex output under CODEX SAYS (CEO — strategy challenge)
header. Present subagent output under CLAUDE SUBAGENT (CEO — strategic independence)
header. Produce CEO consensus table:

```
CEO DUAL VOICES — CONSENSUS TABLE:
Expand Down Expand Up @@ -792,7 +794,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
For each finding: what's wrong, severity (critical/high/medium), and the fix."
NO prior-phase context — subagent must be truly independent.

Error handling: same as Phase 1 (non-blocking, degradation matrix applies).
Error handling: same as Phase 1 (both foreground/blocking, degradation matrix applies).

- Design choices: if codex disagrees with a design decision with valid UX reasoning
→ TASTE DECISION. Scope changes both models agree on → USER CHALLENGE.
Expand All @@ -801,7 +803,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.

1. Step 0 (Design Scope): Rate completeness 0-10. Check DESIGN.md. Map existing patterns.

2. Step 0.5 (Dual Voices): Run Claude subagent AND Codex simultaneously. Present under
2. Step 0.5 (Dual Voices): Run Claude subagent (foreground) first, then Codex. Present under
CODEX SAYS (design — UX challenge) and CLAUDE SUBAGENT (design — independent review)
headers. Produce design litmus scorecard (consensus table). Use the litmus scorecard
format from plan-design-review. Include CEO phase findings in Codex prompt ONLY
Expand Down Expand Up @@ -862,7 +864,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
For each finding: what's wrong, severity, and the fix."
NO prior-phase context — subagent must be truly independent.

Error handling: same as Phase 1 (non-blocking, degradation matrix applies).
Error handling: same as Phase 1 (both foreground/blocking, degradation matrix applies).

- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. Scope changes both models agree on → USER CHALLENGE.
- Evals: always include all relevant suites (P1)
Expand All @@ -874,7 +876,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
1. Step 0 (Scope Challenge): Read actual code referenced by the plan. Map each
sub-problem to existing code. Run the complexity check. Produce concrete findings.

2. Step 0.5 (Dual Voices): Run Claude subagent AND Codex simultaneously. Present
2. Step 0.5 (Dual Voices): Run Claude subagent (foreground) first, then Codex. Present
Codex output under CODEX SAYS (eng — architecture challenge) header. Present subagent
output under CLAUDE SUBAGENT (eng — independent review) header. Produce eng consensus
table:
Expand Down
22 changes: 12 additions & 10 deletions autoplan/SKILL.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION.
- All 10 review sections: run fully, auto-decide each issue, log every decision.
- Dual voices: always run BOTH Claude subagent AND Codex if available (P6).
Run them simultaneously (Agent tool for subagent, Bash for Codex).
Run them sequentially in foreground. First the Claude subagent (Agent tool,
foreground — do NOT use run_in_background), then Codex (Bash). Both must
complete before building the consensus table.

**Codex CEO voice** (via Bash):
```bash
Expand All @@ -262,7 +264,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
5. What's the competitive risk — could someone else solve this first/better?
For each finding: what's wrong, severity (critical/high/medium), and the fix."

**Error handling:** All non-blocking. Codex auth/timeout/empty → proceed with
**Error handling:** Both calls block in foreground. Codex auth/timeout/empty → proceed with
Claude subagent only, tagged `[single-model]`. If Claude subagent also fails →
"Outside voices unavailable — continuing with primary review."

Expand All @@ -284,10 +286,10 @@ Step 0 (0A-0F) — run each sub-step and produce:
- 0E: Temporal interrogation (HOUR 1 → HOUR 6+)
- 0F: Mode selection confirmation

Step 0.5 (Dual Voices): Run Claude subagent AND Codex simultaneously. Present
Codex output under CODEX SAYS (CEO — strategy challenge) header. Present subagent
output under CLAUDE SUBAGENT (CEO — strategic independence) header. Produce CEO
consensus table:
Step 0.5 (Dual Voices): Run Claude subagent (foreground Agent tool) first, then
Codex (Bash). Present Codex output under CODEX SAYS (CEO — strategy challenge)
header. Present subagent output under CLAUDE SUBAGENT (CEO — strategic independence)
header. Produce CEO consensus table:

```
CEO DUAL VOICES — CONSENSUS TABLE:
Expand Down Expand Up @@ -380,7 +382,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
For each finding: what's wrong, severity (critical/high/medium), and the fix."
NO prior-phase context — subagent must be truly independent.

Error handling: same as Phase 1 (non-blocking, degradation matrix applies).
Error handling: same as Phase 1 (both foreground/blocking, degradation matrix applies).

- Design choices: if codex disagrees with a design decision with valid UX reasoning
→ TASTE DECISION. Scope changes both models agree on → USER CHALLENGE.
Expand All @@ -389,7 +391,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.

1. Step 0 (Design Scope): Rate completeness 0-10. Check DESIGN.md. Map existing patterns.

2. Step 0.5 (Dual Voices): Run Claude subagent AND Codex simultaneously. Present under
2. Step 0.5 (Dual Voices): Run Claude subagent (foreground) first, then Codex. Present under
CODEX SAYS (design — UX challenge) and CLAUDE SUBAGENT (design — independent review)
headers. Produce design litmus scorecard (consensus table). Use the litmus scorecard
format from plan-design-review. Include CEO phase findings in Codex prompt ONLY
Expand Down Expand Up @@ -450,7 +452,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
For each finding: what's wrong, severity, and the fix."
NO prior-phase context — subagent must be truly independent.

Error handling: same as Phase 1 (non-blocking, degradation matrix applies).
Error handling: same as Phase 1 (both foreground/blocking, degradation matrix applies).

- Architecture choices: explicit over clever (P5). If codex disagrees with valid reason → TASTE DECISION. Scope changes both models agree on → USER CHALLENGE.
- Evals: always include all relevant suites (P1)
Expand All @@ -462,7 +464,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
1. Step 0 (Scope Challenge): Read actual code referenced by the plan. Map each
sub-problem to existing code. Run the complexity check. Produce concrete findings.

2. Step 0.5 (Dual Voices): Run Claude subagent AND Codex simultaneously. Present
2. Step 0.5 (Dual Voices): Run Claude subagent (foreground) first, then Codex. Present
Codex output under CODEX SAYS (eng — architecture challenge) header. Present subagent
output under CLAUDE SUBAGENT (eng — independent review) header. Produce eng consensus
table:
Expand Down
11 changes: 7 additions & 4 deletions bin/gstack-slug
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
# Security: output is sanitized to [a-zA-Z0-9._-] only, preventing
# shell injection when consumed via source or eval.
set -euo pipefail
RAW_SLUG=$(git remote get-url origin 2>/dev/null | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|;s|.*[:/]\([^/]*/[^/]*\)$|\1|' | tr '/' '-')
RAW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-')
RAW_SLUG=$(git remote get-url origin 2>/dev/null | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|;s|.*[:/]\([^/]*/[^/]*\)$|\1|' | tr '/' '-') || true
RAW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') || true
# Strip any characters that aren't alphanumeric, dot, hyphen, or underscore
SLUG=$(printf '%s' "$RAW_SLUG" | tr -cd 'a-zA-Z0-9._-')
BRANCH=$(printf '%s' "$RAW_BRANCH" | tr -cd 'a-zA-Z0-9._-')
SLUG=$(printf '%s' "${RAW_SLUG:-}" | tr -cd 'a-zA-Z0-9._-')
BRANCH=$(printf '%s' "${RAW_BRANCH:-}" | tr -cd 'a-zA-Z0-9._-')
# Fallback when git context is absent
SLUG="${SLUG:-$(basename "$PWD" | tr -cd 'a-zA-Z0-9._-')}"
BRANCH="${BRANCH:-unknown}"
echo "SLUG=$SLUG"
echo "BRANCH=$BRANCH"
5 changes: 3 additions & 2 deletions browse/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ async function startServer(extraEnv?: Record<string, string>): Promise<ServerSta
function acquireServerLock(): (() => void) | null {
const lockPath = `${config.stateFile}.lock`;
try {
// O_CREAT | O_EXCL — fails if file already exists (atomic check-and-create)
const fd = fs.openSync(lockPath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY);
// 'wx' — create exclusively, fails if file already exists (atomic check-and-create)
// Using string flag instead of numeric constants for Bun Windows compatibility
const fd = fs.openSync(lockPath, 'wx');
fs.writeSync(fd, `${process.pid}\n`);
fs.closeSync(fd);
return () => { try { fs.unlinkSync(lockPath); } catch {} };
Expand Down
Loading
Loading