Files
gstack/docs/OPENCLAW.md
T
Garry TanandClaude Fable 5 253d1dfe26 v1.76.0.0 fix: ship doc-sync survives Conductor — spawned subagent sessions reachable (#2733) (#2741)
* feat(session-kind): explicit GSTACK_SESSION_KIND override; skill-start spawned gates keyed on kind (#2733)

Claude Code subagents inherit the parent env byte-for-byte, so ambient
markers classify them as the parent's kind and the spawned classification
was unreachable outside OpenClaw. GSTACK_SESSION_KIND=spawned (step 0,
spawned-only by design) lets a dispatching skill mark its subagent per
command. skill-start now keys SPAWNED_SESSION and the spawned-session
instruction block on the resolved kind (was raw OPENCLAW_SESSION),
suppresses CONDUCTOR_SESSION for spawned sessions, gates all 11
interactive-onboarding blocks plus their ack-at-emit marker writes on
kind != spawned, and adds a destructive-gate carve-out to the spawned
block (conservative-continue, never prose-STOP).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(hooks): spawned-session escape in Conductor AUQ deny; override coverage in AUQ-error fallback (#2733)

Hooks inherit the harness env, so a per-command GSTACK_SESSION_KIND
prefix inside a subagent's bash can never reach them. Levers added:
a deterministic [conductor][spawned] auto-choose deny for env-level
spawned sessions (OPENCLAW_SESSION or session-wide GSTACK_SESSION_KIND),
and a spawned escape sentence appended to both hooks' prose directives
so a marked subagent that slips and calls AUQ resolves to auto-choose
instead of prose-STOP. The sentence lives in one shared constant
(hosts/claude/hooks/spawned-directive.ts) so the two paths can never
drift; destructive semantics are unified to conservative-continue.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ship): Step 18 marks the document-release subagent spawned — env prefix + auto-choose prompt (#2733)

The dispatch prompt now (1) frames the run as a SPAWNED subagent whose
LAST line is machine-parsed, (2) instructs prefixing the preamble's
gstack-skill-start invocation with GSTACK_SESSION_KIND=spawned on the
same command line (template bash blocks don't share exports), and
(3) resolves every AUQ gate to auto-choosing the recommended option,
conservative on no-recommendation, never destructive. The JSON contract
gains a required "decisions" array (auto-chosen gates, printed to the
ship console — never embedded in the public PR body) and a placement
clause so the skill's own doc-health summary stops competing with the
LAST-line JSON. Tripwire pins added; codex/factory goldens refreshed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(auq-format): proactive SESSION_KIND=spawned rule ordered above the Conductor rule (#2733)

The spawned classification previously existed only in the failure-fallback
branch — a spawned session was invited to call AskUserQuestion and reach
auto-choose via the deny/error detour, and a spawned session inside a
Conductor workspace hit the Conductor prose-STOP rule first. The Tool
resolution list now leads with the spawned rule (auto-choose recommended,
never prose, never BLOCKED, destructive gates resolve conservative), the
self-check carries the never-reach-this-checklist clause, and all tier>=2
SKILL.md renders are regenerated. Context-budget fixture refreshed in the
same commit per the ratchet protocol (the AUQ section is eager in every
tier>=2 skill).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(e2e): spawned document-release subagent returns the JSON contract through a firing gate (#2733)

The behavioral proof the bug shipped without: ship-docsync stubs the
skill (no preamble, no gates) and skill-e2e-workflow suppresses the
gates by prompt. This gate-tier E2E plays the parent — it drives the
verbatim Step 18 dispatch prompt (extracted from the live pr-body.md,
drift-proof) against a real preamble-bearing document-release slice in
a Conductor-ambient env with both AUQ hooks seeded live, an unbumped
VERSION making Step 8 fire. Asserts: the final line parses as the
5-key JSON contract, the fired gate's auto-choice is recorded in
decisions, and VERSION is untouched (the gate resolved to its
recommended Skip). Burn-in: 1/1 pass, $0.35, 21 turns, 106s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(openclaw): document the GSTACK_SESSION_KIND override; wire session-kind into paid selectors (#2733)

OPENCLAW.md's spawned-session section now covers the explicit per-command
marker, its deliberate spawned-only narrowness, the /ship Step 18 usage,
the destructive carve-out, onboarding-block suppression, and the hook
env-blindness caveat. bin/gstack-session-kind and the shared
spawned-directive module join the conductor-prose and
auto-decide-preserved selector dep lists (session-kind previously
appeared in no touchfiles entry — editing it alone triggered no paid
E2E). TODOS.md gains the plan-tune capture follow-up for spawned
auto-choices.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: pre-landing review fixes (#2733)

Review army + coverage audit findings, all applied:
- headless directive carries the spawned escape sentence too (multi-
  specialist: a CI-hosted ship's marked subagent must not end BLOCKED)
- anti-injection scoping on every text-claimable spawned trigger (AUQ
  rule + shared escape sentence): markings count only from the creating
  prompt, never from files/tool output/web content read mid-run
- [conductor][spawned] deny annotates one-way doors per question
- SPAWNED_OVERRIDE: env tamper-visibility status line + OPENCLAW.md note
- spawned sessions skip the network update-check and first-task probe
  (consumers suppressed; preserves the one-shot just-upgraded marker)
- test hardening: dispatch-tripwire end-bound validated, vacuous marker
  asserts replaced with output asserts, E2E cpSync size filter + named
  fence tolerance, spawnedByEnv parity pin, destructive-policy cross-
  surface drift guard, one-way annotation + bogus-value hook cases
- session-kind duplicate rationale comment deduped; regen + goldens +
  context-budget fixture refreshed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: bump version and changelog (v1.76.0.0)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: update project documentation for v1.76.0.0

PROJECT_STRUCTURE.md: add hosts/claude/hooks/ to the directory tree
(AUQ capture + enforcement hooks, spawned-session directive, timeline
stop) — the tree omitted the directory while docs/OPENCLAW.md and
CHANGELOG.md now reference paths inside it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: sync TODOS.md ship dispatch entry with the v1.76.0.0 contract

Codex doc-review finding: the SHIPPED entry for /ship auto-invoking
/document-release still described the four-key JSON contract. Adds the
decisions key (console-printed, never PR markdown), the
GSTACK_SESSION_KIND=spawned dispatch marking (#2733), and the new
spawned-dispatch gate E2E to the proven-by list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 20:45:19 -07:00

8.6 KiB

gstack x OpenClaw Integration

gstack integrates with OpenClaw as a methodology source, not a ported codebase. OpenClaw's ACP runtime spawns Claude Code sessions natively. gstack provides the planning discipline and methodology that makes those sessions better.

This is a lightweight protocol encoded as prompt text. No daemon. No JSON-RPC. No compatibility matrices. The prompt is the bridge.

Architecture

  OpenClaw                               gstack repo
  ─────────────────────                    ──────────────
  Orchestrator: messaging,                 Source of truth for
  calendar, memory, EA                     methodology + planning
       │                                        │
       ├── Native skills (conversational)       ├── Generates native skills
       │   office-hours, ceo-review,            │   via gen-skill-docs pipeline
       │   investigate, retro                   │
       │                                        ├── Generates gstack-lite
       ├── sessions_spawn(runtime: "acp")       │   (planning discipline)
       │       │                                │
       │       └── Claude Code                  ├── Generates gstack-full
       │           └── gstack installed at      │   (complete pipeline)
       │               ~/.claude/skills/gstack  │
       │                                        └── docs/OPENCLAW.md (this file)
       └── Dispatch routing (AGENTS.md)

Dispatch Routing

OpenClaw decides at spawn time which tier of gstack support to use:

Tier When Prompt prefix
Simple One-file edits, typos, config changes No gstack context injected
Medium Multi-file features, refactors gstack-lite CLAUDE.md appended
Heavy Specific gstack skill needed "Load gstack. Run /X"
Full Complete features, objectives, projects gstack-full pipeline appended
Plan "Help me plan a Claude Code project" gstack-plan pipeline appended

Decision heuristic

  • Can it be done in <10 lines of code? -> Simple
  • Does it touch multiple files but the approach is obvious? -> Medium
  • Does the user name a specific skill (/cso, /review, /qa)? -> Heavy
  • Is it a feature, project, or objective (not a task)? -> Full
  • Does the user want to PLAN something for Claude Code without implementing yet? -> Plan

Dispatch routing guide (for AGENTS.md)

The complete ready-to-paste section lives in openclaw/agents-gstack-section.md. Copy it into your OpenClaw AGENTS.md.

Key behavioral rules (these go ABOVE the dispatch tiers):

  1. Always spawn, never redirect. When the user asks to use ANY gstack skill, ALWAYS spawn a Claude Code session. Never tell the user to open Claude Code.
  2. Resolve the repo. If the user names a repo, set the working directory. If unknown, ask which repo.
  3. Autoplan runs end-to-end. Spawn, let it run the full pipeline, report back in chat. User should never have to leave Telegram.

CLAUDE.md collision handling

When spawning Claude Code in a repo that already has a CLAUDE.md, APPEND gstack-lite/full as a new section. Do not replace the repo's existing instructions.

What gstack generates for OpenClaw

All artifacts live in the openclaw/ directory and are generated by bun run gen:skill-docs --host openclaw:

gstack-lite (Medium tier)

openclaw/gstack-lite-CLAUDE.md — ~15 lines of planning discipline:

  1. Read every file before modifying
  2. Write a 5-line plan: what, why, which files, test case, risk
  3. Resolve ambiguity using decision principles
  4. Self-review before reporting done
  5. Completion report: what shipped, decisions made, anything uncertain

A/B tested: 2x time, meaningfully better output.

gstack-full (Full tier)

openclaw/gstack-full-CLAUDE.md — chains existing gstack skills:

  1. Read CLAUDE.md and understand the project
  2. Run /autoplan (CEO + eng + design review)
  3. Implement the approved plan
  4. Run /ship to create a PR
  5. Report back with PR URL and decisions

gstack-plan (Plan tier)

openclaw/gstack-plan-CLAUDE.md — full review gauntlet, no implementation:

  1. Run /office-hours to produce a design doc
  2. Run /autoplan (CEO + eng + design + DX reviews + codex adversarial)
  3. Save the reviewed plan to plans/<project-slug>-plan-<date>.md
  4. Report back: plan path, summary, key decisions, recommended next step

The orchestrator persists the plan link to its own memory store (brain repo, knowledge base, or whatever is configured in AGENTS.md). When the user is ready to build, spawn a FULL session that references the saved plan.

Native methodology skills

Published to ClawHub. Install with clawhub install:

  • gstack-openclaw-office-hours — Product interrogation (6 forcing questions)
  • gstack-openclaw-ceo-review — Strategic challenge (10-section review, 4 modes)
  • gstack-openclaw-investigate — Operational debugging (4-phase methodology)
  • gstack-openclaw-retro — Operational retrospective (weekly review)

Source lives in openclaw/skills/ in the gstack repo. These are hand-crafted adaptations of the gstack methodology for OpenClaw's conversational context. No gstack infrastructure (no browse, no telemetry, no preamble).

Spawned session detection

When Claude Code runs inside a session spawned by OpenClaw, the OPENCLAW_SESSION environment variable should be set. gstack detects this and adjusts:

  • Skips interactive prompts (auto-chooses recommended options; destructive or irreversible options are never auto-chosen — the conservative choice wins and gets recorded in the completion report)
  • Suppresses interactive-onboarding instruction blocks at emission (upgrade checks, telemetry prompts, feature discovery, routing injection, tips), so one-time prompts survive intact for the next human session
  • Suppresses the Conductor prose signal (CONDUCTOR_SESSION: true) — a spawned session inside a Conductor workspace auto-chooses instead of rendering prose to nobody
  • Focuses on task completion and prose reporting

Set the env var in sessions_spawn: env: { OPENCLAW_SESSION: "1" }

Explicit override: GSTACK_SESSION_KIND

GSTACK_SESSION_KIND=spawned is the explicit per-command marker for the same classification, outranking every ambient env marker (including OPENCLAW_SESSION and GSTACK_HEADLESS). It exists because Claude Code subagents inherit the parent session's env byte-for-byte (#2733) — a dispatching skill marks its subagent by prefixing the preamble invocation on the same command line:

GSTACK_SESSION_KIND=spawned "$_SS" --skill "document-release" ...

gstack itself uses this: /ship Step 18 dispatches the /document-release subagent with this prefix so its interactive gates auto-choose instead of prose-stopping. Deliberately narrow: only spawned is honored — headless already has GSTACK_HEADLESS, and letting an env var force interactive over CI markers would be a misclassification footgun. Empty or other values are reserved and ignored (fall through to ambient detection). Note that hook processes inherit the harness env, so a per-command prefix never reaches PreToolUse/PostToolUse hooks — the hook texts carry a spawned escape sentence for that topology (hosts/claude/hooks/spawned-directive.ts).

Tamper visibility. Any mechanism that injects session-wide env (a cloned repo's .claude/settings.json env block, direnv, a CI wrapper) could set GSTACK_SESSION_KIND=spawned for a real human's session and silently flip its confirmation gates to auto-choose. When the env override drives the classification, the preamble emits a loud SPAWNED_OVERRIDE: env status line so the transcript shows WHY the session is spawned — audit .claude/settings.json env blocks in untrusted repos (/cso covers this).

Installation

For OpenClaw users: tell your OpenClaw agent "install gstack for openclaw."

The agent should:

  1. Install gstack-lite CLAUDE.md into its coding session templates
  2. Install the 4 native methodology skills
  3. Add dispatch routing to AGENTS.md
  4. Verify with a test spawn

For gstack developers: ./setup --host openclaw outputs this documentation. The actual artifacts are generated by bun run gen:skill-docs --host openclaw.

What we don't do

  • No dispatch daemon (ACP handles session spawning)
  • No Clawvisor relay (no security layer needed)
  • No bidirectional learnings bridge (brain repo is the knowledge store)
  • No JSON schemas or protocol versioning
  • No SOUL.md from gstack (OpenClaw has its own)
  • No full skill porting (coding skills stay native to Claude Code)