diff --git a/review/sections/review-army.md b/review/sections/review-army.md index 36d1b340c..0e1b20417 100644 --- a/review/sections/review-army.md +++ b/review/sections/review-army.md @@ -8,7 +8,6 @@ _SM=$(~/.claude/skills/gstack/bin/gstack-state-matrix detect --base ) || _SM=SCOPE_STATE_MACHINE=unknown; source <(echo "$_SM") source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) || true set | grep '^SCOPE_' -# Detect stack STACK="" [ -f Gemfile ] && STACK="${STACK}ruby " [ -f package.json ] && STACK="${STACK}node " @@ -19,7 +18,7 @@ echo "STACK: ${STACK:-unknown}" DIFF_BASE=$(git merge-base origin/ HEAD) DIFF_LINES=$(git diff "$DIFF_BASE" --numstat | awk '{n+=$1+$2} END {print n+0}') echo "DIFF_LINES: $DIFF_LINES" -# Detect test framework for specialist test stub generation +# Detect test framework TEST_FW="" { [ -f jest.config.ts ] || [ -f jest.config.js ]; } && TEST_FW="jest" [ -f vitest.config.ts ] && TEST_FW="vitest" @@ -52,11 +51,9 @@ Based on the scope signals above, select which specialists to dispatch. 6. **API Contract** — if SCOPE_API=true. Read `~/.claude/skills/gstack/review/specialists/api-contract.md` 7. **Design** — if SCOPE_FRONTEND=true. Use the existing design review checklist at `~/.claude/skills/gstack/review/design-checklist.md` and run the mechanical pass at the top of that checklist (the user-installed design detector, when present) before the LLM items 8. **Simplification** — if DIFF_LINES > 100. Read `~/.claude/skills/gstack/review/specialists/simplification.md`. Advisory-only lens: hunts unrequested structure (hand-rolled stdlib, one-implementation abstractions, dependencies duplicating platform features), never coverage. -9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown (printed by the scope block): read `~/.claude/skills/gstack/review/specialists/state-machines.md`, then check its output: +9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown: read `~/.claude/skills/gstack/review/specialists/state-machines.md`, then write its full output to `.gstack/tmp/state-machines.md` and check it: ```bash -~/.claude/skills/gstack/bin/gstack-state-matrix check - <<'EOF' - -EOF +~/.claude/skills/gstack/bin/gstack-state-matrix check .gstack/tmp/state-machines.md ``` ### Adaptive gating diff --git a/scripts/resolvers/review-army.ts b/scripts/resolvers/review-army.ts index 1a4c4935c..a12fcb134 100644 --- a/scripts/resolvers/review-army.ts +++ b/scripts/resolvers/review-army.ts @@ -27,7 +27,6 @@ function generateSpecialistSelection(ctx: TemplateContext): string { _SM=$(${ctx.paths.binDir}/gstack-state-matrix detect --base ) || _SM=SCOPE_STATE_MACHINE=unknown; source <(echo "$_SM") source <(${ctx.paths.binDir}/gstack-diff-scope 2>/dev/null) || true set | grep '^SCOPE_' -# Detect stack STACK="" [ -f Gemfile ] && STACK="\${STACK}ruby " [ -f package.json ] && STACK="\${STACK}node " @@ -38,7 +37,7 @@ echo "STACK: \${STACK:-unknown}" DIFF_BASE=$(git merge-base origin/ HEAD) DIFF_LINES=$(git diff "$DIFF_BASE" --numstat | awk '{n+=$1+$2} END {print n+0}') echo "DIFF_LINES: $DIFF_LINES" -# Detect test framework for specialist test stub generation +# Detect test framework TEST_FW="" { [ -f jest.config.ts ] || [ -f jest.config.js ]; } && TEST_FW="jest" [ -f vitest.config.ts ] && TEST_FW="vitest" @@ -71,11 +70,9 @@ Based on the scope signals above, select which specialists to dispatch. 6. **API Contract** — if SCOPE_API=true. Read \`${ctx.paths.skillRoot}/review/specialists/api-contract.md\` 7. **Design** — if SCOPE_FRONTEND=true. Use the existing design review checklist at \`${ctx.paths.skillRoot}/review/design-checklist.md\` and run the mechanical pass at the top of that checklist (the user-installed design detector, when present) before the LLM items 8. **Simplification** — if DIFF_LINES > 100. Read \`${ctx.paths.skillRoot}/review/specialists/simplification.md\`. Advisory-only lens: hunts unrequested structure (hand-rolled stdlib, one-implementation abstractions, dependencies duplicating platform features), never coverage. -9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown (printed by the scope block): read \`${ctx.paths.skillRoot}/review/specialists/state-machines.md\`, then check its output: +9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown: read \`${ctx.paths.skillRoot}/review/specialists/state-machines.md\`, then write its full output to \`.gstack/tmp/state-machines.md\` and check it: \`\`\`bash -${ctx.paths.binDir}/gstack-state-matrix check - <<'EOF' - -EOF +${ctx.paths.binDir}/gstack-state-matrix check .gstack/tmp/state-machines.md \`\`\` ### Adaptive gating diff --git a/ship/sections/review-army.md b/ship/sections/review-army.md index 87a857032..0efb11a24 100644 --- a/ship/sections/review-army.md +++ b/ship/sections/review-army.md @@ -270,7 +270,6 @@ distinct defects stay separate and neither pass substitutes for the other. _SM=$(~/.claude/skills/gstack/bin/gstack-state-matrix detect --base ) || _SM=SCOPE_STATE_MACHINE=unknown; source <(echo "$_SM") source <(~/.claude/skills/gstack/bin/gstack-diff-scope 2>/dev/null) || true set | grep '^SCOPE_' -# Detect stack STACK="" [ -f Gemfile ] && STACK="${STACK}ruby " [ -f package.json ] && STACK="${STACK}node " @@ -281,7 +280,7 @@ echo "STACK: ${STACK:-unknown}" DIFF_BASE=$(git merge-base origin/ HEAD) DIFF_LINES=$(git diff "$DIFF_BASE" --numstat | awk '{n+=$1+$2} END {print n+0}') echo "DIFF_LINES: $DIFF_LINES" -# Detect test framework for specialist test stub generation +# Detect test framework TEST_FW="" { [ -f jest.config.ts ] || [ -f jest.config.js ]; } && TEST_FW="jest" [ -f vitest.config.ts ] && TEST_FW="vitest" @@ -314,11 +313,9 @@ Based on the scope signals above, select which specialists to dispatch. 6. **API Contract** — if SCOPE_API=true. Read `~/.claude/skills/gstack/review/specialists/api-contract.md` 7. **Design** — if SCOPE_FRONTEND=true. Use the existing design review checklist at `~/.claude/skills/gstack/review/design-checklist.md` and run the mechanical pass at the top of that checklist (the user-installed design detector, when present) before the LLM items 8. **Simplification** — if DIFF_LINES > 100. Read `~/.claude/skills/gstack/review/specialists/simplification.md`. Advisory-only lens: hunts unrequested structure (hand-rolled stdlib, one-implementation abstractions, dependencies duplicating platform features), never coverage. -9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown (printed by the scope block): read `~/.claude/skills/gstack/review/specialists/state-machines.md`, then check its output: +9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown: read `~/.claude/skills/gstack/review/specialists/state-machines.md`, then write its full output to `.gstack/tmp/state-machines.md` and check it: ```bash -~/.claude/skills/gstack/bin/gstack-state-matrix check - <<'EOF' - -EOF +~/.claude/skills/gstack/bin/gstack-state-matrix check .gstack/tmp/state-machines.md ``` ### Adaptive gating diff --git a/test/fixtures/skill-md-size-allowlist.json b/test/fixtures/skill-md-size-allowlist.json index 82dbfe751..9f5980083 100644 --- a/test/fixtures/skill-md-size-allowlist.json +++ b/test/fixtures/skill-md-size-allowlist.json @@ -37,7 +37,7 @@ "cursor/gstack-plan-design-review": 138935, "cursor/gstack-plan-devex-review": 134558, "cursor/gstack-plan-eng-review": 151523, - "cursor/gstack-review": 141043, + "cursor/gstack-review": 141010, "factory/gstack-autoplan": 131397, "factory/gstack-codex": 100523, "factory/gstack-design-consultation": 108523, @@ -47,7 +47,7 @@ "factory/gstack-plan-design-review": 141716, "factory/gstack-plan-devex-review": 137927, "factory/gstack-plan-eng-review": 154637, - "factory/gstack-review": 144825, + "factory/gstack-review": 144792, "gbrain/gstack-autoplan": 129650, "gbrain/gstack-design-review": 132733, "gbrain/gstack-land-and-deploy": 116039, @@ -67,7 +67,7 @@ "kiro/gstack-plan-design-review": 138775, "kiro/gstack-plan-devex-review": 134398, "kiro/gstack-plan-eng-review": 151373, - "kiro/gstack-review": 140849, + "kiro/gstack-review": 140816, "openclaw/gstack-autoplan": 129355, "openclaw/gstack-design-review": 131538, "openclaw/gstack-land-and-deploy": 115627, @@ -82,7 +82,7 @@ "opencode/gstack-plan-design-review": 140705, "opencode/gstack-plan-devex-review": 136779, "opencode/gstack-plan-eng-review": 153275, - "opencode/gstack-review": 143291, + "opencode/gstack-review": 143258, "slate/gstack-autoplan": 128994, "slate/gstack-design-consultation": 106996, "slate/gstack-design-review": 142272, @@ -90,6 +90,6 @@ "slate/gstack-plan-design-review": 138855, "slate/gstack-plan-devex-review": 134478, "slate/gstack-plan-eng-review": 151448, - "slate/gstack-review": 140946 + "slate/gstack-review": 140913 } } diff --git a/test/review-workflow-clarity.test.ts b/test/review-workflow-clarity.test.ts index 1f78c25a9..127575c14 100644 --- a/test/review-workflow-clarity.test.ts +++ b/test/review-workflow-clarity.test.ts @@ -387,8 +387,10 @@ for (const skillName of ['review', 'ship']) { expect(block).toContain(`_SM=$(${HOST_PATHS.claude.binDir}/gstack-state-matrix detect --base ) || _SM=SCOPE_STATE_MACHINE=unknown; source <(echo "$_SM")\n`); expect(block.indexOf('SCOPE_STATE_MACHINE=unknown')).toBeLessThan(block.indexOf("set | grep '^SCOPE_'")); const selection = between(army, '### Select specialists', '### Adaptive gating').replace(/\s+/g, ' '); - expect(selection).toContain('9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown (printed by the scope block)'); - expect(selection).toContain("gstack-state-matrix check - <<'EOF' EOF"); + expect(selection).toContain('9. **State Machines** — if SCOPE_STATE_MACHINE is true or unknown: read'); + expect(selection).toContain('then write its full output to `.gstack/tmp/state-machines.md` and check it:'); + expect(selection).toContain('gstack-state-matrix check .gstack/tmp/state-machines.md '); + expect(selection).not.toContain('<<'); expect(selection).not.toContain('pipe output'); });