mirror of
https://github.com/garrytan/gstack.git
synced 2026-08-07 06:48:37 +02:00
feat: continuous checkpoint mode with non-destructive WIP squash
Adds opt-in auto-commit during long sessions so work survives Claude Code crashes, Conductor workspace handoffs, and context switches. Local-only by default — pushing requires explicit opt-in. Codex review caught multiple landmines that would have shipped: 1. checkpoint_push=true default would push WIP commits to shared branches, trigger CI/deploys, expose secrets. Now default false. 2. Plan's original /ship squash (git reset --soft to merge base) was destructive — uncommitted ALL branch commits, not just WIP, and caused non-fast-forward pushes. Redesigned: rebase --autosquash scoped to WIP commits only, with explicit fallback for WIP-only branches and STOP-and-ask for conflicts. 3. gstack-config get returned empty for missing keys with exit 0, ignoring the annotated defaults in the header comments. Fixed: get now falls back to a lookup_default() table that is the canonical source for defaults. 4. Telemetry default mismatched: header said 'anonymous' but runtime treated empty as 'off'. Aligned: default is 'off' everywhere. 5. /checkpoint resume only read markdown checkpoint files, not the WIP commit [gstack-context] bodies the plan referenced. Wired up parsing of [gstack-context] blocks from WIP commits as a second recovery trail alongside the markdown checkpoints. Changes: - bin/gstack-config: add checkpoint_mode (default explicit) and checkpoint_push (default false) to CONFIG_HEADER. Add lookup_default() as canonical default source. get() falls back to defaults when key absent. list now shows value + source (set/default). New 'defaults' subcommand to inspect the table. - scripts/resolvers/preamble.ts: preamble bash reads _CHECKPOINT_MODE and _CHECKPOINT_PUSH, prints CHECKPOINT_MODE: and CHECKPOINT_PUSH: so the mode is visible. New generateContinuousCheckpoint() section in T2+ tier describes WIP commit format with [gstack-context] body and the rules (never git add -A, never commit broken tests, push only if opted in). Example deliberately shows a clean-state context so it doesn't contradict the rules. - ship/SKILL.md.tmpl: new Step 5.75 WIP Commit Squash. Detects WIP count, exports [gstack-context] blocks before squash (as backup), uses rebase --autosquash for mixed branches and soft-reset only when VERIFIED WIP-only. Explicit anti-footgun rules against blind soft- reset. Aborts with BLOCKED status on conflict instead of destroying non-WIP commits. - checkpoint/SKILL.md.tmpl: new Step 1.5 to parse [gstack-context] blocks from WIP commits via git log --grep="^WIP:". Merges with markdown checkpoint for fuller session recovery. - Golden ship fixtures regenerated (ship is T4, preamble change shows up). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
6c8cf6774f
commit
fe34349966
@@ -89,6 +89,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -99,6 +99,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -402,6 +407,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
|
|||||||
+69
-7
@@ -2,9 +2,10 @@
|
|||||||
# gstack-config — read/write ~/.gstack/config.yaml
|
# gstack-config — read/write ~/.gstack/config.yaml
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# gstack-config get <key> — read a config value
|
# gstack-config get <key> — read a config value (falls back to DEFAULTS)
|
||||||
# gstack-config set <key> <value> — write a config value
|
# gstack-config set <key> <value> — write a config value
|
||||||
# gstack-config list — show all config
|
# gstack-config list — show all config (values + defaults)
|
||||||
|
# gstack-config defaults — show just the defaults table
|
||||||
#
|
#
|
||||||
# Env overrides (for testing):
|
# Env overrides (for testing):
|
||||||
# GSTACK_STATE_DIR — override ~/.gstack state directory
|
# GSTACK_STATE_DIR — override ~/.gstack state directory
|
||||||
@@ -14,6 +15,8 @@ STATE_DIR="${GSTACK_STATE_DIR:-$HOME/.gstack}"
|
|||||||
CONFIG_FILE="$STATE_DIR/config.yaml"
|
CONFIG_FILE="$STATE_DIR/config.yaml"
|
||||||
|
|
||||||
# Annotated header for new config files. Written once on first `set`.
|
# Annotated header for new config files. Written once on first `set`.
|
||||||
|
# Default semantics: DEFAULTS table below is the canonical source. Header text
|
||||||
|
# is documentation that must stay in sync with DEFAULTS.
|
||||||
CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on next skill run.
|
CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on next skill run.
|
||||||
# Docs: https://github.com/garrytan/gstack
|
# Docs: https://github.com/garrytan/gstack
|
||||||
#
|
#
|
||||||
@@ -25,8 +28,8 @@ CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on ne
|
|||||||
# # prompt. Set back to false to be asked again.
|
# # prompt. Set back to false to be asked again.
|
||||||
#
|
#
|
||||||
# ─── Telemetry ───────────────────────────────────────────────────────
|
# ─── Telemetry ───────────────────────────────────────────────────────
|
||||||
# telemetry: anonymous # off | anonymous | community
|
# telemetry: off # off | anonymous | community
|
||||||
# # off — no data sent, no local analytics
|
# # off — no data sent, no local analytics (default)
|
||||||
# # anonymous — counter only, no device ID
|
# # anonymous — counter only, no device ID
|
||||||
# # community — usage data + stable device ID
|
# # community — usage data + stable device ID
|
||||||
#
|
#
|
||||||
@@ -38,6 +41,16 @@ CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on ne
|
|||||||
# skill_prefix: false # true = namespace skills as /gstack-qa, /gstack-ship
|
# skill_prefix: false # true = namespace skills as /gstack-qa, /gstack-ship
|
||||||
# # false = short names /qa, /ship
|
# # false = short names /qa, /ship
|
||||||
#
|
#
|
||||||
|
# ─── Checkpoint ──────────────────────────────────────────────────────
|
||||||
|
# checkpoint_mode: explicit # explicit | continuous
|
||||||
|
# # explicit — commit only when you run /ship or /checkpoint
|
||||||
|
# # continuous — auto-commit after each significant change
|
||||||
|
# # with WIP: prefix + [gstack-context] body
|
||||||
|
#
|
||||||
|
# checkpoint_push: false # true = push WIP commits to remote as you go
|
||||||
|
# # false = keep WIP commits local only (default)
|
||||||
|
# # Pushing can trigger CI/deploy hooks — opt in carefully.
|
||||||
|
#
|
||||||
# ─── Advanced ────────────────────────────────────────────────────────
|
# ─── Advanced ────────────────────────────────────────────────────────
|
||||||
# codex_reviews: enabled # disabled = skip Codex adversarial reviews in /ship
|
# codex_reviews: enabled # disabled = skip Codex adversarial reviews in /ship
|
||||||
# gstack_contributor: false # true = file field reports when gstack misbehaves
|
# gstack_contributor: false # true = file field reports when gstack misbehaves
|
||||||
@@ -45,6 +58,27 @@ CONFIG_HEADER='# gstack configuration — edit freely, changes take effect on ne
|
|||||||
#
|
#
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# DEFAULTS table — canonical default values for known keys.
|
||||||
|
# `get <key>` returns DEFAULTS[key] when the key is absent from the config file
|
||||||
|
# AND the env override is not set. Keep in sync with the CONFIG_HEADER comments.
|
||||||
|
lookup_default() {
|
||||||
|
case "$1" in
|
||||||
|
proactive) echo "true" ;;
|
||||||
|
routing_declined) echo "false" ;;
|
||||||
|
telemetry) echo "off" ;;
|
||||||
|
auto_upgrade) echo "false" ;;
|
||||||
|
update_check) echo "true" ;;
|
||||||
|
skill_prefix) echo "false" ;;
|
||||||
|
checkpoint_mode) echo "explicit" ;;
|
||||||
|
checkpoint_push) echo "false" ;;
|
||||||
|
codex_reviews) echo "enabled" ;;
|
||||||
|
gstack_contributor) echo "false" ;;
|
||||||
|
skip_eng_review) echo "false" ;;
|
||||||
|
cross_project_learnings) echo "" ;; # intentionally empty → unset triggers first-time prompt
|
||||||
|
*) echo "" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
get)
|
get)
|
||||||
KEY="${2:?Usage: gstack-config get <key>}"
|
KEY="${2:?Usage: gstack-config get <key>}"
|
||||||
@@ -53,7 +87,11 @@ case "${1:-}" in
|
|||||||
echo "Error: key must contain only alphanumeric characters and underscores" >&2
|
echo "Error: key must contain only alphanumeric characters and underscores" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
grep -E "^${KEY}:" "$CONFIG_FILE" 2>/dev/null | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true
|
VALUE=$(grep -E "^${KEY}:" "$CONFIG_FILE" 2>/dev/null | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true)
|
||||||
|
if [ -z "$VALUE" ]; then
|
||||||
|
VALUE=$(lookup_default "$KEY")
|
||||||
|
fi
|
||||||
|
printf '%s' "$VALUE"
|
||||||
;;
|
;;
|
||||||
set)
|
set)
|
||||||
KEY="${2:?Usage: gstack-config set <key> <value>}"
|
KEY="${2:?Usage: gstack-config set <key> <value>}"
|
||||||
@@ -84,10 +122,34 @@ case "${1:-}" in
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
list)
|
list)
|
||||||
cat "$CONFIG_FILE" 2>/dev/null || true
|
if [ -f "$CONFIG_FILE" ]; then
|
||||||
|
cat "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "# ─── Active values (including defaults for unset keys) ───"
|
||||||
|
for KEY in proactive routing_declined telemetry auto_upgrade update_check \
|
||||||
|
skill_prefix checkpoint_mode checkpoint_push codex_reviews \
|
||||||
|
gstack_contributor skip_eng_review; do
|
||||||
|
VALUE=$(grep -E "^${KEY}:" "$CONFIG_FILE" 2>/dev/null | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true)
|
||||||
|
SOURCE="default"
|
||||||
|
if [ -n "$VALUE" ]; then
|
||||||
|
SOURCE="set"
|
||||||
|
else
|
||||||
|
VALUE=$(lookup_default "$KEY")
|
||||||
|
fi
|
||||||
|
printf ' %-24s %s (%s)\n' "$KEY:" "$VALUE" "$SOURCE"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
defaults)
|
||||||
|
echo "# gstack-config defaults"
|
||||||
|
for KEY in proactive routing_declined telemetry auto_upgrade update_check \
|
||||||
|
skill_prefix checkpoint_mode checkpoint_push codex_reviews \
|
||||||
|
gstack_contributor skip_eng_review; do
|
||||||
|
printf ' %-24s %s\n' "$KEY:" "$(lookup_default "$KEY")"
|
||||||
|
done
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Usage: gstack-config {get|set|list} [key] [value]"
|
echo "Usage: gstack-config {get|set|list|defaults} [key] [value]"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -394,6 +399,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -397,6 +402,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
@@ -737,6 +786,41 @@ in their frontmatter, so all files in the directory are candidates). This enable
|
|||||||
Conductor workspace handoff — a checkpoint saved on one branch can be resumed from
|
Conductor workspace handoff — a checkpoint saved on one branch can be resumed from
|
||||||
another.
|
another.
|
||||||
|
|
||||||
|
### Step 1.5: Check for WIP commit context (continuous checkpoint mode)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` was `"continuous"` during prior work, the branch may have
|
||||||
|
`WIP:` commits with structured `[gstack-context]` blocks in their bodies. These
|
||||||
|
are a second recovery trail alongside the markdown checkpoint files.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
_BRANCH=$(git branch --show-current 2>/dev/null)
|
||||||
|
# Detect if this branch has any WIP commits against the nearest remote ancestor
|
||||||
|
_BASE=$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD origin/master 2>/dev/null)
|
||||||
|
if [ -n "$_BASE" ]; then
|
||||||
|
WIP_COMMITS=$(git log "$_BASE"..HEAD --grep="^WIP:" --format="%H" 2>/dev/null | head -20)
|
||||||
|
if [ -n "$WIP_COMMITS" ]; then
|
||||||
|
echo "WIP_COMMITS_FOUND"
|
||||||
|
# Extract [gstack-context] blocks from each WIP commit body
|
||||||
|
for SHA in $WIP_COMMITS; do
|
||||||
|
echo "--- commit $SHA ---"
|
||||||
|
git log -1 "$SHA" --format="%s%n%n%b" 2>/dev/null | \
|
||||||
|
awk '/\[gstack-context\]/,/\[\/gstack-context\]/ { print }'
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "NO_WIP_COMMITS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COMMITS_FOUND`: Read the extracted `[gstack-context]` blocks. Each block
|
||||||
|
represents a logical unit of prior work with Decisions/Remaining/Tried/Skill.
|
||||||
|
Merge these with the markdown checkpoint file to reconstruct session state. The
|
||||||
|
git history shows the chronological arc; the markdown checkpoint shows the
|
||||||
|
intentional save points. Both matter.
|
||||||
|
|
||||||
|
**Important:** Do NOT delete WIP commits during resume. They remain the recovery
|
||||||
|
trail until /ship squashes them into clean commits during PR creation.
|
||||||
|
|
||||||
### Step 2: Load checkpoint
|
### Step 2: Load checkpoint
|
||||||
|
|
||||||
If the user specified a checkpoint (by number, title fragment, or date), find the
|
If the user specified a checkpoint (by number, title fragment, or date), find the
|
||||||
|
|||||||
@@ -189,6 +189,41 @@ in their frontmatter, so all files in the directory are candidates). This enable
|
|||||||
Conductor workspace handoff — a checkpoint saved on one branch can be resumed from
|
Conductor workspace handoff — a checkpoint saved on one branch can be resumed from
|
||||||
another.
|
another.
|
||||||
|
|
||||||
|
### Step 1.5: Check for WIP commit context (continuous checkpoint mode)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` was `"continuous"` during prior work, the branch may have
|
||||||
|
`WIP:` commits with structured `[gstack-context]` blocks in their bodies. These
|
||||||
|
are a second recovery trail alongside the markdown checkpoint files.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
_BRANCH=$(git branch --show-current 2>/dev/null)
|
||||||
|
# Detect if this branch has any WIP commits against the nearest remote ancestor
|
||||||
|
_BASE=$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD origin/master 2>/dev/null)
|
||||||
|
if [ -n "$_BASE" ]; then
|
||||||
|
WIP_COMMITS=$(git log "$_BASE"..HEAD --grep="^WIP:" --format="%H" 2>/dev/null | head -20)
|
||||||
|
if [ -n "$WIP_COMMITS" ]; then
|
||||||
|
echo "WIP_COMMITS_FOUND"
|
||||||
|
# Extract [gstack-context] blocks from each WIP commit body
|
||||||
|
for SHA in $WIP_COMMITS; do
|
||||||
|
echo "--- commit $SHA ---"
|
||||||
|
git log -1 "$SHA" --format="%s%n%n%b" 2>/dev/null | \
|
||||||
|
awk '/\[gstack-context\]/,/\[\/gstack-context\]/ { print }'
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "NO_WIP_COMMITS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COMMITS_FOUND`: Read the extracted `[gstack-context]` blocks. Each block
|
||||||
|
represents a logical unit of prior work with Decisions/Remaining/Tried/Skill.
|
||||||
|
Merge these with the markdown checkpoint file to reconstruct session state. The
|
||||||
|
git history shows the chronological arc; the markdown checkpoint shows the
|
||||||
|
intentional save points. Both matter.
|
||||||
|
|
||||||
|
**Important:** Do NOT delete WIP commits during resume. They remain the recovery
|
||||||
|
trail until /ship squashes them into clean commits during PR creation.
|
||||||
|
|
||||||
### Step 2: Load checkpoint
|
### Step 2: Load checkpoint
|
||||||
|
|
||||||
If the user specified a checkpoint (by number, title fragment, or date), find the
|
If the user specified a checkpoint (by number, title fragment, or date), find the
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -396,6 +401,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -399,6 +404,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -399,6 +404,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -401,6 +406,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -399,6 +404,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -396,6 +401,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -399,6 +404,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -396,6 +401,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -396,6 +401,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -108,6 +108,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -411,6 +416,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -393,6 +398,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -396,6 +401,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -403,6 +408,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -393,6 +398,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -394,6 +399,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -399,6 +404,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -397,6 +402,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -401,6 +406,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -399,6 +404,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -395,6 +400,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
+49
@@ -98,6 +98,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -401,6 +406,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -394,6 +399,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -397,6 +402,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
@@ -99,6 +99,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: ${ctx.model ?? 'none'}"
|
echo "MODEL_OVERLAY: ${ctx.model ?? 'none'}"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(${ctx.paths.binDir}/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(${ctx.paths.binDir}/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
\`\`\``;
|
\`\`\``;
|
||||||
@@ -706,6 +711,52 @@ are shown, synthesize a one-paragraph welcome briefing before proceeding:
|
|||||||
available]. [Health score if available]." Keep it to 2-3 sentences.`;
|
available]. [Health score if available]." Keep it to 2-3 sentences.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateContinuousCheckpoint(): string {
|
||||||
|
return `## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If \`CHECKPOINT_MODE\` is \`"continuous"\` (from preamble output): auto-commit work as
|
||||||
|
you go with \`WIP:\` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER \`git add -A\` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if \`CHECKPOINT_PUSH\` is \`"true"\` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
\`git log\` whenever they want.
|
||||||
|
|
||||||
|
**When \`/checkpoint resume\` runs,** it parses \`[gstack-context]\` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When \`/ship\` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
\`git rebase --autosquash\` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If \`CHECKPOINT_MODE\` is \`"explicit"\` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.`;
|
||||||
|
}
|
||||||
|
|
||||||
function generateContextHealth(): string {
|
function generateContextHealth(): string {
|
||||||
return `## Context Health (soft directive)
|
return `## Context Health (soft directive)
|
||||||
|
|
||||||
@@ -751,7 +802,7 @@ export function generatePreamble(ctx: TemplateContext): string {
|
|||||||
generateSpawnedSessionCheck(),
|
generateSpawnedSessionCheck(),
|
||||||
generateModelOverlay(ctx),
|
generateModelOverlay(ctx),
|
||||||
generateVoiceDirective(tier),
|
generateVoiceDirective(tier),
|
||||||
...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection(), generateContextHealth()] : []),
|
...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection(), generateContinuousCheckpoint(), generateContextHealth()] : []),
|
||||||
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
|
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
|
||||||
generateCompletionStatus(ctx),
|
generateCompletionStatus(ctx),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -397,6 +402,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
|
|||||||
+116
@@ -95,6 +95,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -398,6 +403,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
@@ -2332,6 +2381,73 @@ Save this summary — it goes into the PR body in Step 8.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Step 5.75: WIP Commit Squash (continuous checkpoint mode only)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"`, the branch likely contains `WIP:` commits
|
||||||
|
from auto-checkpointing. These must be squashed INTO the corresponding logical
|
||||||
|
commits before Step 6 runs. Non-WIP commits on the branch (earlier landed work)
|
||||||
|
must be preserved.
|
||||||
|
|
||||||
|
**Detection:**
|
||||||
|
```bash
|
||||||
|
WIP_COUNT=$(git log <base>..HEAD --oneline --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
echo "WIP_COMMITS: $WIP_COUNT"
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COUNT` is 0: skip this step entirely.
|
||||||
|
|
||||||
|
If `WIP_COUNT` > 0, collect the WIP context first so it survives the squash:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Export [gstack-context] blocks from all WIP commits on this branch.
|
||||||
|
# This file becomes input to the CHANGELOG entry and may inform PR body context.
|
||||||
|
mkdir -p "$(git rev-parse --show-toplevel)/.gstack"
|
||||||
|
git log <base>..HEAD --grep="^WIP:" --format="%H%n%B%n---END---" > \
|
||||||
|
"$(git rev-parse --show-toplevel)/.gstack/wip-context-before-squash.md" 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Non-destructive squash strategy:**
|
||||||
|
|
||||||
|
`git reset --soft <merge-base>` WOULD uncommit everything including non-WIP commits.
|
||||||
|
DO NOT DO THAT. Instead, use `git rebase` scoped to filter WIP commits only.
|
||||||
|
|
||||||
|
Option 1 (preferred, if there are non-WIP commits mixed in):
|
||||||
|
```bash
|
||||||
|
# Interactive rebase with automated WIP squashing.
|
||||||
|
# Mark every WIP commit as 'fixup' (drop its message, fold changes into prior commit).
|
||||||
|
git rebase -i $(git merge-base HEAD origin/<base>) \
|
||||||
|
--exec 'true' \
|
||||||
|
-X ours 2>/dev/null || {
|
||||||
|
echo "Rebase conflict. Aborting: git rebase --abort"
|
||||||
|
git rebase --abort
|
||||||
|
echo "STATUS: BLOCKED — manual WIP squash required"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Option 2 (simpler, if the branch is ALL WIP commits so far — no landed work):
|
||||||
|
```bash
|
||||||
|
# Branch contains only WIP commits. Reset-soft is safe here because there's
|
||||||
|
# nothing non-WIP to preserve. Verify first.
|
||||||
|
NON_WIP=$(git log <base>..HEAD --oneline --invert-grep --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
if [ "$NON_WIP" -eq 0 ]; then
|
||||||
|
git reset --soft $(git merge-base HEAD origin/<base>)
|
||||||
|
echo "WIP-only branch, reset-soft to merge base. Step 6 will create clean commits."
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Decide at runtime which option applies. If unsure, prefer stopping and asking the
|
||||||
|
user via AskUserQuestion rather than destroying non-WIP commits.
|
||||||
|
|
||||||
|
**Anti-footgun rules:**
|
||||||
|
- NEVER blind `git reset --soft` if there are non-WIP commits. Codex flagged this
|
||||||
|
as destructive — it would uncommit real landed work and turn Step 7 into a
|
||||||
|
non-fast-forward push for anyone who already pushed.
|
||||||
|
- Only proceed to Step 6 after WIP commits are successfully squashed/absorbed or
|
||||||
|
the branch has been verified to contain only WIP work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Step 6: Commit (bisectable chunks)
|
## Step 6: Commit (bisectable chunks)
|
||||||
|
|
||||||
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
||||||
|
|||||||
@@ -435,6 +435,73 @@ Save this summary — it goes into the PR body in Step 8.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Step 5.75: WIP Commit Squash (continuous checkpoint mode only)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"`, the branch likely contains `WIP:` commits
|
||||||
|
from auto-checkpointing. These must be squashed INTO the corresponding logical
|
||||||
|
commits before Step 6 runs. Non-WIP commits on the branch (earlier landed work)
|
||||||
|
must be preserved.
|
||||||
|
|
||||||
|
**Detection:**
|
||||||
|
```bash
|
||||||
|
WIP_COUNT=$(git log <base>..HEAD --oneline --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
echo "WIP_COMMITS: $WIP_COUNT"
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COUNT` is 0: skip this step entirely.
|
||||||
|
|
||||||
|
If `WIP_COUNT` > 0, collect the WIP context first so it survives the squash:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Export [gstack-context] blocks from all WIP commits on this branch.
|
||||||
|
# This file becomes input to the CHANGELOG entry and may inform PR body context.
|
||||||
|
mkdir -p "$(git rev-parse --show-toplevel)/.gstack"
|
||||||
|
git log <base>..HEAD --grep="^WIP:" --format="%H%n%B%n---END---" > \
|
||||||
|
"$(git rev-parse --show-toplevel)/.gstack/wip-context-before-squash.md" 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Non-destructive squash strategy:**
|
||||||
|
|
||||||
|
`git reset --soft <merge-base>` WOULD uncommit everything including non-WIP commits.
|
||||||
|
DO NOT DO THAT. Instead, use `git rebase` scoped to filter WIP commits only.
|
||||||
|
|
||||||
|
Option 1 (preferred, if there are non-WIP commits mixed in):
|
||||||
|
```bash
|
||||||
|
# Interactive rebase with automated WIP squashing.
|
||||||
|
# Mark every WIP commit as 'fixup' (drop its message, fold changes into prior commit).
|
||||||
|
git rebase -i $(git merge-base HEAD origin/<base>) \
|
||||||
|
--exec 'true' \
|
||||||
|
-X ours 2>/dev/null || {
|
||||||
|
echo "Rebase conflict. Aborting: git rebase --abort"
|
||||||
|
git rebase --abort
|
||||||
|
echo "STATUS: BLOCKED — manual WIP squash required"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Option 2 (simpler, if the branch is ALL WIP commits so far — no landed work):
|
||||||
|
```bash
|
||||||
|
# Branch contains only WIP commits. Reset-soft is safe here because there's
|
||||||
|
# nothing non-WIP to preserve. Verify first.
|
||||||
|
NON_WIP=$(git log <base>..HEAD --oneline --invert-grep --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
if [ "$NON_WIP" -eq 0 ]; then
|
||||||
|
git reset --soft $(git merge-base HEAD origin/<base>)
|
||||||
|
echo "WIP-only branch, reset-soft to merge base. Step 6 will create clean commits."
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Decide at runtime which option applies. If unsure, prefer stopping and asking the
|
||||||
|
user via AskUserQuestion rather than destroying non-WIP commits.
|
||||||
|
|
||||||
|
**Anti-footgun rules:**
|
||||||
|
- NEVER blind `git reset --soft` if there are non-WIP commits. Codex flagged this
|
||||||
|
as destructive — it would uncommit real landed work and turn Step 7 into a
|
||||||
|
non-fast-forward push for anyone who already pushed.
|
||||||
|
- Only proceed to Step 6 after WIP commits are successfully squashed/absorbed or
|
||||||
|
the branch has been verified to contain only WIP work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Step 6: Commit (bisectable chunks)
|
## Step 6: Commit (bisectable chunks)
|
||||||
|
|
||||||
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
||||||
|
|||||||
+116
@@ -95,6 +95,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -398,6 +403,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
@@ -2332,6 +2381,73 @@ Save this summary — it goes into the PR body in Step 8.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Step 5.75: WIP Commit Squash (continuous checkpoint mode only)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"`, the branch likely contains `WIP:` commits
|
||||||
|
from auto-checkpointing. These must be squashed INTO the corresponding logical
|
||||||
|
commits before Step 6 runs. Non-WIP commits on the branch (earlier landed work)
|
||||||
|
must be preserved.
|
||||||
|
|
||||||
|
**Detection:**
|
||||||
|
```bash
|
||||||
|
WIP_COUNT=$(git log <base>..HEAD --oneline --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
echo "WIP_COMMITS: $WIP_COUNT"
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COUNT` is 0: skip this step entirely.
|
||||||
|
|
||||||
|
If `WIP_COUNT` > 0, collect the WIP context first so it survives the squash:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Export [gstack-context] blocks from all WIP commits on this branch.
|
||||||
|
# This file becomes input to the CHANGELOG entry and may inform PR body context.
|
||||||
|
mkdir -p "$(git rev-parse --show-toplevel)/.gstack"
|
||||||
|
git log <base>..HEAD --grep="^WIP:" --format="%H%n%B%n---END---" > \
|
||||||
|
"$(git rev-parse --show-toplevel)/.gstack/wip-context-before-squash.md" 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Non-destructive squash strategy:**
|
||||||
|
|
||||||
|
`git reset --soft <merge-base>` WOULD uncommit everything including non-WIP commits.
|
||||||
|
DO NOT DO THAT. Instead, use `git rebase` scoped to filter WIP commits only.
|
||||||
|
|
||||||
|
Option 1 (preferred, if there are non-WIP commits mixed in):
|
||||||
|
```bash
|
||||||
|
# Interactive rebase with automated WIP squashing.
|
||||||
|
# Mark every WIP commit as 'fixup' (drop its message, fold changes into prior commit).
|
||||||
|
git rebase -i $(git merge-base HEAD origin/<base>) \
|
||||||
|
--exec 'true' \
|
||||||
|
-X ours 2>/dev/null || {
|
||||||
|
echo "Rebase conflict. Aborting: git rebase --abort"
|
||||||
|
git rebase --abort
|
||||||
|
echo "STATUS: BLOCKED — manual WIP squash required"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Option 2 (simpler, if the branch is ALL WIP commits so far — no landed work):
|
||||||
|
```bash
|
||||||
|
# Branch contains only WIP commits. Reset-soft is safe here because there's
|
||||||
|
# nothing non-WIP to preserve. Verify first.
|
||||||
|
NON_WIP=$(git log <base>..HEAD --oneline --invert-grep --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
if [ "$NON_WIP" -eq 0 ]; then
|
||||||
|
git reset --soft $(git merge-base HEAD origin/<base>)
|
||||||
|
echo "WIP-only branch, reset-soft to merge base. Step 6 will create clean commits."
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Decide at runtime which option applies. If unsure, prefer stopping and asking the
|
||||||
|
user via AskUserQuestion rather than destroying non-WIP commits.
|
||||||
|
|
||||||
|
**Anti-footgun rules:**
|
||||||
|
- NEVER blind `git reset --soft` if there are non-WIP commits. Codex flagged this
|
||||||
|
as destructive — it would uncommit real landed work and turn Step 7 into a
|
||||||
|
non-fast-forward push for anyone who already pushed.
|
||||||
|
- Only proceed to Step 6 after WIP commits are successfully squashed/absorbed or
|
||||||
|
the branch has been verified to contain only WIP work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Step 6: Commit (bisectable chunks)
|
## Step 6: Commit (bisectable chunks)
|
||||||
|
|
||||||
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
||||||
|
|||||||
+116
@@ -89,6 +89,11 @@ if [ -d ".agents/skills/gstack" ] && [ ! -L ".agents/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$($GSTACK_BIN/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$($GSTACK_BIN/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -392,6 +397,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
@@ -1952,6 +2001,73 @@ Save this summary — it goes into the PR body in Step 8.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Step 5.75: WIP Commit Squash (continuous checkpoint mode only)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"`, the branch likely contains `WIP:` commits
|
||||||
|
from auto-checkpointing. These must be squashed INTO the corresponding logical
|
||||||
|
commits before Step 6 runs. Non-WIP commits on the branch (earlier landed work)
|
||||||
|
must be preserved.
|
||||||
|
|
||||||
|
**Detection:**
|
||||||
|
```bash
|
||||||
|
WIP_COUNT=$(git log <base>..HEAD --oneline --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
echo "WIP_COMMITS: $WIP_COUNT"
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COUNT` is 0: skip this step entirely.
|
||||||
|
|
||||||
|
If `WIP_COUNT` > 0, collect the WIP context first so it survives the squash:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Export [gstack-context] blocks from all WIP commits on this branch.
|
||||||
|
# This file becomes input to the CHANGELOG entry and may inform PR body context.
|
||||||
|
mkdir -p "$(git rev-parse --show-toplevel)/.gstack"
|
||||||
|
git log <base>..HEAD --grep="^WIP:" --format="%H%n%B%n---END---" > \
|
||||||
|
"$(git rev-parse --show-toplevel)/.gstack/wip-context-before-squash.md" 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Non-destructive squash strategy:**
|
||||||
|
|
||||||
|
`git reset --soft <merge-base>` WOULD uncommit everything including non-WIP commits.
|
||||||
|
DO NOT DO THAT. Instead, use `git rebase` scoped to filter WIP commits only.
|
||||||
|
|
||||||
|
Option 1 (preferred, if there are non-WIP commits mixed in):
|
||||||
|
```bash
|
||||||
|
# Interactive rebase with automated WIP squashing.
|
||||||
|
# Mark every WIP commit as 'fixup' (drop its message, fold changes into prior commit).
|
||||||
|
git rebase -i $(git merge-base HEAD origin/<base>) \
|
||||||
|
--exec 'true' \
|
||||||
|
-X ours 2>/dev/null || {
|
||||||
|
echo "Rebase conflict. Aborting: git rebase --abort"
|
||||||
|
git rebase --abort
|
||||||
|
echo "STATUS: BLOCKED — manual WIP squash required"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Option 2 (simpler, if the branch is ALL WIP commits so far — no landed work):
|
||||||
|
```bash
|
||||||
|
# Branch contains only WIP commits. Reset-soft is safe here because there's
|
||||||
|
# nothing non-WIP to preserve. Verify first.
|
||||||
|
NON_WIP=$(git log <base>..HEAD --oneline --invert-grep --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
if [ "$NON_WIP" -eq 0 ]; then
|
||||||
|
git reset --soft $(git merge-base HEAD origin/<base>)
|
||||||
|
echo "WIP-only branch, reset-soft to merge base. Step 6 will create clean commits."
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Decide at runtime which option applies. If unsure, prefer stopping and asking the
|
||||||
|
user via AskUserQuestion rather than destroying non-WIP commits.
|
||||||
|
|
||||||
|
**Anti-footgun rules:**
|
||||||
|
- NEVER blind `git reset --soft` if there are non-WIP commits. Codex flagged this
|
||||||
|
as destructive — it would uncommit real landed work and turn Step 7 into a
|
||||||
|
non-fast-forward push for anyone who already pushed.
|
||||||
|
- Only proceed to Step 6 after WIP commits are successfully squashed/absorbed or
|
||||||
|
the branch has been verified to contain only WIP work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Step 6: Commit (bisectable chunks)
|
## Step 6: Commit (bisectable chunks)
|
||||||
|
|
||||||
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
||||||
|
|||||||
+116
@@ -91,6 +91,11 @@ if [ -d ".factory/skills/gstack" ] && [ ! -L ".factory/skills/gstack" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "VENDORED_GSTACK: $_VENDORED"
|
echo "VENDORED_GSTACK: $_VENDORED"
|
||||||
echo "MODEL_OVERLAY: claude"
|
echo "MODEL_OVERLAY: claude"
|
||||||
|
# Checkpoint mode (explicit = no auto-commit, continuous = WIP commits as you go)
|
||||||
|
_CHECKPOINT_MODE=$($GSTACK_BIN/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit")
|
||||||
|
_CHECKPOINT_PUSH=$($GSTACK_BIN/gstack-config get checkpoint_push 2>/dev/null || echo "false")
|
||||||
|
echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE"
|
||||||
|
echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH"
|
||||||
# Detect spawned session (OpenClaw or other orchestrator)
|
# Detect spawned session (OpenClaw or other orchestrator)
|
||||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||||
```
|
```
|
||||||
@@ -394,6 +399,50 @@ AI makes completeness near-free. Always recommend the complete option over short
|
|||||||
|
|
||||||
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
Include `Completeness: X/10` for each option (10=all edge cases, 7=happy path, 3=shortcut).
|
||||||
|
|
||||||
|
## Continuous Checkpoint Mode
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"` (from preamble output): auto-commit work as
|
||||||
|
you go with `WIP:` prefix so session state survives crashes and context switches.
|
||||||
|
|
||||||
|
**When to commit (continuous mode only):**
|
||||||
|
- After creating a new file (not scratch/temp files)
|
||||||
|
- After finishing a function/component/module
|
||||||
|
- After fixing a bug that's verified by a passing test
|
||||||
|
- Before any long-running operation (install, full build, full test suite)
|
||||||
|
|
||||||
|
**Commit format** — include structured context in the body:
|
||||||
|
|
||||||
|
```
|
||||||
|
WIP: <concise description of what changed>
|
||||||
|
|
||||||
|
[gstack-context]
|
||||||
|
Decisions: <key choices made this step>
|
||||||
|
Remaining: <what's left in the logical unit>
|
||||||
|
Tried: <failed approaches worth recording> (omit if none)
|
||||||
|
Skill: </skill-name-if-running>
|
||||||
|
[/gstack-context]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Stage only files you intentionally changed. NEVER `git add -A` in continuous mode.
|
||||||
|
- Do NOT commit with known-broken tests. Fix first, then commit. The [gstack-context]
|
||||||
|
example values MUST reflect a clean state.
|
||||||
|
- Do NOT commit mid-edit. Finish the logical unit.
|
||||||
|
- Push ONLY if `CHECKPOINT_PUSH` is `"true"` (default is false). Pushing WIP commits
|
||||||
|
to a shared remote can trigger CI, deploys, and expose secrets — that is why push
|
||||||
|
is opt-in, not default.
|
||||||
|
- Background discipline — do NOT announce each commit to the user. They can see
|
||||||
|
`git log` whenever they want.
|
||||||
|
|
||||||
|
**When `/checkpoint resume` runs,** it parses `[gstack-context]` blocks from WIP
|
||||||
|
commits on the current branch to reconstruct session state. When `/ship` runs, it
|
||||||
|
filter-squashes WIP commits only (preserving non-WIP commits) via
|
||||||
|
`git rebase --autosquash` so the PR contains clean bisectable commits.
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"explicit"` (the default): no auto-commit behavior. Commit
|
||||||
|
only when the user explicitly asks, or when a skill workflow (like /ship) runs a
|
||||||
|
commit step. Ignore this section entirely.
|
||||||
|
|
||||||
## Context Health (soft directive)
|
## Context Health (soft directive)
|
||||||
|
|
||||||
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary
|
||||||
@@ -2328,6 +2377,73 @@ Save this summary — it goes into the PR body in Step 8.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Step 5.75: WIP Commit Squash (continuous checkpoint mode only)
|
||||||
|
|
||||||
|
If `CHECKPOINT_MODE` is `"continuous"`, the branch likely contains `WIP:` commits
|
||||||
|
from auto-checkpointing. These must be squashed INTO the corresponding logical
|
||||||
|
commits before Step 6 runs. Non-WIP commits on the branch (earlier landed work)
|
||||||
|
must be preserved.
|
||||||
|
|
||||||
|
**Detection:**
|
||||||
|
```bash
|
||||||
|
WIP_COUNT=$(git log <base>..HEAD --oneline --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
echo "WIP_COMMITS: $WIP_COUNT"
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIP_COUNT` is 0: skip this step entirely.
|
||||||
|
|
||||||
|
If `WIP_COUNT` > 0, collect the WIP context first so it survives the squash:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Export [gstack-context] blocks from all WIP commits on this branch.
|
||||||
|
# This file becomes input to the CHANGELOG entry and may inform PR body context.
|
||||||
|
mkdir -p "$(git rev-parse --show-toplevel)/.gstack"
|
||||||
|
git log <base>..HEAD --grep="^WIP:" --format="%H%n%B%n---END---" > \
|
||||||
|
"$(git rev-parse --show-toplevel)/.gstack/wip-context-before-squash.md" 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Non-destructive squash strategy:**
|
||||||
|
|
||||||
|
`git reset --soft <merge-base>` WOULD uncommit everything including non-WIP commits.
|
||||||
|
DO NOT DO THAT. Instead, use `git rebase` scoped to filter WIP commits only.
|
||||||
|
|
||||||
|
Option 1 (preferred, if there are non-WIP commits mixed in):
|
||||||
|
```bash
|
||||||
|
# Interactive rebase with automated WIP squashing.
|
||||||
|
# Mark every WIP commit as 'fixup' (drop its message, fold changes into prior commit).
|
||||||
|
git rebase -i $(git merge-base HEAD origin/<base>) \
|
||||||
|
--exec 'true' \
|
||||||
|
-X ours 2>/dev/null || {
|
||||||
|
echo "Rebase conflict. Aborting: git rebase --abort"
|
||||||
|
git rebase --abort
|
||||||
|
echo "STATUS: BLOCKED — manual WIP squash required"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Option 2 (simpler, if the branch is ALL WIP commits so far — no landed work):
|
||||||
|
```bash
|
||||||
|
# Branch contains only WIP commits. Reset-soft is safe here because there's
|
||||||
|
# nothing non-WIP to preserve. Verify first.
|
||||||
|
NON_WIP=$(git log <base>..HEAD --oneline --invert-grep --grep="^WIP:" 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
if [ "$NON_WIP" -eq 0 ]; then
|
||||||
|
git reset --soft $(git merge-base HEAD origin/<base>)
|
||||||
|
echo "WIP-only branch, reset-soft to merge base. Step 6 will create clean commits."
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Decide at runtime which option applies. If unsure, prefer stopping and asking the
|
||||||
|
user via AskUserQuestion rather than destroying non-WIP commits.
|
||||||
|
|
||||||
|
**Anti-footgun rules:**
|
||||||
|
- NEVER blind `git reset --soft` if there are non-WIP commits. Codex flagged this
|
||||||
|
as destructive — it would uncommit real landed work and turn Step 7 into a
|
||||||
|
non-fast-forward push for anyone who already pushed.
|
||||||
|
- Only proceed to Step 6 after WIP commits are successfully squashed/absorbed or
|
||||||
|
the branch has been verified to contain only WIP work.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Step 6: Commit (bisectable chunks)
|
## Step 6: Commit (bisectable chunks)
|
||||||
|
|
||||||
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
||||||
|
|||||||
Reference in New Issue
Block a user