diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 80d2dd563..c2c8549ee 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -1968,8 +1968,11 @@ command breaks the review readiness dashboard in /ship. ```bash ~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"CEO review (MODE): SCOPE_SUMMARY","rationale":"VERDICT","scope":"branch","source":"skill","confidence":8}' 2>/dev/null || true ``` +The second command records the accepted scope as a durable cross-session decision so the next session sees what was settled (and why) without re-litigating it. It writes to `~/.gstack/` (same pattern as review-log), is non-interactive, and is best-effort (`|| true` — never blocks the review). Substitute `SCOPE_SUMMARY` (e.g. "accepted 4 of 6 proposals" for expansion, or "held scope" / "cut 3 items" for HOLD/REDUCTION) and `VERDICT` (the one-line verdict from the summary). + Before running this command, substitute the placeholder values from the Completion Summary you just produced: - **TIMESTAMP**: current ISO 8601 datetime (e.g., 2026-03-16T14:30:00) - **STATUS**: "clean" if 0 unresolved decisions AND 0 critical gaps; otherwise "issues_open" diff --git a/plan-ceo-review/SKILL.md.tmpl b/plan-ceo-review/SKILL.md.tmpl index cd51ece29..5e1257297 100644 --- a/plan-ceo-review/SKILL.md.tmpl +++ b/plan-ceo-review/SKILL.md.tmpl @@ -802,8 +802,11 @@ command breaks the review readiness dashboard in /ship. ```bash ~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-ceo-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"mode":"MODE","scope_proposed":N,"scope_accepted":N,"scope_deferred":N,"commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"CEO review (MODE): SCOPE_SUMMARY","rationale":"VERDICT","scope":"branch","source":"skill","confidence":8}' 2>/dev/null || true ``` +The second command records the accepted scope as a durable cross-session decision so the next session sees what was settled (and why) without re-litigating it. It writes to `~/.gstack/` (same pattern as review-log), is non-interactive, and is best-effort (`|| true` — never blocks the review). Substitute `SCOPE_SUMMARY` (e.g. "accepted 4 of 6 proposals" for expansion, or "held scope" / "cut 3 items" for HOLD/REDUCTION) and `VERDICT` (the one-line verdict from the summary). + Before running this command, substitute the placeholder values from the Completion Summary you just produced: - **TIMESTAMP**: current ISO 8601 datetime (e.g., 2026-03-16T14:30:00) - **STATUS**: "clean" if 0 unresolved decisions AND 0 critical gaps; otherwise "issues_open" diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index d3fed23d5..aa13fd157 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -1583,8 +1583,11 @@ command breaks the review readiness dashboard in /ship. ```bash ~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Eng review (MODE): ARCH_SUMMARY","rationale":"KEY_DECISION","scope":"branch","source":"skill","confidence":8}' 2>/dev/null || true ``` +The second command records the architecture verdict as a durable cross-session decision (so a future session inherits the chosen approach and what was hardened, not just the count). Same `~/.gstack/` write pattern as review-log, non-interactive, best-effort (`|| true`). Substitute `ARCH_SUMMARY` (e.g. "N findings, all folded" or "M unresolved") and `KEY_DECISION` (the load-bearing architecture call from the report, one line — omit if the review found nothing durable). + Substitute values from the Completion Summary: - **TIMESTAMP**: current ISO 8601 datetime - **STATUS**: "clean" if 0 unresolved decisions AND 0 critical gaps; otherwise "issues_open" diff --git a/plan-eng-review/SKILL.md.tmpl b/plan-eng-review/SKILL.md.tmpl index 09f5b163a..b1dcb5b11 100644 --- a/plan-eng-review/SKILL.md.tmpl +++ b/plan-eng-review/SKILL.md.tmpl @@ -304,8 +304,11 @@ command breaks the review readiness dashboard in /ship. ```bash ~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"plan-eng-review","timestamp":"TIMESTAMP","status":"STATUS","unresolved":N,"critical_gaps":N,"issues_found":N,"mode":"MODE","commit":"COMMIT"}' +~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Eng review (MODE): ARCH_SUMMARY","rationale":"KEY_DECISION","scope":"branch","source":"skill","confidence":8}' 2>/dev/null || true ``` +The second command records the architecture verdict as a durable cross-session decision (so a future session inherits the chosen approach and what was hardened, not just the count). Same `~/.gstack/` write pattern as review-log, non-interactive, best-effort (`|| true`). Substitute `ARCH_SUMMARY` (e.g. "N findings, all folded" or "M unresolved") and `KEY_DECISION` (the load-bearing architecture call from the report, one line — omit if the review found nothing durable). + Substitute values from the Completion Summary: - **TIMESTAMP**: current ISO 8601 datetime - **STATUS**: "clean" if 0 unresolved decisions AND 0 critical gaps; otherwise "issues_open" diff --git a/ship/SKILL.md b/ship/SKILL.md index 750a51d05..d65d6bf25 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -1015,6 +1015,12 @@ stay agent judgment; the slot pick stays `gstack-next-version`. ``` The CLI validates the 4-digit `MAJOR.MINOR.PATCH.MICRO` pattern and writes **both** VERSION and package.json. On a half-write (VERSION written, package.json failed) it exits 3 — re-run, and classify will report DRIFT_STALE_PKG for `repair` to fix. +5. **Record the release decision** (durable cross-session memory). The bump level is a real decision the next session should not re-derive blind: + ```bash + ~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Ship NEW_VERSION (BUMP_LEVEL)","rationale":"WHY","scope":"repo","source":"skill","confidence":9}' 2>/dev/null || true + ``` + Substitute `NEW_VERSION`, `BUMP_LEVEL`, and a one-line `WHY` (the signal that set the level: diff scale, a new feature, a breaking change). Best-effort and non-interactive; never blocks the ship. Skip on the ALREADY_BUMPED path (the decision was logged on the run that did the bump). + > **STOP.** Before writing the CHANGELOG entry (Step 13), Read `~/.claude/skills/gstack/ship/sections/changelog.md` and execute it > in full. Do not work from memory — that section is the source of truth for this step. diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index cd6875d94..bbce60822 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -189,6 +189,12 @@ stay agent judgment; the slot pick stays `gstack-next-version`. ``` The CLI validates the 4-digit `MAJOR.MINOR.PATCH.MICRO` pattern and writes **both** VERSION and package.json. On a half-write (VERSION written, package.json failed) it exits 3 — re-run, and classify will report DRIFT_STALE_PKG for `repair` to fix. +5. **Record the release decision** (durable cross-session memory). The bump level is a real decision the next session should not re-derive blind: + ```bash + ~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Ship NEW_VERSION (BUMP_LEVEL)","rationale":"WHY","scope":"repo","source":"skill","confidence":9}' 2>/dev/null || true + ``` + Substitute `NEW_VERSION`, `BUMP_LEVEL`, and a one-line `WHY` (the signal that set the level: diff scale, a new feature, a breaking change). Best-effort and non-interactive; never blocks the ship. Skip on the ALREADY_BUMPED path (the decision was logged on the run that did the bump). + {{SECTION:changelog}} ## Step 14: TODOS.md (auto-update) diff --git a/spec/SKILL.md b/spec/SKILL.md index 2da327d96..0630d02f9 100644 --- a/spec/SKILL.md +++ b/spec/SKILL.md @@ -1798,8 +1798,11 @@ If `gh` is available and authenticated, file from the scanned temp file: ISSUE_URL=$(gh issue create --title "" --body-file "$REDACT_FILE") ISSUE_NUMBER=$(echo "$ISSUE_URL" | sed -E 's|.*/issues/([0-9]+)$|\1|') echo "Filed: $ISSUE_URL" +~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Spec filed #ISSUE_NUMBER: TITLE","rationale":"APPROACH","scope":"issue","issue":"ISSUE_NUMBER","source":"skill","confidence":7}' 2>/dev/null || true ``` +The last line records the spec as a durable, issue-scoped cross-session decision so a future session (or `/ship` closing the issue) inherits the core approach and why, not just the issue link. Non-interactive, best-effort (`|| true`). Substitute `ISSUE_NUMBER` (from the filed issue), `TITLE` (the issue title), and `APPROACH` (the one core approach/decision the spec settled). Only fires when the issue was actually filed. + If `gh` is not available, print: "`gh` not authenticated — title and body below for paste into https://github.com/{owner}/{repo}/issues/new with zero reformatting needed." Then emit the rendered title + body. diff --git a/spec/SKILL.md.tmpl b/spec/SKILL.md.tmpl index 39dbdcf5d..6c0c14e1b 100644 --- a/spec/SKILL.md.tmpl +++ b/spec/SKILL.md.tmpl @@ -317,8 +317,11 @@ If `gh` is available and authenticated, file from the scanned temp file: ISSUE_URL=$(gh issue create --title "<title>" --body-file "$REDACT_FILE") ISSUE_NUMBER=$(echo "$ISSUE_URL" | sed -E 's|.*/issues/([0-9]+)$|\1|') echo "Filed: $ISSUE_URL" +~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Spec filed #ISSUE_NUMBER: TITLE","rationale":"APPROACH","scope":"issue","issue":"ISSUE_NUMBER","source":"skill","confidence":7}' 2>/dev/null || true ``` +The last line records the spec as a durable, issue-scoped cross-session decision so a future session (or `/ship` closing the issue) inherits the core approach and why, not just the issue link. Non-interactive, best-effort (`|| true`). Substitute `ISSUE_NUMBER` (from the filed issue), `TITLE` (the issue title), and `APPROACH` (the one core approach/decision the spec settled). Only fires when the issue was actually filed. + If `gh` is not available, print: "`gh` not authenticated — title and body below for paste into https://github.com/{owner}/{repo}/issues/new with zero reformatting needed." Then emit the rendered title + body. diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index 750a51d05..d65d6bf25 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -1015,6 +1015,12 @@ stay agent judgment; the slot pick stays `gstack-next-version`. ``` The CLI validates the 4-digit `MAJOR.MINOR.PATCH.MICRO` pattern and writes **both** VERSION and package.json. On a half-write (VERSION written, package.json failed) it exits 3 — re-run, and classify will report DRIFT_STALE_PKG for `repair` to fix. +5. **Record the release decision** (durable cross-session memory). The bump level is a real decision the next session should not re-derive blind: + ```bash + ~/.claude/skills/gstack/bin/gstack-decision-log '{"decision":"Ship NEW_VERSION (BUMP_LEVEL)","rationale":"WHY","scope":"repo","source":"skill","confidence":9}' 2>/dev/null || true + ``` + Substitute `NEW_VERSION`, `BUMP_LEVEL`, and a one-line `WHY` (the signal that set the level: diff scale, a new feature, a breaking change). Best-effort and non-interactive; never blocks the ship. Skip on the ALREADY_BUMPED path (the decision was logged on the run that did the bump). + > **STOP.** Before writing the CHANGELOG entry (Step 13), Read `~/.claude/skills/gstack/ship/sections/changelog.md` and execute it > in full. Do not work from memory — that section is the source of truth for this step. diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index 56cb66d73..214f59801 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -2141,6 +2141,12 @@ stay agent judgment; the slot pick stays `gstack-next-version`. ``` The CLI validates the 4-digit `MAJOR.MINOR.PATCH.MICRO` pattern and writes **both** VERSION and package.json. On a half-write (VERSION written, package.json failed) it exits 3 — re-run, and classify will report DRIFT_STALE_PKG for `repair` to fix. +5. **Record the release decision** (durable cross-session memory). The bump level is a real decision the next session should not re-derive blind: + ```bash + $GSTACK_ROOT/bin/gstack-decision-log '{"decision":"Ship NEW_VERSION (BUMP_LEVEL)","rationale":"WHY","scope":"repo","source":"skill","confidence":9}' 2>/dev/null || true + ``` + Substitute `NEW_VERSION`, `BUMP_LEVEL`, and a one-line `WHY` (the signal that set the level: diff scale, a new feature, a breaking change). Best-effort and non-interactive; never blocks the ship. Skip on the ALREADY_BUMPED path (the decision was logged on the run that did the bump). + ## Step 13: CHANGELOG (auto-generate) 1. Read `CHANGELOG.md` header to know the format. diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index 889d313ae..a2b9f4770 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -2519,6 +2519,12 @@ stay agent judgment; the slot pick stays `gstack-next-version`. ``` The CLI validates the 4-digit `MAJOR.MINOR.PATCH.MICRO` pattern and writes **both** VERSION and package.json. On a half-write (VERSION written, package.json failed) it exits 3 — re-run, and classify will report DRIFT_STALE_PKG for `repair` to fix. +5. **Record the release decision** (durable cross-session memory). The bump level is a real decision the next session should not re-derive blind: + ```bash + $GSTACK_ROOT/bin/gstack-decision-log '{"decision":"Ship NEW_VERSION (BUMP_LEVEL)","rationale":"WHY","scope":"repo","source":"skill","confidence":9}' 2>/dev/null || true + ``` + Substitute `NEW_VERSION`, `BUMP_LEVEL`, and a one-line `WHY` (the signal that set the level: diff scale, a new feature, a breaking change). Best-effort and non-interactive; never blocks the ship. Skip on the ALREADY_BUMPED path (the decision was logged on the run that did the bump). + ## Step 13: CHANGELOG (auto-generate) 1. Read `CHANGELOG.md` header to know the format.