diff --git a/CHANGELOG.md b/CHANGELOG.md index a2da8817b..ec881da50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [1.91.158.0] - 2026-10-19 + +**`gstack-config set plan_mode_preamble off` leaves the plan-mode preamble out of every installed skill, for people who never use plan mode.** The "Plan Mode Safe Operations" and "Skill Invocation During Plan Mode" sections add about 1.6 KB to each of 50 Claude skills. With the key off, the next `./setup` renders every host's skills with `gen-skill-docs --plan-mode=off`, and the default Claude install serves that render instead of the committed files. The default is on, and with it on every render and the committed SKILL.md files are byte-for-byte unchanged. + +### Added +- **`gen-skill-docs --plan-mode=off`** drops the two sections at generation time. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" keep their marker. Hosts whose capabilities declare no plan mode already render the sections empty, so in practice the flag matters for Claude, Copilot and OpenCode. Fixes #3168. From #3213 by @xingzihai, finished with the config wiring. +- **The `plan_mode_preamble` config key** (`on` | `off`, default `on`). It is a closed domain like `explain_level`: an unknown value warns and stores `on`. Setting it outside `./setup` says it applies on the next setup run and prints the `./setup --refresh-registered` command that applies it now. +- **Every installed render carries the choice:** all 16 `gen:skill-docs` call sites in `setup`, the Claude render helper, `gstack-config gbrain-refresh`, and the router that `gstack-relink` re-renders in place (as it already does for `disabled_skills`). When setup has to build, `scripts/build.sh` renders Factory, OpenCode, Cursor, Copilot and Antigravity without the flag, so with the key off setup renders those hosts again afterwards. +- **The default Claude install gets a render when the key is off.** Without a working gbrain (absent, or the detector failed), `gstack_claude_render_action` returns `plain` instead of serving the committed files; with gbrain the brain-aware render already runs and now carries the flag too. The activation record (`~/.gstack/render/claude.overlay`) gains `plan_mode=off`. Turning the key back on removes that render on the next setup when gbrain is absent or its detector fails (a failed detector otherwise keeps a render), and re-renders the brain-aware render with the sections when gbrain is present. A failed render with the key off keeps the previous render. Records written with the key on are unchanged. + +### Fixed +- **`gstack-relink` refreshes the `_gstack-command` router alias after it re-renders the router.** It used to copy the router before the re-render, so the alias kept the previous router (with `disabled_skills`, the full skill list) until the next relink. + +### Changed +- **Gate integrity:** new tests `test/plan-mode-off-build.test.ts` (from #3213, unchanged), `test/plan-mode-off-generation.test.ts`, `test/plan-mode-preamble-config.test.ts`, `test/plan-mode-preamble-render.test.ts` and `test/plan-mode-preamble-setup.test.ts`. No existing test was edited, and no threshold, trial count, case kind or judge changed. + ## [1.91.157.0] - 2026-10-19 **Claude SKILL.md files no longer carry a "When to invoke" body section, which saves about 20 KB across 56 skills.** Claude Code reads a skill's body only after the skill is invoked, so routing prose there never routed anything. Routing still comes from the catalog description and the CLAUDE.md routing block, and voice triggers move into the root router's routing block. From #3129 by @thanhnguyentung95. diff --git a/README.md b/README.md index c2037045c..e44cf94ae 100644 --- a/README.md +++ b/README.md @@ -797,6 +797,8 @@ types into that element; bare `browse type ` types into whatever has focus **Don't use some skills?** `gstack-config set disabled_skills make-pdf,pair-agent` stops registering them on every host, so their descriptions stop loading into each session. Claude Code updates right away; other hosts on their next `./setup --host ` or `/gstack-upgrade`. Their files stay installed, so a skill that calls a disabled one still works (you get a warning). Typos are rejected with the closest skill name, `gstack-upgrade` can't be disabled, and `gstack-config set disabled_skills ""` re-enables everything. +**Never use plan mode?** `gstack-config set plan_mode_preamble off` leaves the "Plan Mode Safe Operations" and "Skill Invocation During Plan Mode" sections (about 1.6 KB per skill) out of every installed skill on the next `./setup` run; the command prints the exact `./setup --refresh-registered` line that applies it. Claude Code then serves a render under `~/.gstack/render/claude` instead of the committed files. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" keep their marker. `gstack-config set plan_mode_preamble on` (the default) and another `./setup` bring the sections back. It matters for Claude Code, Copilot and OpenCode: hosts without plan mode (Codex and others) never carry these sections. + **Want namespaced commands?** `cd ~/.claude/skills/gstack && ./setup --prefix` — switches from `/qa` to `/gstack-qa`. Useful if you run other skill packs alongside gstack. **Codex says "Skipped loading skill(s) due to invalid SKILL.md"?** Your Codex skill descriptions are stale. `${CODEX_HOME:-~/.codex}/skills/gstack` is a runtime directory, not the checkout: `./setup --status` shows the Codex row's source checkout. Fix: `cd && git pull && ./setup --host codex` — for a repo-local install, run it from inside the project. diff --git a/VERSION b/VERSION index 6c4ab49a6..087197d9d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.91.157.0 +1.91.158.0 diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md index bcc293a95..f19ab312a 100644 --- a/agents-digest/gstack-AGENTS.md +++ b/agents-digest/gstack-AGENTS.md @@ -1,4 +1,4 @@ -# gstack digest v1.91.157.0 — regenerate/re-copy after upgrading gstack +# gstack digest v1.91.158.0 — regenerate/re-copy after upgrading gstack Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed for agent hosts without a full skill install. The full skills add workflows, diff --git a/bin/gstack-config b/bin/gstack-config index 8e33aeb9a..163b1b4dd 100755 --- a/bin/gstack-config +++ b/bin/gstack-config @@ -94,6 +94,13 @@ CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on ne # # (for power users who know the terms) # # Unknown values default to "default" with a warning. # # See docs/designs/PLAN_TUNING_V1.md for rationale. +# plan_mode_preamble: on # on = every skill carries the plan-mode preamble +# # off = rendered skills omit the "Plan Mode Safe +# # Operations" and "Skill Invocation During +# # Plan Mode" sections (~1.8 KB each), for +# # users who never enter plan mode +# # Applies on the next ./setup run. Unknown values +# # default to "on" with a warning. # # ─── Artifacts sync (renamed from gbrain_sync_mode in v1.27.0.0) ───── # artifacts_sync_mode: off # off | artifacts-only | full @@ -279,6 +286,7 @@ lookup_default() { update_check) echo "true" ;; skill_prefix) echo "false" ;; explain_level) echo "default" ;; + plan_mode_preamble) echo "on" ;; # on | off — off drops the plan-mode preamble on the next ./setup (#3168) codex_reviews) echo "enabled" ;; design_detector) echo "auto" ;; # auto | off — impeccable engine pre-pass in the design skills design_detector_install_prompted) echo "false" ;; # true once the user answered the one-time engine install offer with "never ask again" @@ -734,6 +742,10 @@ $_gstack_legacy_root" echo "Warning: explain_level '$VALUE' not recognized. Valid values: default, terse. Using default." >&2 VALUE="default" fi + if [ "$KEY" = "plan_mode_preamble" ] && [ "$VALUE" != "on" ] && [ "$VALUE" != "off" ]; then + echo "Warning: plan_mode_preamble '$VALUE' not recognized. Valid values: on, off. Using on." >&2 + VALUE="on" + fi if [ "$KEY" = "artifacts_sync_mode" ] && [ "$VALUE" != "off" ] && [ "$VALUE" != "artifacts-only" ] && [ "$VALUE" != "full" ]; then echo "Warning: artifacts_sync_mode '$VALUE' not recognized. Valid values: off, artifacts-only, full. Using off." >&2 VALUE="off" @@ -985,6 +997,11 @@ $_gstack_legacy_root" gstack_install_registry_rows | awk -F '\t' '$1 != "claude" { print " apply to " $1 " (" $4 "): cd " $6 " && ./setup --host " $1 }' ) fi fi + # Installed skills are rendered by ./setup, so the preamble choice lands + # on its next run (every registered host). + if [ "$KEY" = "plan_mode_preamble" ] && [ -z "${GSTACK_SETUP_RUNNING:-}" ]; then + printf 'gstack-config: plan_mode_preamble=%s applies on the next ./setup run. Apply now: cd %q && ./setup --refresh-registered\n' "$VALUE" "$(cd "$(dirname "$0")/.." && pwd)" + fi ;; unset) KEY="${2:?Usage: gstack-config unset }" @@ -1009,7 +1026,7 @@ $_gstack_legacy_root" echo "# ─── Active values (including defaults for unset keys) ───" report_root_disagreement for KEY in proactive routing_declined telemetry auto_upgrade update_check \ - skill_prefix explain_level \ + skill_prefix explain_level plan_mode_preamble \ codex_reviews gstack_contributor skip_eng_review workspace_root \ artifacts_sync_mode artifacts_sync_mode_prompted artifacts_sync_removals plan_tune_hooks \ timeline_stop_hook design_detector design_detector_install_prompted memorable_recall \ @@ -1034,7 +1051,7 @@ $_gstack_legacy_root" defaults) echo "# gstack-config defaults" for KEY in proactive routing_declined telemetry auto_upgrade update_check \ - skill_prefix explain_level \ + skill_prefix explain_level plan_mode_preamble \ codex_reviews gstack_contributor skip_eng_review workspace_root \ artifacts_sync_mode artifacts_sync_mode_prompted artifacts_sync_removals plan_tune_hooks \ timeline_stop_hook design_detector design_detector_install_prompted memorable_recall \ @@ -1065,6 +1082,8 @@ $_gstack_legacy_root" # generated SKILL.md files match your installation state. SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" . "$SCRIPT_DIR/gstack-render-claude.sh" 2>/dev/null || { echo "$0: $SCRIPT_DIR/gstack-render-claude.sh is missing. fix: reinstall with ./setup or /gstack-upgrade" >&2; exit 1; } + _PLAN_MODE_ARG="" + [ "$("$0" get plan_mode_preamble 2>/dev/null || true)" != off ] || _PLAN_MODE_ARG="--plan-mode=off" DETECT_BIN="$SCRIPT_DIR/gstack-gbrain-detect" DETECTION_FILE="$STATE_DIR/gbrain-detection.json" mkdir -p "$STATE_DIR" @@ -1133,7 +1152,7 @@ $_gstack_legacy_root" gstack_claude_overlay "$INSTALL_DIR" "$0" RENDER_TMP="$RENDER_DIR.tmp.$$" rm -rf "$RENDER_TMP" - if ( cd "$INSTALL_DIR" && bun run gen:skill-docs:user --host claude --out-dir "$RENDER_TMP" --link-root "$RENDER_DIR" --model "$_GSTACK_OVERLAY" >/dev/null 2>&1 ); then + if ( cd "$INSTALL_DIR" && bun run gen:skill-docs:user --host claude --out-dir "$RENDER_TMP" --link-root "$RENDER_DIR" --model "$_GSTACK_OVERLAY" ${_PLAN_MODE_ARG:+"$_PLAN_MODE_ARG"} >/dev/null 2>&1 ); then gstack_render_lock "$RENDER_DIR" _swap_in_render "$RENDER_DIR" "$RENDER_TMP" gstack_render_unlock "$RENDER_DIR" @@ -1159,7 +1178,7 @@ $_gstack_legacy_root" # brain blocks, so removing gbrain keeps the chosen overlay. INSTALL_DIR="$HOME/.claude/skills/gstack" RENDER_DIR="${GSTACK_USER_RENDER_DIR:-$STATE_DIR/render/claude}" - if { [ -d "$RENDER_DIR" ] || "$0" has claude_overlay_model; } \ + if { [ -d "$RENDER_DIR" ] || "$0" has claude_overlay_model || [ -n "$_PLAN_MODE_ARG" ]; } \ && [ -d "$INSTALL_DIR" ] && [ ! -L "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/VERSION" ] && [ -f "$INSTALL_DIR/package.json" ]; then if ! command -v bun >/dev/null 2>&1; then echo "Skip: bun not on PATH — the Claude render at $RENDER_DIR was not refreshed. Install bun, then re-run 'gstack-config gbrain-refresh'." diff --git a/bin/gstack-relink b/bin/gstack-relink index 40ff055dc..4bc76b05b 100755 --- a/bin/gstack-relink +++ b/bin/gstack-relink @@ -461,19 +461,26 @@ done # (in place, like gstack-patch-names). Clearing the list restores the committed # bytes. Only a generated router is rewritten, and only from a checkout that # carries the generator; a failed render keeps the current router. +# plan_mode_preamble=off (#3168) renders it without the plan-mode preamble the +# same way, and turning it back on restores the committed bytes. _ROUTER="$INSTALL_DIR/SKILL.md" _GEN_SRC="$(cd "$SCRIPT_DIR/.." && pwd)" -if { [ "$DISABLED" != " " ] || grep -q '^Disabled on this install' "$_ROUTER" 2>/dev/null; } \ +_PLAN_MODE_ARG="" +[ "$("$GSTACK_CONFIG" get plan_mode_preamble 2>/dev/null || true)" != off ] || _PLAN_MODE_ARG="--plan-mode=off" +if { [ "$DISABLED" != " " ] || grep -q '^Disabled on this install' "$_ROUTER" 2>/dev/null \ + || [ -n "$_PLAN_MODE_ARG" ] \ + || { grep -q 'PLAN MODE EXCEPTION' "$_ROUTER" 2>/dev/null && ! grep -q '^## Plan Mode Safe Operations' "$_ROUTER" 2>/dev/null; }; } \ && grep -q '