mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-09 14:55: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:
@@ -89,6 +89,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
||||
fi
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||
```
|
||||
|
||||
@@ -99,6 +99,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
||||
fi
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||
```
|
||||
|
||||
+69
-7
@@ -2,9 +2,10 @@
|
||||
# gstack-config — read/write ~/.gstack/config.yaml
|
||||
#
|
||||
# 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 list — show all config
|
||||
# gstack-config list — show all config (values + defaults)
|
||||
# gstack-config defaults — show just the defaults table
|
||||
#
|
||||
# Env overrides (for testing):
|
||||
# GSTACK_STATE_DIR — override ~/.gstack state directory
|
||||
@@ -14,6 +15,8 @@ STATE_DIR="${GSTACK_STATE_DIR:-$HOME/.gstack}"
|
||||
CONFIG_FILE="$STATE_DIR/config.yaml"
|
||||
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
# ─── Telemetry ───────────────────────────────────────────────────────
|
||||
# telemetry: anonymous # off | anonymous | community
|
||||
# # off — no data sent, no local analytics
|
||||
# telemetry: off # off | anonymous | community
|
||||
# # off — no data sent, no local analytics (default)
|
||||
# # anonymous — counter only, no 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
|
||||
# # 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 ────────────────────────────────────────────────────────
|
||||
# codex_reviews: enabled # disabled = skip Codex adversarial reviews in /ship
|
||||
# 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
|
||||
get)
|
||||
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
|
||||
exit 1
|
||||
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)
|
||||
KEY="${2:?Usage: gstack-config set <key> <value>}"
|
||||
@@ -84,10 +122,34 @@ case "${1:-}" in
|
||||
fi
|
||||
;;
|
||||
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
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -91,6 +91,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
||||
fi
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||
```
|
||||
|
||||
@@ -91,6 +91,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
||||
fi
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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.`;
|
||||
}
|
||||
|
||||
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 {
|
||||
return `## Context Health (soft directive)
|
||||
|
||||
@@ -751,7 +802,7 @@ export function generatePreamble(ctx: TemplateContext): string {
|
||||
generateSpawnedSessionCheck(),
|
||||
generateModelOverlay(ctx),
|
||||
generateVoiceDirective(tier),
|
||||
...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection(), generateContextHealth()] : []),
|
||||
...(tier >= 2 ? [generateContextRecovery(ctx), generateAskUserFormat(ctx), generateCompletenessSection(), generateContinuousCheckpoint(), generateContextHealth()] : []),
|
||||
...(tier >= 3 ? [generateRepoModeSection(), generateSearchBeforeBuildingSection(ctx)] : []),
|
||||
generateCompletionStatus(ctx),
|
||||
];
|
||||
|
||||
@@ -88,6 +88,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
||||
fi
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true
|
||||
```
|
||||
|
||||
@@ -94,6 +94,11 @@ if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
|
||||
fi
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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)
|
||||
|
||||
**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)
|
||||
|
||||
**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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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)
|
||||
|
||||
**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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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)
|
||||
|
||||
**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
|
||||
echo "VENDORED_GSTACK: $_VENDORED"
|
||||
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)
|
||||
[ -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).
|
||||
|
||||
## 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)
|
||||
|
||||
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)
|
||||
|
||||
**Goal:** Create small, logical commits that work well with `git bisect` and help LLMs understand what changed.
|
||||
|
||||
Reference in New Issue
Block a user