From 33c6be4031a7463d47b8bca7d6410c1c255a1d75 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 14:30:06 -0700 Subject: [PATCH 01/12] feat(gstack2): add proportional-discovery overlay for session-scale builds (#886) A /plan Discovery run on a for-fun terminal toy burned ~115K output tokens: 10 one-at-a-time AskUserQuestion rounds, a consent-gated web search, a wireframe, outside-voice offers, a 3-iteration adversarial review loop, and a design doc with a Distribution Plan. The office-hours specialist scales every builder session to startup-diagnostic depth because nothing classifies build scale. Evidence for upstream issue #886 (GENERAL: Reduce Token Overhead, disposition NEEDS_EVIDENCE): session transcript ~/.claude/projects/-Users-sinabina-spacegame/b01e246b-*.jsonl. The overlay classifies session-scale vs product-scale after Phase 1 and, for session-scale builder sessions, batches remaining Phase 2B questions into one round, default-skips the landscape search, gates the sketch and outside voices on an explicit ask, caps adversarial review at one iteration, and sizes Next Steps in hours, not a phased roadmap. Both approval gates and startup-mode pressure are unchanged. Co-Authored-By: Claude Fable 5 --- scripts/gstack2/bug-fix-overlays.ts | 30 ++++++++++++++++++++++++++ scripts/gstack2/generate-skill-tree.ts | 8 +++---- scripts/gstack2/run-parity.ts | 9 ++++---- test/gstack2-skills.test.ts | 2 +- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/scripts/gstack2/bug-fix-overlays.ts b/scripts/gstack2/bug-fix-overlays.ts index 031bb4893a..04709b8e13 100644 --- a/scripts/gstack2/bug-fix-overlays.ts +++ b/scripts/gstack2/bug-fix-overlays.ts @@ -342,6 +342,22 @@ At the Phase 5 approval gate, print the full design-doc body as direct assistant expected: { print_doc_inline: true, before_approval_auq: true }, }, }, + { + pr: 886, + url: 'https://github.com/garrytan/gstack/issues/886', + title: 'Right-size discovery for session-scale builds', + targets: ['office-hours'], + anchor: 'GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY', + body: `### Proportional discovery for session-scale builds + +After Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2. + +For a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment.`, + regression: { + input: { mode: 'builder', goal: 'having fun', external_users: false, deployment_state: 'none' }, + expected: { scale: 'session', questions_batched: true, landscape_search: 'skip-unless-asked', sketch_offer: 'on-request', review_iterations_max: 1, roadmap_horizon: 'hours-to-days' }, + }, + }, { pr: 452, url: 'https://github.com/garrytan/gstack/pull/452', @@ -531,6 +547,20 @@ export function evaluateBugFixRegression(pr: number, rawInput: unknown): Record< } case 452: return { apply_repo_rules: input.claude_md_has_review_section === true, silent_skip_if_absent: true }; + case 886: { + const session = input.mode === 'builder' + && input.external_users !== true + && input.deployment_state !== 'production' + && /fun|learn|personal|toy|hobby|single.session/i.test(String(input.goal ?? '')); + return { + scale: session ? 'session' : 'product', + questions_batched: session, + landscape_search: session ? 'skip-unless-asked' : 'privacy-gated-offer', + sketch_offer: session ? 'on-request' : 'default-offer', + review_iterations_max: session ? 1 : 3, + roadmap_horizon: session ? 'hours-to-days' : 'stage-appropriate', + }; + } default: throw new Error(`No executable GStack 2 regression evaluator for PR #${pr}`); } diff --git a/scripts/gstack2/generate-skill-tree.ts b/scripts/gstack2/generate-skill-tree.ts index 92d2a9fae5..80427a73ae 100644 --- a/scripts/gstack2/generate-skill-tree.ts +++ b/scripts/gstack2/generate-skill-tree.ts @@ -82,7 +82,7 @@ function assertInventory(): void { } if (legacySections().length !== 16) throw new Error(`Expected 16 section templates, found ${legacySections().length}`); if (SCENARIOS.length !== 25) throw new Error(`Expected 25 parity scenarios, found ${SCENARIOS.length}`); - if (BUG_FIX_OVERLAYS.length !== 25) throw new Error(`Expected 25 upstream judgment overlays, found ${BUG_FIX_OVERLAYS.length}`); + if (BUG_FIX_OVERLAYS.length !== 26) throw new Error(`Expected 26 upstream judgment overlays, found ${BUG_FIX_OVERLAYS.length}`); } function toc(body: string): string { @@ -159,7 +159,7 @@ function renderModule(assignment: SourceAssignment): { content: string; renderSh : overlays.length ? 'BUG_FIX' : 'JUDGMENT_PRESERVING_CARVE'; const overlayText = overlays.map((overlay) => [ ``, - `## Upstream judgment port: PR #${overlay.pr}`, + `## Upstream judgment port: ${overlay.url.includes('/issues/') ? 'issue' : 'PR'} #${overlay.pr}`, '', `[${overlay.title}](${overlay.url})`, '', @@ -742,7 +742,7 @@ ${rows} ## Mechanical versus judgment changes - \`JUDGMENT_PRESERVING_CARVE\`: pinned specialist workflow with the retired shared onboarding wrapper excluded, retired invocations resolved to six public routes, host/runtime paths normalized, and large carved phases loaded lazily from package-local pinned references. -- \`BUG_FIX\`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 25 upstream PRs and its regression fixture. +- \`BUG_FIX\`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 26 upstream PRs and issues and its regression fixture. - Asset relocation is byte-for-byte from the pinned Git blob and is indexed per tree. `; } @@ -763,7 +763,7 @@ function parityDoc(assetCount: number): string { Parity is executable, not a prose claim. Run \`bun run scripts/gstack2/run-parity.ts\` or the dedicated Bun tests. -The pinned release inventory passes **${EXPECTED_PARITY_CHECKS.toLocaleString('en-US')} checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 25 regression ports, and **${assetCount} assets**. +The pinned release inventory passes **${EXPECTED_PARITY_CHECKS.toLocaleString('en-US')} checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 26 regression ports, and **${assetCount} assets**. The suite verifies: diff --git a/scripts/gstack2/run-parity.ts b/scripts/gstack2/run-parity.ts index 252ce95197..c55af64ebd 100644 --- a/scripts/gstack2/run-parity.ts +++ b/scripts/gstack2/run-parity.ts @@ -17,8 +17,9 @@ const ALLOWED_DISPOSITIONS = new Set(['VERBATIM_PORT', 'MECHANICAL_PORT', 'JUDGM // accounted for the 16 lazy-section checks; the remaining 136 cover runtime // contracts, retired-invocation guards, and generated package closure. Porting // six more upstream judgment overlays (16 -> 22) added 30 checks. Three more -// Tier-2 overlays (22 -> 25) added 15 checks (5 per overlay). -export const EXPECTED_PARITY_CHECKS = 4881; +// Tier-2 overlays (22 -> 25) added 15 checks (5 per overlay). The +// proportional-discovery overlay for issue #886 (25 -> 26) added 5 more. +export const EXPECTED_PARITY_CHECKS = 4886; function sha256(value: string | Uint8Array): string { return createHash('sha256').update(value).digest('hex'); @@ -253,8 +254,8 @@ export function runParity(): ParityResult { check(JSON.stringify(json(path.join(ROOT, 'evals', 'parity', 'scenarios', `${scenario.id}.json`))) === JSON.stringify(scenario), `${scenario.id} generated fixture drift`); } - check(BUG_FIX_OVERLAYS.length === 25, `Expected 25 regression definitions; got ${BUG_FIX_OVERLAYS.length}`); - check(files(path.join(ROOT, 'evals', 'parity', 'regressions'), '.json').length === 25, 'Generated regression fixture count is not 25'); + check(BUG_FIX_OVERLAYS.length === 26, `Expected 26 regression definitions; got ${BUG_FIX_OVERLAYS.length}`); + check(files(path.join(ROOT, 'evals', 'parity', 'regressions'), '.json').length === 26, 'Generated regression fixture count is not 26'); for (const overlay of BUG_FIX_OVERLAYS) { const fixture = json(path.join(ROOT, 'evals', 'parity', 'regressions', `pr-${overlay.pr}.json`)); check(JSON.stringify(fixture) === JSON.stringify(overlay), `PR #${overlay.pr} regression fixture drift`); diff --git a/test/gstack2-skills.test.ts b/test/gstack2-skills.test.ts index 9ace6c93db..798a5d01a0 100644 --- a/test/gstack2-skills.test.ts +++ b/test/gstack2-skills.test.ts @@ -27,7 +27,7 @@ describe('GStack 2 skill parity', () => { const result = runParity(); expect(result.sources).toBe(55); expect(result.sections).toBe(16); - expect(result.regressions).toBe(25); + expect(result.regressions).toBe(26); }, 30_000); test('keeps image generation host-native, optional, and provider-free', () => { From f455a43abac276b88158ea5dc63da6f00f4ac14e Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 14:30:06 -0700 Subject: [PATCH 02/12] chore(gstack2): regenerate skill tree for the #886 proportional-discovery overlay Co-Authored-By: Claude Fable 5 --- docs/gstack-2/JUDGMENT-PARITY.md | 2 +- docs/gstack-2/JUDGMENT-PROVENANCE.json | 12 ++++++++- docs/gstack-2/SKILL-MIGRATION.md | 4 +-- evals/parity/contracts/office-hours.json | 3 ++- evals/parity/manifest.json | 12 ++++++++- evals/parity/regressions/pr-886.json | 26 +++++++++++++++++++ .../deterministic/office-hours.json | 7 +++++ skills/plan/references/legacy/office-hours.md | 12 +++++++++ 8 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 evals/parity/regressions/pr-886.json diff --git a/docs/gstack-2/JUDGMENT-PARITY.md b/docs/gstack-2/JUDGMENT-PARITY.md index c0aed2787e..74debc35a6 100644 --- a/docs/gstack-2/JUDGMENT-PARITY.md +++ b/docs/gstack-2/JUDGMENT-PARITY.md @@ -2,7 +2,7 @@ Parity is executable, not a prose claim. Run `bun run scripts/gstack2/run-parity.ts` or the dedicated Bun tests. -The pinned release inventory passes **4,881 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 25 regression ports, and **78 assets**. +The pinned release inventory passes **4,886 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 26 regression ports, and **78 assets**. The suite verifies: diff --git a/docs/gstack-2/JUDGMENT-PROVENANCE.json b/docs/gstack-2/JUDGMENT-PROVENANCE.json index ac3b722559..480e45d514 100644 --- a/docs/gstack-2/JUDGMENT-PROVENANCE.json +++ b/docs/gstack-2/JUDGMENT-PROVENANCE.json @@ -90,7 +90,8 @@ 679, 2030, 1049, - 1116 + 1116, + 886 ], "original_source_file": "office-hours/SKILL.md.tmpl", "original_line_range": "1-526", @@ -7413,6 +7414,15 @@ ], "anchor": "GSTACK2_FIX_1116_INLINE_APPROVAL_DOC" }, + { + "pr": 886, + "url": "https://github.com/garrytan/gstack/issues/886", + "title": "Right-size discovery for session-scale builds", + "targets": [ + "office-hours" + ], + "anchor": "GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY" + }, { "pr": 452, "url": "https://github.com/garrytan/gstack/pull/452", diff --git a/docs/gstack-2/SKILL-MIGRATION.md b/docs/gstack-2/SKILL-MIGRATION.md index 0f90b0b46d..aefed2d5ed 100644 --- a/docs/gstack-2/SKILL-MIGRATION.md +++ b/docs/gstack-2/SKILL-MIGRATION.md @@ -11,7 +11,7 @@ The fixed public modes are: Design = `Explore | Generate | Critique | Implement` | Legacy invocation | Replacement | Visibility | Mandatory | Judgment overlays | |---|---|---|---|---| | `/gstack` | `$plan --mode Discovery --module gstack` | internal (internal) | no | #679 | -| `/office-hours` | `$plan --mode Discovery --module office-hours` | internal (primary) | yes | #679, #2030, #1049, #1116 | +| `/office-hours` | `$plan --mode Discovery --module office-hours` | internal (primary) | yes | #679, #2030, #1049, #1116, #886 | | `/plan-ceo-review` | `$plan --mode Product --module plan-ceo-review` | internal (primary) | yes | #679, #2030 | | `/plan-eng-review` | `$plan --mode Engineering --module plan-eng-review` | internal (primary) | yes | #679, #1071, #2030, #592 | | `/plan-devex-review` | `$plan --mode DX --module plan-devex-review` | internal (primary) | yes | #679, #2030 | @@ -75,5 +75,5 @@ The fixed public modes are: Design = `Explore | Generate | Critique | Implement` ## Mechanical versus judgment changes - `JUDGMENT_PRESERVING_CARVE`: pinned specialist workflow with the retired shared onboarding wrapper excluded, retired invocations resolved to six public routes, host/runtime paths normalized, and large carved phases loaded lazily from package-local pinned references. -- `BUG_FIX`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 25 upstream PRs and its regression fixture. +- `BUG_FIX`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 26 upstream PRs and issues and its regression fixture. - Asset relocation is byte-for-byte from the pinned Git blob and is indexed per tree. diff --git a/evals/parity/contracts/office-hours.json b/evals/parity/contracts/office-hours.json index 666dc0077c..a1eebb8d6f 100644 --- a/evals/parity/contracts/office-hours.json +++ b/evals/parity/contracts/office-hours.json @@ -15,7 +15,8 @@ 679, 2030, 1049, - 1116 + 1116, + 886 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/manifest.json b/evals/parity/manifest.json index ac3b722559..480e45d514 100644 --- a/evals/parity/manifest.json +++ b/evals/parity/manifest.json @@ -90,7 +90,8 @@ 679, 2030, 1049, - 1116 + 1116, + 886 ], "original_source_file": "office-hours/SKILL.md.tmpl", "original_line_range": "1-526", @@ -7413,6 +7414,15 @@ ], "anchor": "GSTACK2_FIX_1116_INLINE_APPROVAL_DOC" }, + { + "pr": 886, + "url": "https://github.com/garrytan/gstack/issues/886", + "title": "Right-size discovery for session-scale builds", + "targets": [ + "office-hours" + ], + "anchor": "GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY" + }, { "pr": 452, "url": "https://github.com/garrytan/gstack/pull/452", diff --git a/evals/parity/regressions/pr-886.json b/evals/parity/regressions/pr-886.json new file mode 100644 index 0000000000..a2975edd41 --- /dev/null +++ b/evals/parity/regressions/pr-886.json @@ -0,0 +1,26 @@ +{ + "pr": 886, + "url": "https://github.com/garrytan/gstack/issues/886", + "title": "Right-size discovery for session-scale builds", + "targets": [ + "office-hours" + ], + "anchor": "GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY", + "body": "### Proportional discovery for session-scale builds\n\nAfter Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2.\n\nFor a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment.", + "regression": { + "input": { + "mode": "builder", + "goal": "having fun", + "external_users": false, + "deployment_state": "none" + }, + "expected": { + "scale": "session", + "questions_batched": true, + "landscape_search": "skip-unless-asked", + "sketch_offer": "on-request", + "review_iterations_max": 1, + "roadmap_horizon": "hours-to-days" + } + } +} diff --git a/evals/parity/transcripts/deterministic/office-hours.json b/evals/parity/transcripts/deterministic/office-hours.json index 2dfa0becfa..8fca45a7fd 100644 --- a/evals/parity/transcripts/deterministic/office-hours.json +++ b/evals/parity/transcripts/deterministic/office-hours.json @@ -109,6 +109,13 @@ "reproduced_defect": "Print the design doc inline before the approval gate", "regression_fixture": "evals/parity/regressions/pr-1116.json", "explanation": "### Inline design doc at the approval gate\n\nAt the Phase 5 approval gate, print the full design-doc body as direct assistant text before the Approve/Revise/Start-over AskUserQuestion. Do not point the user at the file path and do not rely on a `Bash cat` or `Read` tool call to display it: tool outputs are frequently collapsed in the Claude Code UI, which leaves the user approving a document they cannot see. The assistant message is the one surface guaranteed to render, so emit a short preamble naming the saved path followed by the verbatim document body, then ask for approval." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/886", + "reproduced_defect": "Right-size discovery for session-scale builds", + "regression_fixture": "evals/parity/regressions/pr-886.json", + "explanation": "### Proportional discovery for session-scale builds\n\nAfter Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2.\n\nFor a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment." } ] } diff --git a/skills/plan/references/legacy/office-hours.md b/skills/plan/references/legacy/office-hours.md index 4909fd0501..4e293fbf84 100644 --- a/skills/plan/references/legacy/office-hours.md +++ b/skills/plan/references/legacy/office-hours.md @@ -770,3 +770,15 @@ The design doc file is the artifact of this session. Before the telemetry block At the Phase 5 approval gate, print the full design-doc body as direct assistant text before the Approve/Revise/Start-over AskUserQuestion. Do not point the user at the file path and do not rely on a `Bash cat` or `Read` tool call to display it: tool outputs are frequently collapsed in the Claude Code UI, which leaves the user approving a document they cannot see. The assistant message is the one surface guaranteed to render, so emit a short preamble naming the saved path followed by the verbatim document body, then ask for approval. + + +## Upstream judgment port: issue #886 + +[Right-size discovery for session-scale builds](https://github.com/garrytan/gstack/issues/886) + +### Proportional discovery for session-scale builds + +After Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2. + +For a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment. + From 1961526ca5b7c5617e7556baf3e94ed5356de431 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 14:52:44 -0700 Subject: [PATCH 03/12] feat(gstack2): generalize #886 to build-scale classification across all /plan specialists The first cut only right-sized office-hours builder mode. Any planning specialist can over-treat a small ask, so scale detection now lives in the /plan dispatcher itself: a Scale header line classified from fifteen build-scale vectors (audience, users, commercial intent, deployment, horizon, maintenance, integration surface, extensibility, data sensitivity, stakes, team, codebase, reversibility, distribution, compliance). Highest vector wins; unknown vectors default low; never ask questions just to classify. "A cool space animation in my terminal" is session-scale; "a startup with customizable APIs" is venture-scale. Overlay #886 now targets all six planning specialists (office-hours, plan-ceo-review, plan-eng-review, plan-devex-review, spec, autoplan) and keys its proportionality budgets (question batching, research and outside-voice gating, review-iteration caps, artifact size, step units) off the printed Scale. product/venture scale changes nothing; STOP and approval gates are unchanged at every scale. Co-Authored-By: Claude Fable 5 --- scripts/gstack2/bug-fix-overlays.ts | 62 ++++++++++++++++++-------- scripts/gstack2/generate-skill-tree.ts | 22 +++++++-- scripts/gstack2/run-parity.ts | 5 ++- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/scripts/gstack2/bug-fix-overlays.ts b/scripts/gstack2/bug-fix-overlays.ts index 04709b8e13..47c2dd41d7 100644 --- a/scripts/gstack2/bug-fix-overlays.ts +++ b/scripts/gstack2/bug-fix-overlays.ts @@ -345,17 +345,22 @@ At the Phase 5 approval gate, print the full design-doc body as direct assistant { pr: 886, url: 'https://github.com/garrytan/gstack/issues/886', - title: 'Right-size discovery for session-scale builds', - targets: ['office-hours'], - anchor: 'GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY', - body: `### Proportional discovery for session-scale builds + title: 'Scale planning machinery to the printed build scale', + targets: ['office-hours', 'plan-ceo-review', 'plan-eng-review', 'plan-devex-review', 'spec', 'autoplan'], + anchor: 'GSTACK2_FIX_886_PROPORTIONAL_PLANNING', + body: `### Proportional planning for the printed build scale + +The /plan dispatcher prints a \`Scale:\` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. -After Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2. +- \`session\` and \`hobby\`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- \`project\`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- \`product\` and \`venture\`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. -For a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment.`, +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration.`, regression: { - input: { mode: 'builder', goal: 'having fun', external_users: false, deployment_state: 'none' }, - expected: { scale: 'session', questions_batched: true, landscape_search: 'skip-unless-asked', sketch_offer: 'on-request', review_iterations_max: 1, roadmap_horizon: 'hours-to-days' }, + input: { audience: 'self', users: 'none', commercial: 'none', deployment: 'none', horizon: 'session', stakes: 'fun', extensibility: 'fixed' }, + expected: { scale: 'session', questions_batched: true, question_rounds_max: 1, web_search: 'on-request', outside_voices: 'on-request', review_iterations_max: 1, step_unit: 'hours' }, }, }, { @@ -548,17 +553,38 @@ export function evaluateBugFixRegression(pr: number, rawInput: unknown): Record< case 452: return { apply_repo_rules: input.claude_md_has_review_section === true, silent_skip_if_absent: true }; case 886: { - const session = input.mode === 'builder' - && input.external_users !== true - && input.deployment_state !== 'production' - && /fun|learn|personal|toy|hobby|single.session/i.test(String(input.goal ?? '')); + const ranks: Record> = { + audience: { self: 0, friends: 1, team: 2, public: 3 }, + users: { none: 0, handful: 1, many: 3 }, + commercial: { none: 0, maybe: 2, core: 4 }, + deployment: { none: 0, local: 0, hosted: 2, production: 3 }, + horizon: { session: 0, days: 1, weeks: 2, months: 4 }, + maintenance: { throwaway: 0, kept: 1, maintained: 2 }, + integration: { standalone: 0, 'consumes-apis': 1, 'exposes-apis': 3, 'multi-service': 3 }, + extensibility: { fixed: 0, configurable: 2, 'customizable-platform': 4 }, + data: { none: 0, personal: 2, regulated: 4 }, + stakes: { fun: 0, annoyance: 1, money: 3, safety: 4 }, + team: { solo: 0, few: 2, org: 3 }, + codebase: { greenfield: 0, existing: 1, 'legacy-production': 3 }, + reversibility: { discardable: 0, breaking: 3 }, + distribution: { private: 0, shared: 1, published: 3 }, + compliance: { none: 0, some: 2, audited: 4 }, + }; + // Highest tier any vector demands wins; unknown vectors default low. + const rank = Object.entries(ranks).reduce( + (max, [vector, levels]) => Math.max(max, levels[String(input[vector] ?? '')] ?? 0), + 0, + ); + const scale = ['session', 'hobby', 'project', 'product', 'venture'][rank]; + const small = rank <= 1; return { - scale: session ? 'session' : 'product', - questions_batched: session, - landscape_search: session ? 'skip-unless-asked' : 'privacy-gated-offer', - sketch_offer: session ? 'on-request' : 'default-offer', - review_iterations_max: session ? 1 : 3, - roadmap_horizon: session ? 'hours-to-days' : 'stage-appropriate', + scale, + questions_batched: rank <= 2, + question_rounds_max: small ? rank + 1 : null, + web_search: small ? 'on-request' : 'privacy-gated-offer', + outside_voices: small ? 'on-request' : 'offer', + review_iterations_max: small ? 1 : 3, + step_unit: ['hours', 'days', 'weeks', 'stage-appropriate', 'stage-appropriate'][rank], }; } default: diff --git a/scripts/gstack2/generate-skill-tree.ts b/scripts/gstack2/generate-skill-tree.ts index 80427a73ae..17dd049676 100644 --- a/scripts/gstack2/generate-skill-tree.ts +++ b/scripts/gstack2/generate-skill-tree.ts @@ -203,7 +203,23 @@ function rootSkill(dispatcher: DispatcherDefinition): string { ? '\n9. When `system-functional` is active, read `references/SYSTEM-FUNCTIONAL.md` completely and execute it alongside the selected preserved specialists.\n' : dispatcher.name === 'ship' ? '\n9. Before push, PR creation/update, merge, deploy, rollback, release publication, or external notification, read `references/EXTERNAL-EFFECTS.md` and execute the action through its durable state wrapper.\n' - : ''; + : dispatcher.name === 'plan' + ? '\n9. Classify the Scale header line from the Build scale section before any questioning begins. Every planning specialist applies its proportional-planning judgment port to that scale.\n' + : ''; + const scaleLine = dispatcher.name === 'plan' + ? 'Scale: \n' + : ''; + const buildScale = dispatcher.name === 'plan' + ? ` +## Build scale + +Classify the request on fifteen scale vectors before any questioning begins, from the prompt and cheap repository evidence only. Never run a questioning round merely to classify scale. Default unknown vectors to the low end; the specialist's own workflow raises the scale naturally when answers reveal more (builder talk turning into startup talk upgrades mid-session). + +Vectors: audience (self → friends/team → public), expected users (none → handful → many), commercial intent (none → maybe → core), deployment target (none/local → hosted → production), time horizon (one sitting → days → weeks → months+), maintenance expectation (throwaway → kept → maintained), integration surface (standalone → consumes APIs → exposes APIs/multi-service), extensibility ask (fixed → configurable → customizable platform), data sensitivity (none → personal → regulated), failure stakes (lost fun → annoyance → money/trust/safety), team (solo → few → org), codebase (greenfield → existing repo → legacy production), reversibility (discardable → migrations/breaking changes), distribution (private → shared → published), compliance (none → some → audited). + +The highest tier any vector demands wins: \`session\` (all vectors low — one sitting, for fun, self only), \`hobby\` (kept personal tool, days), \`project\` (shared or in a real repo, weeks), \`product\` (external users, hosted, revenue intent), \`venture\` (startup ambition, platform/API surface, team, months+). "A cool space animation in my terminal" is session-scale. "A startup with customizable APIs" is venture-scale. Print the result on the header's Scale line with the two or three vectors that decided it. +` + : ''; return `--- name: ${dispatcher.name} @@ -223,7 +239,7 @@ Before any substantive output, print these exact labels in this exact order. Res Target: Mode: Depth: -Mutation: +${scaleLine}Mutation: Active modules: Skipped modules: Web context: @@ -239,7 +255,7 @@ Web context: 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 8. At exit, report completed artifacts, evidence, unresolved decisions, skipped modules with reasons, and any blocked gate. -${supplemental} +${supplemental}${buildScale} ## Top-level modes diff --git a/scripts/gstack2/run-parity.ts b/scripts/gstack2/run-parity.ts index c55af64ebd..8d74790a1e 100644 --- a/scripts/gstack2/run-parity.ts +++ b/scripts/gstack2/run-parity.ts @@ -18,8 +18,9 @@ const ALLOWED_DISPOSITIONS = new Set(['VERBATIM_PORT', 'MECHANICAL_PORT', 'JUDGM // contracts, retired-invocation guards, and generated package closure. Porting // six more upstream judgment overlays (16 -> 22) added 30 checks. Three more // Tier-2 overlays (22 -> 25) added 15 checks (5 per overlay). The -// proportional-discovery overlay for issue #886 (25 -> 26) added 5 more. -export const EXPECTED_PARITY_CHECKS = 4886; +// proportional-planning overlay for issue #886 (25 -> 26, six plan-tree +// targets) added 15 more (2 per targeted module + 3 regression checks). +export const EXPECTED_PARITY_CHECKS = 4896; function sha256(value: string | Uint8Array): string { return createHash('sha256').update(value).digest('hex'); From b2fe7f9de3bad1692461d1284868e149f349be77 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 14:52:44 -0700 Subject: [PATCH 04/12] chore(gstack2): regenerate skill tree for build-scale proportional planning Co-Authored-By: Claude Fable 5 --- docs/gstack-2/JUDGMENT-PARITY.md | 2 +- docs/gstack-2/JUDGMENT-PROVENANCE.json | 26 +++++++++++----- docs/gstack-2/SKILL-MIGRATION.md | 10 +++--- evals/parity/contracts/autoplan.json | 3 +- evals/parity/contracts/plan-ceo-review.json | 3 +- evals/parity/contracts/plan-devex-review.json | 3 +- evals/parity/contracts/plan-eng-review.json | 3 +- evals/parity/contracts/spec.json | 3 +- evals/parity/manifest.json | 26 +++++++++++----- evals/parity/regressions/pr-886.json | 31 ++++++++++++------- .../transcripts/deterministic/ceo-review.json | 7 +++++ .../transcripts/deterministic/dx-review.json | 7 +++++ .../deterministic/engineering-review.json | 7 +++++ .../deterministic/office-hours.json | 4 +-- .../deterministic/specification.json | 7 +++++ evals/parity/transcripts/policy-units.json | 2 +- skills/plan/SKILL.md | 11 +++++++ skills/plan/references/legacy/autoplan.md | 17 ++++++++++ skills/plan/references/legacy/office-hours.md | 15 ++++++--- .../plan/references/legacy/plan-ceo-review.md | 17 ++++++++++ .../references/legacy/plan-devex-review.md | 17 ++++++++++ .../plan/references/legacy/plan-eng-review.md | 17 ++++++++++ skills/plan/references/legacy/spec.md | 17 ++++++++++ 23 files changed, 209 insertions(+), 46 deletions(-) diff --git a/docs/gstack-2/JUDGMENT-PARITY.md b/docs/gstack-2/JUDGMENT-PARITY.md index 74debc35a6..e7e5c62034 100644 --- a/docs/gstack-2/JUDGMENT-PARITY.md +++ b/docs/gstack-2/JUDGMENT-PARITY.md @@ -2,7 +2,7 @@ Parity is executable, not a prose claim. Run `bun run scripts/gstack2/run-parity.ts` or the dedicated Bun tests. -The pinned release inventory passes **4,886 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 26 regression ports, and **78 assets**. +The pinned release inventory passes **4,896 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 26 regression ports, and **78 assets**. The suite verifies: diff --git a/docs/gstack-2/JUDGMENT-PROVENANCE.json b/docs/gstack-2/JUDGMENT-PROVENANCE.json index 480e45d514..156ac168bd 100644 --- a/docs/gstack-2/JUDGMENT-PROVENANCE.json +++ b/docs/gstack-2/JUDGMENT-PROVENANCE.json @@ -205,7 +205,8 @@ "disposition": "BUG_FIX", "overlays": [ 679, - 2030 + 2030, + 886 ], "original_source_file": "plan-ceo-review/SKILL.md.tmpl", "original_line_range": "1-427", @@ -347,7 +348,8 @@ 679, 1071, 2030, - 592 + 592, + 886 ], "original_source_file": "plan-eng-review/SKILL.md.tmpl", "original_line_range": "1-158", @@ -466,7 +468,8 @@ "disposition": "BUG_FIX", "overlays": [ 679, - 2030 + 2030, + 886 ], "original_source_file": "plan-devex-review/SKILL.md.tmpl", "original_line_range": "1-462", @@ -600,7 +603,8 @@ "overlays": [ 679, 2014, - 2023 + 2023, + 886 ], "original_source_file": "autoplan/SKILL.md.tmpl", "original_line_range": "1-916", @@ -689,7 +693,8 @@ "target": "skills/plan/references/legacy/spec.md", "disposition": "BUG_FIX", "overlays": [ - 679 + 679, + 886 ], "original_source_file": "spec/SKILL.md.tmpl", "original_line_range": "1-769", @@ -7417,11 +7422,16 @@ { "pr": 886, "url": "https://github.com/garrytan/gstack/issues/886", - "title": "Right-size discovery for session-scale builds", + "title": "Scale planning machinery to the printed build scale", "targets": [ - "office-hours" + "office-hours", + "plan-ceo-review", + "plan-eng-review", + "plan-devex-review", + "spec", + "autoplan" ], - "anchor": "GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY" + "anchor": "GSTACK2_FIX_886_PROPORTIONAL_PLANNING" }, { "pr": 452, diff --git a/docs/gstack-2/SKILL-MIGRATION.md b/docs/gstack-2/SKILL-MIGRATION.md index aefed2d5ed..d514823369 100644 --- a/docs/gstack-2/SKILL-MIGRATION.md +++ b/docs/gstack-2/SKILL-MIGRATION.md @@ -12,11 +12,11 @@ The fixed public modes are: Design = `Explore | Generate | Critique | Implement` |---|---|---|---|---| | `/gstack` | `$plan --mode Discovery --module gstack` | internal (internal) | no | #679 | | `/office-hours` | `$plan --mode Discovery --module office-hours` | internal (primary) | yes | #679, #2030, #1049, #1116, #886 | -| `/plan-ceo-review` | `$plan --mode Product --module plan-ceo-review` | internal (primary) | yes | #679, #2030 | -| `/plan-eng-review` | `$plan --mode Engineering --module plan-eng-review` | internal (primary) | yes | #679, #1071, #2030, #592 | -| `/plan-devex-review` | `$plan --mode DX --module plan-devex-review` | internal (primary) | yes | #679, #2030 | -| `/autoplan` | `$plan --mode Full chain --module autoplan` | internal (primary) | yes | #679, #2014, #2023 | -| `/spec` | `$plan --mode Specification --module spec` | internal (primary) | yes | #679 | +| `/plan-ceo-review` | `$plan --mode Product --module plan-ceo-review` | internal (primary) | yes | #679, #2030, #886 | +| `/plan-eng-review` | `$plan --mode Engineering --module plan-eng-review` | internal (primary) | yes | #679, #1071, #2030, #592, #886 | +| `/plan-devex-review` | `$plan --mode DX --module plan-devex-review` | internal (primary) | yes | #679, #2030, #886 | +| `/autoplan` | `$plan --mode Full chain --module autoplan` | internal (primary) | yes | #679, #2014, #2023, #886 | +| `/spec` | `$plan --mode Specification --module spec` | internal (primary) | yes | #679, #886 | | `/plan-tune` | `$plan --mode Discovery --module plan-tune` | internal (primary) | yes | #679 | | `/context-save` | `$plan --mode Discovery --module context-save` | internal (internal) | no | #679 | | `/context-restore` | `$plan --mode Discovery --module context-restore` | internal (internal) | no | #679 | diff --git a/evals/parity/contracts/autoplan.json b/evals/parity/contracts/autoplan.json index 1282d343bc..e7cf23397d 100644 --- a/evals/parity/contracts/autoplan.json +++ b/evals/parity/contracts/autoplan.json @@ -14,7 +14,8 @@ "overlays": [ 679, 2014, - 2023 + 2023, + 886 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/plan-ceo-review.json b/evals/parity/contracts/plan-ceo-review.json index 700a85d233..375a2988b1 100644 --- a/evals/parity/contracts/plan-ceo-review.json +++ b/evals/parity/contracts/plan-ceo-review.json @@ -13,7 +13,8 @@ "target": "skills/plan/references/legacy/plan-ceo-review.md", "overlays": [ 679, - 2030 + 2030, + 886 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/plan-devex-review.json b/evals/parity/contracts/plan-devex-review.json index d8624cbb62..d9507fc907 100644 --- a/evals/parity/contracts/plan-devex-review.json +++ b/evals/parity/contracts/plan-devex-review.json @@ -13,7 +13,8 @@ "target": "skills/plan/references/legacy/plan-devex-review.md", "overlays": [ 679, - 2030 + 2030, + 886 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/plan-eng-review.json b/evals/parity/contracts/plan-eng-review.json index 3da0652ab1..287fde4d76 100644 --- a/evals/parity/contracts/plan-eng-review.json +++ b/evals/parity/contracts/plan-eng-review.json @@ -15,7 +15,8 @@ 679, 1071, 2030, - 592 + 592, + 886 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/spec.json b/evals/parity/contracts/spec.json index 7eeb62e502..037a71024b 100644 --- a/evals/parity/contracts/spec.json +++ b/evals/parity/contracts/spec.json @@ -12,7 +12,8 @@ "normalized_render_sha256": "76b7c03e6d8e7b852beda0a58409d97153771dd8f7b870bbdda23e996ac23fc1", "target": "skills/plan/references/legacy/spec.md", "overlays": [ - 679 + 679, + 886 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/manifest.json b/evals/parity/manifest.json index 480e45d514..156ac168bd 100644 --- a/evals/parity/manifest.json +++ b/evals/parity/manifest.json @@ -205,7 +205,8 @@ "disposition": "BUG_FIX", "overlays": [ 679, - 2030 + 2030, + 886 ], "original_source_file": "plan-ceo-review/SKILL.md.tmpl", "original_line_range": "1-427", @@ -347,7 +348,8 @@ 679, 1071, 2030, - 592 + 592, + 886 ], "original_source_file": "plan-eng-review/SKILL.md.tmpl", "original_line_range": "1-158", @@ -466,7 +468,8 @@ "disposition": "BUG_FIX", "overlays": [ 679, - 2030 + 2030, + 886 ], "original_source_file": "plan-devex-review/SKILL.md.tmpl", "original_line_range": "1-462", @@ -600,7 +603,8 @@ "overlays": [ 679, 2014, - 2023 + 2023, + 886 ], "original_source_file": "autoplan/SKILL.md.tmpl", "original_line_range": "1-916", @@ -689,7 +693,8 @@ "target": "skills/plan/references/legacy/spec.md", "disposition": "BUG_FIX", "overlays": [ - 679 + 679, + 886 ], "original_source_file": "spec/SKILL.md.tmpl", "original_line_range": "1-769", @@ -7417,11 +7422,16 @@ { "pr": 886, "url": "https://github.com/garrytan/gstack/issues/886", - "title": "Right-size discovery for session-scale builds", + "title": "Scale planning machinery to the printed build scale", "targets": [ - "office-hours" + "office-hours", + "plan-ceo-review", + "plan-eng-review", + "plan-devex-review", + "spec", + "autoplan" ], - "anchor": "GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY" + "anchor": "GSTACK2_FIX_886_PROPORTIONAL_PLANNING" }, { "pr": 452, diff --git a/evals/parity/regressions/pr-886.json b/evals/parity/regressions/pr-886.json index a2975edd41..c9b6961b48 100644 --- a/evals/parity/regressions/pr-886.json +++ b/evals/parity/regressions/pr-886.json @@ -1,26 +1,35 @@ { "pr": 886, "url": "https://github.com/garrytan/gstack/issues/886", - "title": "Right-size discovery for session-scale builds", + "title": "Scale planning machinery to the printed build scale", "targets": [ - "office-hours" + "office-hours", + "plan-ceo-review", + "plan-eng-review", + "plan-devex-review", + "spec", + "autoplan" ], - "anchor": "GSTACK2_FIX_886_PROPORTIONAL_DISCOVERY", - "body": "### Proportional discovery for session-scale builds\n\nAfter Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2.\n\nFor a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment.", + "anchor": "GSTACK2_FIX_886_PROPORTIONAL_PLANNING", + "body": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration.", "regression": { "input": { - "mode": "builder", - "goal": "having fun", - "external_users": false, - "deployment_state": "none" + "audience": "self", + "users": "none", + "commercial": "none", + "deployment": "none", + "horizon": "session", + "stakes": "fun", + "extensibility": "fixed" }, "expected": { "scale": "session", "questions_batched": true, - "landscape_search": "skip-unless-asked", - "sketch_offer": "on-request", + "question_rounds_max": 1, + "web_search": "on-request", + "outside_voices": "on-request", "review_iterations_max": 1, - "roadmap_horizon": "hours-to-days" + "step_unit": "hours" } } } diff --git a/evals/parity/transcripts/deterministic/ceo-review.json b/evals/parity/transcripts/deterministic/ceo-review.json index dbb54530cc..d71bbbd4c6 100644 --- a/evals/parity/transcripts/deterministic/ceo-review.json +++ b/evals/parity/transcripts/deterministic/ceo-review.json @@ -95,6 +95,13 @@ "reproduced_defect": "Record only signal-bearing learnings", "regression_fixture": "evals/parity/regressions/pr-2030.json", "explanation": "### Signal-gated learning\n\nPersist a learning only when the interaction contains a useful, reusable signal such as an explicit preference, correction, accepted recommendation, or rejected direction. Track helpful and harmful outcomes separately. Do not manufacture a learning merely because a workflow completed." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/886", + "reproduced_defect": "Scale planning machinery to the printed build scale", + "regression_fixture": "evals/parity/regressions/pr-886.json", + "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." } ] } diff --git a/evals/parity/transcripts/deterministic/dx-review.json b/evals/parity/transcripts/deterministic/dx-review.json index 8b380468a0..59dd48ff0d 100644 --- a/evals/parity/transcripts/deterministic/dx-review.json +++ b/evals/parity/transcripts/deterministic/dx-review.json @@ -96,6 +96,13 @@ "reproduced_defect": "Record only signal-bearing learnings", "regression_fixture": "evals/parity/regressions/pr-2030.json", "explanation": "### Signal-gated learning\n\nPersist a learning only when the interaction contains a useful, reusable signal such as an explicit preference, correction, accepted recommendation, or rejected direction. Track helpful and harmful outcomes separately. Do not manufacture a learning merely because a workflow completed." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/886", + "reproduced_defect": "Scale planning machinery to the printed build scale", + "regression_fixture": "evals/parity/regressions/pr-886.json", + "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." } ] } diff --git a/evals/parity/transcripts/deterministic/engineering-review.json b/evals/parity/transcripts/deterministic/engineering-review.json index 9ff7131d33..0f19705161 100644 --- a/evals/parity/transcripts/deterministic/engineering-review.json +++ b/evals/parity/transcripts/deterministic/engineering-review.json @@ -109,6 +109,13 @@ "reproduced_defect": "Run a pre-mortem before challenging scope", "regression_fixture": "evals/parity/regressions/pr-592.json", "explanation": "### Pre-mortem before scope challenge\n\nBefore reviewing anything, run a pre-mortem: it is three months later and this plan failed, name the top three reasons why. Reason from production reality, not the plan's internal logic, and name concrete failure modes (data loss, performance cliff, security hole, team confusion), not abstract worries. Present those three failure modes to the user before the scope challenge, which follows the pre-mortem rather than opening the review." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/886", + "reproduced_defect": "Scale planning machinery to the printed build scale", + "regression_fixture": "evals/parity/regressions/pr-886.json", + "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." } ] } diff --git a/evals/parity/transcripts/deterministic/office-hours.json b/evals/parity/transcripts/deterministic/office-hours.json index 8fca45a7fd..0c1b8956c3 100644 --- a/evals/parity/transcripts/deterministic/office-hours.json +++ b/evals/parity/transcripts/deterministic/office-hours.json @@ -113,9 +113,9 @@ { "classification": "INTENTIONAL_IMPROVEMENT", "issue_or_pr": "https://github.com/garrytan/gstack/issues/886", - "reproduced_defect": "Right-size discovery for session-scale builds", + "reproduced_defect": "Scale planning machinery to the printed build scale", "regression_fixture": "evals/parity/regressions/pr-886.json", - "explanation": "### Proportional discovery for session-scale builds\n\nAfter Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2.\n\nFor a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment." + "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." } ] } diff --git a/evals/parity/transcripts/deterministic/specification.json b/evals/parity/transcripts/deterministic/specification.json index 9c47b2d089..ae195eade8 100644 --- a/evals/parity/transcripts/deterministic/specification.json +++ b/evals/parity/transcripts/deterministic/specification.json @@ -88,6 +88,13 @@ "reproduced_defect": "Match the user language", "regression_fixture": "evals/parity/regressions/pr-679.json", "explanation": "### User-language rule\n\nWrite questions, progress updates, reports, and artifacts in the language used by the user. Source material, code identifiers, commands, and quotations may remain in their original language when translating them would reduce accuracy." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/886", + "reproduced_defect": "Scale planning machinery to the printed build scale", + "regression_fixture": "evals/parity/regressions/pr-886.json", + "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." } ] } diff --git a/evals/parity/transcripts/policy-units.json b/evals/parity/transcripts/policy-units.json index 6afea0e7c2..b94d7a1daf 100644 --- a/evals/parity/transcripts/policy-units.json +++ b/evals/parity/transcripts/policy-units.json @@ -426,7 +426,7 @@ "prompt_sha256": "51b7d53bc342e8632e34ae31a167cbde568ab5ee2a6dd2ccc980583a30604164", "semantic_attempt_sha256": "06f77b27c9bd360562655b23ca00a0dd021bdb14ebaaf3d836845e4e0cb43d68" }, - "policy_sha256": "43d5cbbf88ed4f9afa3e7af214b4aa8c3a764a7006d76a864344df05d1f76392", + "policy_sha256": "7436f2bd70592738eda54ae9666d52ae909a4d44c06297e6486afda124cdbf41", "policy_present": true, "prompt_is_not_authority_input": true, "verdict": "PASS" diff --git a/skills/plan/SKILL.md b/skills/plan/SKILL.md index 8c06285b8c..36452e7f72 100644 --- a/skills/plan/SKILL.md +++ b/skills/plan/SKILL.md @@ -16,6 +16,7 @@ Before any substantive output, print these exact labels in this exact order. Res Target: Mode: Depth: +Scale: Mutation: Active modules: Skipped modules: @@ -33,6 +34,16 @@ Web context: 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 8. At exit, report completed artifacts, evidence, unresolved decisions, skipped modules with reasons, and any blocked gate. +9. Classify the Scale header line from the Build scale section before any questioning begins. Every planning specialist applies its proportional-planning judgment port to that scale. + +## Build scale + +Classify the request on fifteen scale vectors before any questioning begins, from the prompt and cheap repository evidence only. Never run a questioning round merely to classify scale. Default unknown vectors to the low end; the specialist's own workflow raises the scale naturally when answers reveal more (builder talk turning into startup talk upgrades mid-session). + +Vectors: audience (self → friends/team → public), expected users (none → handful → many), commercial intent (none → maybe → core), deployment target (none/local → hosted → production), time horizon (one sitting → days → weeks → months+), maintenance expectation (throwaway → kept → maintained), integration surface (standalone → consumes APIs → exposes APIs/multi-service), extensibility ask (fixed → configurable → customizable platform), data sensitivity (none → personal → regulated), failure stakes (lost fun → annoyance → money/trust/safety), team (solo → few → org), codebase (greenfield → existing repo → legacy production), reversibility (discardable → migrations/breaking changes), distribution (private → shared → published), compliance (none → some → audited). + +The highest tier any vector demands wins: `session` (all vectors low — one sitting, for fun, self only), `hobby` (kept personal tool, days), `project` (shared or in a real repo, weeks), `product` (external users, hosted, revenue intent), `venture` (startup ambition, platform/API surface, team, months+). "A cool space animation in my terminal" is session-scale. "A startup with customizable APIs" is venture-scale. Print the result on the header's Scale line with the two or three vectors that decided it. + ## Top-level modes diff --git a/skills/plan/references/legacy/autoplan.md b/skills/plan/references/legacy/autoplan.md index d99331bc21..64a12bd3a3 100644 --- a/skills/plan/references/legacy/autoplan.md +++ b/skills/plan/references/legacy/autoplan.md @@ -1088,3 +1088,20 @@ Before design and DX phases, print the detected scope signals and counts that dr When only one model produced a review row, label it **Claude-only** or **Codex-only** and print a visible single-voice banner. Never describe a one-model result as consensus, agreement, or cross-model validation. + + +## Upstream judgment port: issue #886 + +[Scale planning machinery to the printed build scale](https://github.com/garrytan/gstack/issues/886) + +### Proportional planning for the printed build scale + +The /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. + +- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. + +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + diff --git a/skills/plan/references/legacy/office-hours.md b/skills/plan/references/legacy/office-hours.md index 4e293fbf84..2ffe6aadaf 100644 --- a/skills/plan/references/legacy/office-hours.md +++ b/skills/plan/references/legacy/office-hours.md @@ -771,14 +771,19 @@ The design doc file is the artifact of this session. Before the telemetry block At the Phase 5 approval gate, print the full design-doc body as direct assistant text before the Approve/Revise/Start-over AskUserQuestion. Do not point the user at the file path and do not rely on a `Bash cat` or `Read` tool call to display it: tool outputs are frequently collapsed in the Claude Code UI, which leaves the user approving a document they cannot see. The assistant message is the one surface guaranteed to render, so emit a short preamble naming the saved path followed by the verbatim document body, then ask for approval. - + ## Upstream judgment port: issue #886 -[Right-size discovery for session-scale builds](https://github.com/garrytan/gstack/issues/886) +[Scale planning machinery to the printed build scale](https://github.com/garrytan/gstack/issues/886) -### Proportional discovery for session-scale builds +### Proportional planning for the printed build scale -After Phase 1 mode selection, classify the build scale from structured evidence: who it is for, whether external users or revenue exist, whether anything deploys, and the stated time horizon. A personal, for-fun, learning, or single-session build with no external users and nothing deployed is **session-scale**; everything else is **product-scale**. Print the classification and its evidence before Phase 2. +The /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. -For a session-scale builder session, proportionality is the default rather than an escape hatch the user must trigger; a polite user answering every question is not evidence the full machinery is wanted. Batch every Phase 2B question the initial prompt left unanswered into one AskUserQuestion call (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics). Skip the Phase 2.75 landscape search unless the user asks for it; the privacy gate is unchanged whenever it runs. Offer the visual sketch and outside design voices only when the user asks for visual or design help. Keep Phase 4 alternatives and both approval gates, each in a single round. Cap the adversarial spec review at one iteration. Keep the design doc near one page with Next Steps sized in hours or days, never a phased multi-week roadmap or a Distribution Plan the user did not ask for. The user can always ask for the complete treatment. +- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. + +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. diff --git a/skills/plan/references/legacy/plan-ceo-review.md b/skills/plan/references/legacy/plan-ceo-review.md index 6be0123797..78361745ab 100644 --- a/skills/plan/references/legacy/plan-ceo-review.md +++ b/skills/plan/references/legacy/plan-ceo-review.md @@ -647,3 +647,20 @@ Write questions, progress updates, reports, and artifacts in the language used b Persist a learning only when the interaction contains a useful, reusable signal such as an explicit preference, correction, accepted recommendation, or rejected direction. Track helpful and harmful outcomes separately. Do not manufacture a learning merely because a workflow completed. + + +## Upstream judgment port: issue #886 + +[Scale planning machinery to the printed build scale](https://github.com/garrytan/gstack/issues/886) + +### Proportional planning for the printed build scale + +The /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. + +- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. + +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + diff --git a/skills/plan/references/legacy/plan-devex-review.md b/skills/plan/references/legacy/plan-devex-review.md index 0ab57a6df3..bedf5b9a69 100644 --- a/skills/plan/references/legacy/plan-devex-review.md +++ b/skills/plan/references/legacy/plan-devex-review.md @@ -685,3 +685,20 @@ Write questions, progress updates, reports, and artifacts in the language used b Persist a learning only when the interaction contains a useful, reusable signal such as an explicit preference, correction, accepted recommendation, or rejected direction. Track helpful and harmful outcomes separately. Do not manufacture a learning merely because a workflow completed. + + +## Upstream judgment port: issue #886 + +[Scale planning machinery to the printed build scale](https://github.com/garrytan/gstack/issues/886) + +### Proportional planning for the printed build scale + +The /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. + +- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. + +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + diff --git a/skills/plan/references/legacy/plan-eng-review.md b/skills/plan/references/legacy/plan-eng-review.md index 7b1f7aac26..e4c9efef3e 100644 --- a/skills/plan/references/legacy/plan-eng-review.md +++ b/skills/plan/references/legacy/plan-eng-review.md @@ -295,3 +295,20 @@ Persist a learning only when the interaction contains a useful, reusable signal Before reviewing anything, run a pre-mortem: it is three months later and this plan failed, name the top three reasons why. Reason from production reality, not the plan's internal logic, and name concrete failure modes (data loss, performance cliff, security hole, team confusion), not abstract worries. Present those three failure modes to the user before the scope challenge, which follows the pre-mortem rather than opening the review. + + +## Upstream judgment port: issue #886 + +[Scale planning machinery to the printed build scale](https://github.com/garrytan/gstack/issues/886) + +### Proportional planning for the printed build scale + +The /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. + +- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. + +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + diff --git a/skills/plan/references/legacy/spec.md b/skills/plan/references/legacy/spec.md index 076210d947..eca3c694b9 100644 --- a/skills/plan/references/legacy/spec.md +++ b/skills/plan/references/legacy/spec.md @@ -805,3 +805,20 @@ Add to the standard template: Write questions, progress updates, reports, and artifacts in the language used by the user. Source material, code identifiers, commands, and quotations may remain in their original language when translating them would reduce accuracy. + + +## Upstream judgment port: issue #886 + +[Scale planning machinery to the printed build scale](https://github.com/garrytan/gstack/issues/886) + +### Proportional planning for the printed build scale + +The /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment. + +- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for. +- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks. +- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing. +- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point. + +For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + From 4829cadb2feac310fa4aabcd5ef7083601087a44 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 15:00:36 -0700 Subject: [PATCH 05/12] chore: collapse GStack 2 generator output in PR review via linguist-generated Co-Authored-By: Claude Fable 5 --- .gitattributes | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitattributes b/.gitattributes index 92e301fde7..6cab444175 100644 --- a/.gitattributes +++ b/.gitattributes @@ -51,3 +51,17 @@ bin/* text eol=lf # the content-addressed staged filename. lib/diagram-render/dist/*.html text eol=lf whitespace=-trailing-space lib/diagram-render/dist/*.json text eol=lf + +# GStack 2 generator output (scripts/gstack2/, `bun run gen:gstack2`). +# Marked linguist-generated so PR reviews collapse these by default and +# reviewers see only the hand-edited generator inputs. check:gstack2-generated +# enforces that these always match a clean regeneration, so their diffs are +# reproducible rather than reviewable. +skills/** linguist-generated=true +compat/** linguist-generated=true +evals/parity/** linguist-generated=true +docs/gstack-2/JUDGMENT-PARITY.md linguist-generated=true +docs/gstack-2/JUDGMENT-PROVENANCE.json linguist-generated=true +docs/gstack-2/SCENARIOS.md linguist-generated=true +docs/gstack-2/SKILL-MIGRATION.md linguist-generated=true +docs/gstack-2/BACKLOG-MAP.json linguist-generated=true From 17f1e3142fa049246a2dc2f6668368c75ddd7b33 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:00:24 -0700 Subject: [PATCH 06/12] =?UTF-8?q?release:=20v1.61.0.0=20=E2=80=94=20propor?= =?UTF-8?q?tional=20/plan=20via=20build-scale=20classification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++++++ VERSION | 2 +- package.json | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc149c519..c90d767176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,45 @@ > completion state and remaining P0 gates. No version bump or release claim is > made here while that status holds. +## [1.61.0.0] - 2026-07-22 + +## **/plan now sizes its machinery to your ask.** +## **A terminal toy gets one question round, not a startup diagnostic.** + +Ask /plan for something small and it plans something small. The dispatcher now classifies every request on fifteen build-scale vectors (audience, users, commercial intent, deployment, time horizon, integration surface, extensibility, stakes, and so on) and prints the verdict as a `Scale:` line in the execution header: session, hobby, project, product, or venture. Every planning specialist keys its effort to that line. "A cool space animation in my terminal" is session-scale and gets one batched question round, no web research, no outside design voices, and a one-page doc with next steps in hours. "A startup with customizable APIs" is venture-scale and gets the full question pressure, exactly as before. Classification comes from your prompt and cheap repository evidence only; /plan never asks questions just to decide how many questions to ask. + +### The numbers that matter + +Source: a real /plan Discovery session on 2026-07-22 for a zero-player terminal spaceship toy (transcript `~/.claude/projects/-Users-sinabina-spacegame/b01e246b-*.jsonl`). The After column is the enforced rule at session scale, pinned by the executable regression in `evals/parity/regressions/pr-886.json` (run: `bun run test:gstack2`). + +| Metric (session-scale ask) | Before | After | +|---|---|---| +| AskUserQuestion rounds | 10, one at a time | 1, batched | +| Adversarial review iterations on the doc | 3 | 1 max | +| Web searches by default | 2 | 0, on request | +| Wireframe + outside-voice offers | 2 | 0, on request | +| Next-steps horizon | phased roadmap + distribution plan | hours | +| Output tokens for the session | 115,395 measured | no measurement yet | + +Ten separate question rounds means ten full round-trips before a single line of design exists. For a toy built for fun, that was the whole session. One batched round answers the same questions in one pass. + +### What this means for you + +Small ideas stop costing big-idea tokens and big-idea patience. You can throw a one-liner at /plan and get a one-page plan the same sitting, and the moment your answers reveal real ambition (users, revenue, a platform) the scale upgrades mid-session and the full workflow comes back. Approval gates never shrink at any scale. Just describe what you want to build; the sizing is /plan's job now. + +### Itemized changes + +#### Added + +- **Build-scale classification in /plan.** The dispatcher's execution header gains a `Scale:` line (session, hobby, project, product, venture) classified from fifteen scale vectors before any questioning begins. Highest vector wins; unknown vectors default low; explicit statements dominate inference. +- **Proportional-planning judgment port (#886)** across all six planning specialists (office-hours, plan-ceo-review, plan-eng-review, plan-devex-review, spec, autoplan): question batching, research and outside-voice gating, review-iteration caps, artifact size, and step units keyed to the printed Scale. product and venture scale change nothing; STOP and approval gates are unchanged everywhere. + +#### For contributors + +- Overlay #886 anchors to the upstream issue "GENERAL: Reduce Token Overhead" and ships an executable vector-to-tier regression evaluated by `run-parity.ts` (check inventory 4,881 to 4,896). +- Generator output (`skills/**`, `compat/**`, `evals/parity/**`, generated `docs/gstack-2/` docs) is now marked `linguist-generated`, so PRs collapse it and reviewers see only hand-edited generator inputs. `check:gstack2-generated` keeps the collapsed files honest. +- Overlay headings now say "issue" instead of "PR" when the source URL is an issue. + ## [1.60.1.0] - 2026-07-09 ## **The /autoplan dual-voice eval is back on the board, catching real regressions.** diff --git a/VERSION b/VERSION index c4190e0048..82b3fa4c6d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.60.1.0 +1.61.0.0 diff --git a/package.json b/package.json index aa3f6e575a..75c289fd44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.60.1.0", + "version": "1.61.0.0", "description": "GStack 2 — six portable Agent Skills with an optional host-neutral runtime.", "license": "MIT", "type": "module", From 31ae801cc8df3a31d19ea36df19503df28bde5f9 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:06:41 -0700 Subject: [PATCH 07/12] ci(gstack2): fetch the pinned base commit in gate jobs so PR runs can read pinned blobs The generator reads pinned 1.x templates via git show at GSTACK2_BASE_SHA (bb57306d), which is only reachable from codex/* branches. PR checkouts never fetch it, so every gate job that runs gen:gstack2 failed on any pull request to this repo (this workflow had never passed on a PR; its only green run was a workflow_dispatch on a codex/gstack-2-ci-* branch). A depth-1 fetch of the pinned sha gives git show the commit, trees, and blobs it needs. Co-Authored-By: Claude Fable 5 --- .github/workflows/gstack2-gate.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/gstack2-gate.yml b/.github/workflows/gstack2-gate.yml index 6c0cbf9c6d..03ece139a1 100644 --- a/.github/workflows/gstack2-gate.yml +++ b/.github/workflows/gstack2-gate.yml @@ -25,6 +25,8 @@ jobs: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + - name: Fetch the pinned GStack 2 base commit (not reachable from PR refs) + run: git fetch --no-tags --depth=1 origin bb57306d98c97011b0919c6132705a15b1579781 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: 1.3.14 @@ -51,6 +53,8 @@ jobs: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + - name: Fetch the pinned GStack 2 base commit (not reachable from PR refs) + run: git fetch --no-tags --depth=1 origin bb57306d98c97011b0919c6132705a15b1579781 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: 1.3.14 @@ -66,6 +70,8 @@ jobs: timeout-minutes: 15 steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - name: Fetch the pinned GStack 2 base commit (not reachable from PR refs) + run: git fetch --no-tags --depth=1 origin bb57306d98c97011b0919c6132705a15b1579781 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: 1.3.14 @@ -84,6 +90,8 @@ jobs: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + - name: Fetch the pinned GStack 2 base commit (not reachable from PR refs) + run: git fetch --no-tags --depth=1 origin bb57306d98c97011b0919c6132705a15b1579781 - name: Build the declared development container run: docker build --file .devcontainer/Dockerfile --tag gstack2-devcontainer . - name: Run the GStack 2 gate inside the container From 77f3bca253eccd1ad1427a117550fd2453956110 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:18:54 -0700 Subject: [PATCH 08/12] =?UTF-8?q?feat(gstack2):=20repo-local=20design=20do?= =?UTF-8?q?cs=20=E2=80=94=20write=20to=20docs/designs/,=20review=20repo-fi?= =?UTF-8?q?rst=20(#703)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The office-hours design doc lands at ~/.gstack/projects//--design-.md and the approval question points the user at that path. Nobody finds their design doc in a hidden hashed directory. Upstream issue #703 asks plan reviews to prefer repo-local design docs. Overlay #703 (office-hours, plan-ceo-review, plan-eng-review, plan-devex-review, autoplan): inside a repository the canonical doc goes to docs/designs/.md and every presentation or approval names that path; the $GSTACK_HOME copy is still written for downstream skills, prior-design lookup, and cross-team discovery. Outside a repository the $GSTACK_HOME path is printed in full. Reviewers prefer repo-local docs over the store when both exist. Co-Authored-By: Claude Fable 5 --- scripts/gstack2/bug-fix-overlays.ts | 23 +++++++++++++++++++++++ scripts/gstack2/generate-skill-tree.ts | 6 +++--- scripts/gstack2/run-parity.ts | 10 ++++++---- test/gstack2-skills.test.ts | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/scripts/gstack2/bug-fix-overlays.ts b/scripts/gstack2/bug-fix-overlays.ts index 47c2dd41d7..d178738989 100644 --- a/scripts/gstack2/bug-fix-overlays.ts +++ b/scripts/gstack2/bug-fix-overlays.ts @@ -363,6 +363,20 @@ For office-hours specifically: at session or hobby scale, batch the Phase 2B que expected: { scale: 'session', questions_batched: true, question_rounds_max: 1, web_search: 'on-request', outside_voices: 'on-request', review_iterations_max: 1, step_unit: 'hours' }, }, }, + { + pr: 703, + url: 'https://github.com/garrytan/gstack/issues/703', + title: 'Write design docs repo-local and read them from the repo first', + targets: ['office-hours', 'plan-ceo-review', 'plan-eng-review', 'plan-devex-review', 'autoplan'], + anchor: 'GSTACK2_FIX_703_REPO_LOCAL_DESIGN_DOCS', + body: `### Repo-local design artifacts + +When the session produces a design or plan document and the working directory is inside a repository, write it to \`docs/designs/.md\` in that repository (create \`docs/designs/\` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under \`"\${GSTACK_HOME:-\$HOME/.gstack}"/projects//\` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the \`\$GSTACK_HOME\` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (\`docs/designs/\`, \`docs/plans/\`, or an explicitly provided path) over the \`\$GSTACK_HOME\` store whenever both exist.`, + regression: { + input: { in_repository: true, artifact: 'design-doc' }, + expected: { canonical_path: 'docs/designs/', gstack_home_copy: true, approval_names_visible_path: true, reviewer_prefers: 'repo-local' }, + }, + }, { pr: 452, url: 'https://github.com/garrytan/gstack/pull/452', @@ -552,6 +566,15 @@ export function evaluateBugFixRegression(pr: number, rawInput: unknown): Record< } case 452: return { apply_repo_rules: input.claude_md_has_review_section === true, silent_skip_if_absent: true }; + case 703: { + const inRepo = input.in_repository === true; + return { + canonical_path: inRepo ? 'docs/designs/' : 'gstack-home-projects-store', + gstack_home_copy: true, + approval_names_visible_path: true, + reviewer_prefers: 'repo-local', + }; + } case 886: { const ranks: Record> = { audience: { self: 0, friends: 1, team: 2, public: 3 }, diff --git a/scripts/gstack2/generate-skill-tree.ts b/scripts/gstack2/generate-skill-tree.ts index 857b39f8ef..ed942b4ada 100644 --- a/scripts/gstack2/generate-skill-tree.ts +++ b/scripts/gstack2/generate-skill-tree.ts @@ -82,7 +82,7 @@ function assertInventory(): void { } if (legacySections().length !== 16) throw new Error(`Expected 16 section templates, found ${legacySections().length}`); if (SCENARIOS.length !== 25) throw new Error(`Expected 25 parity scenarios, found ${SCENARIOS.length}`); - if (BUG_FIX_OVERLAYS.length !== 26) throw new Error(`Expected 26 upstream judgment overlays, found ${BUG_FIX_OVERLAYS.length}`); + if (BUG_FIX_OVERLAYS.length !== 27) throw new Error(`Expected 27 upstream judgment overlays, found ${BUG_FIX_OVERLAYS.length}`); } function toc(body: string): string { @@ -758,7 +758,7 @@ ${rows} ## Mechanical versus judgment changes - \`JUDGMENT_PRESERVING_CARVE\`: pinned specialist workflow with the retired shared onboarding wrapper excluded, retired invocations resolved to six public routes, host/runtime paths normalized, and large carved phases loaded lazily from package-local pinned references. -- \`BUG_FIX\`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 26 upstream PRs and issues and its regression fixture. +- \`BUG_FIX\`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 27 upstream PRs and issues and its regression fixture. - Asset relocation is byte-for-byte from the pinned Git blob and is indexed per tree. `; } @@ -779,7 +779,7 @@ function parityDoc(assetCount: number): string { Parity is executable, not a prose claim. Run \`bun run scripts/gstack2/run-parity.ts\` or the dedicated Bun tests. -The pinned release inventory passes **${EXPECTED_PARITY_CHECKS.toLocaleString('en-US')} checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 26 regression ports, and **${assetCount} assets**. +The pinned release inventory passes **${EXPECTED_PARITY_CHECKS.toLocaleString('en-US')} checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 27 regression ports, and **${assetCount} assets**. The suite verifies: diff --git a/scripts/gstack2/run-parity.ts b/scripts/gstack2/run-parity.ts index 8d74790a1e..e2eebba959 100644 --- a/scripts/gstack2/run-parity.ts +++ b/scripts/gstack2/run-parity.ts @@ -19,8 +19,10 @@ const ALLOWED_DISPOSITIONS = new Set(['VERBATIM_PORT', 'MECHANICAL_PORT', 'JUDGM // six more upstream judgment overlays (16 -> 22) added 30 checks. Three more // Tier-2 overlays (22 -> 25) added 15 checks (5 per overlay). The // proportional-planning overlay for issue #886 (25 -> 26, six plan-tree -// targets) added 15 more (2 per targeted module + 3 regression checks). -export const EXPECTED_PARITY_CHECKS = 4896; +// targets) added 15 more (2 per targeted module + 3 regression checks). The +// repo-local design-doc overlay for issue #703 (26 -> 27, five plan-tree +// targets) added 13 more. +export const EXPECTED_PARITY_CHECKS = 4909; function sha256(value: string | Uint8Array): string { return createHash('sha256').update(value).digest('hex'); @@ -255,8 +257,8 @@ export function runParity(): ParityResult { check(JSON.stringify(json(path.join(ROOT, 'evals', 'parity', 'scenarios', `${scenario.id}.json`))) === JSON.stringify(scenario), `${scenario.id} generated fixture drift`); } - check(BUG_FIX_OVERLAYS.length === 26, `Expected 26 regression definitions; got ${BUG_FIX_OVERLAYS.length}`); - check(files(path.join(ROOT, 'evals', 'parity', 'regressions'), '.json').length === 26, 'Generated regression fixture count is not 26'); + check(BUG_FIX_OVERLAYS.length === 27, `Expected 27 regression definitions; got ${BUG_FIX_OVERLAYS.length}`); + check(files(path.join(ROOT, 'evals', 'parity', 'regressions'), '.json').length === 27, 'Generated regression fixture count is not 27'); for (const overlay of BUG_FIX_OVERLAYS) { const fixture = json(path.join(ROOT, 'evals', 'parity', 'regressions', `pr-${overlay.pr}.json`)); check(JSON.stringify(fixture) === JSON.stringify(overlay), `PR #${overlay.pr} regression fixture drift`); diff --git a/test/gstack2-skills.test.ts b/test/gstack2-skills.test.ts index 798a5d01a0..f9d3610e90 100644 --- a/test/gstack2-skills.test.ts +++ b/test/gstack2-skills.test.ts @@ -27,7 +27,7 @@ describe('GStack 2 skill parity', () => { const result = runParity(); expect(result.sources).toBe(55); expect(result.sections).toBe(16); - expect(result.regressions).toBe(26); + expect(result.regressions).toBe(27); }, 30_000); test('keeps image generation host-native, optional, and provider-free', () => { From 15873047c450d463954a07e572764c9479cb214f Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:18:54 -0700 Subject: [PATCH 09/12] chore(gstack2): regenerate skill tree for the #703 repo-local design-doc overlay Co-Authored-By: Claude Fable 5 --- docs/gstack-2/JUDGMENT-PARITY.md | 2 +- docs/gstack-2/JUDGMENT-PROVENANCE.json | 28 +++++++++++++++---- docs/gstack-2/SKILL-MIGRATION.md | 12 ++++---- evals/parity/contracts/autoplan.json | 3 +- evals/parity/contracts/office-hours.json | 3 +- evals/parity/contracts/plan-ceo-review.json | 3 +- evals/parity/contracts/plan-devex-review.json | 3 +- evals/parity/contracts/plan-eng-review.json | 3 +- evals/parity/manifest.json | 28 +++++++++++++++---- evals/parity/regressions/pr-703.json | 26 +++++++++++++++++ .../transcripts/deterministic/ceo-review.json | 7 +++++ .../transcripts/deterministic/dx-review.json | 7 +++++ .../deterministic/engineering-review.json | 7 +++++ .../deterministic/office-hours.json | 7 +++++ skills/plan/references/legacy/autoplan.md | 10 +++++++ skills/plan/references/legacy/office-hours.md | 10 +++++++ .../plan/references/legacy/plan-ceo-review.md | 10 +++++++ .../references/legacy/plan-devex-review.md | 10 +++++++ .../plan/references/legacy/plan-eng-review.md | 10 +++++++ 19 files changed, 167 insertions(+), 22 deletions(-) create mode 100644 evals/parity/regressions/pr-703.json diff --git a/docs/gstack-2/JUDGMENT-PARITY.md b/docs/gstack-2/JUDGMENT-PARITY.md index e7e5c62034..20e06d0997 100644 --- a/docs/gstack-2/JUDGMENT-PARITY.md +++ b/docs/gstack-2/JUDGMENT-PARITY.md @@ -2,7 +2,7 @@ Parity is executable, not a prose claim. Run `bun run scripts/gstack2/run-parity.ts` or the dedicated Bun tests. -The pinned release inventory passes **4,896 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 26 regression ports, and **78 assets**. +The pinned release inventory passes **4,909 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 27 regression ports, and **78 assets**. The suite verifies: diff --git a/docs/gstack-2/JUDGMENT-PROVENANCE.json b/docs/gstack-2/JUDGMENT-PROVENANCE.json index 156ac168bd..78349a8d18 100644 --- a/docs/gstack-2/JUDGMENT-PROVENANCE.json +++ b/docs/gstack-2/JUDGMENT-PROVENANCE.json @@ -91,7 +91,8 @@ 2030, 1049, 1116, - 886 + 886, + 703 ], "original_source_file": "office-hours/SKILL.md.tmpl", "original_line_range": "1-526", @@ -206,7 +207,8 @@ "overlays": [ 679, 2030, - 886 + 886, + 703 ], "original_source_file": "plan-ceo-review/SKILL.md.tmpl", "original_line_range": "1-427", @@ -349,7 +351,8 @@ 1071, 2030, 592, - 886 + 886, + 703 ], "original_source_file": "plan-eng-review/SKILL.md.tmpl", "original_line_range": "1-158", @@ -469,7 +472,8 @@ "overlays": [ 679, 2030, - 886 + 886, + 703 ], "original_source_file": "plan-devex-review/SKILL.md.tmpl", "original_line_range": "1-462", @@ -604,7 +608,8 @@ 679, 2014, 2023, - 886 + 886, + 703 ], "original_source_file": "autoplan/SKILL.md.tmpl", "original_line_range": "1-916", @@ -7433,6 +7438,19 @@ ], "anchor": "GSTACK2_FIX_886_PROPORTIONAL_PLANNING" }, + { + "pr": 703, + "url": "https://github.com/garrytan/gstack/issues/703", + "title": "Write design docs repo-local and read them from the repo first", + "targets": [ + "office-hours", + "plan-ceo-review", + "plan-eng-review", + "plan-devex-review", + "autoplan" + ], + "anchor": "GSTACK2_FIX_703_REPO_LOCAL_DESIGN_DOCS" + }, { "pr": 452, "url": "https://github.com/garrytan/gstack/pull/452", diff --git a/docs/gstack-2/SKILL-MIGRATION.md b/docs/gstack-2/SKILL-MIGRATION.md index d514823369..70b470412c 100644 --- a/docs/gstack-2/SKILL-MIGRATION.md +++ b/docs/gstack-2/SKILL-MIGRATION.md @@ -11,11 +11,11 @@ The fixed public modes are: Design = `Explore | Generate | Critique | Implement` | Legacy invocation | Replacement | Visibility | Mandatory | Judgment overlays | |---|---|---|---|---| | `/gstack` | `$plan --mode Discovery --module gstack` | internal (internal) | no | #679 | -| `/office-hours` | `$plan --mode Discovery --module office-hours` | internal (primary) | yes | #679, #2030, #1049, #1116, #886 | -| `/plan-ceo-review` | `$plan --mode Product --module plan-ceo-review` | internal (primary) | yes | #679, #2030, #886 | -| `/plan-eng-review` | `$plan --mode Engineering --module plan-eng-review` | internal (primary) | yes | #679, #1071, #2030, #592, #886 | -| `/plan-devex-review` | `$plan --mode DX --module plan-devex-review` | internal (primary) | yes | #679, #2030, #886 | -| `/autoplan` | `$plan --mode Full chain --module autoplan` | internal (primary) | yes | #679, #2014, #2023, #886 | +| `/office-hours` | `$plan --mode Discovery --module office-hours` | internal (primary) | yes | #679, #2030, #1049, #1116, #886, #703 | +| `/plan-ceo-review` | `$plan --mode Product --module plan-ceo-review` | internal (primary) | yes | #679, #2030, #886, #703 | +| `/plan-eng-review` | `$plan --mode Engineering --module plan-eng-review` | internal (primary) | yes | #679, #1071, #2030, #592, #886, #703 | +| `/plan-devex-review` | `$plan --mode DX --module plan-devex-review` | internal (primary) | yes | #679, #2030, #886, #703 | +| `/autoplan` | `$plan --mode Full chain --module autoplan` | internal (primary) | yes | #679, #2014, #2023, #886, #703 | | `/spec` | `$plan --mode Specification --module spec` | internal (primary) | yes | #679, #886 | | `/plan-tune` | `$plan --mode Discovery --module plan-tune` | internal (primary) | yes | #679 | | `/context-save` | `$plan --mode Discovery --module context-save` | internal (internal) | no | #679 | @@ -75,5 +75,5 @@ The fixed public modes are: Design = `Explore | Generate | Critique | Implement` ## Mechanical versus judgment changes - `JUDGMENT_PRESERVING_CARVE`: pinned specialist workflow with the retired shared onboarding wrapper excluded, retired invocations resolved to six public routes, host/runtime paths normalized, and large carved phases loaded lazily from package-local pinned references. -- `BUG_FIX`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 26 upstream PRs and issues and its regression fixture. +- `BUG_FIX`: the canonical carved body plus a clearly delimited judgment overlay sourced from one of the 27 upstream PRs and issues and its regression fixture. - Asset relocation is byte-for-byte from the pinned Git blob and is indexed per tree. diff --git a/evals/parity/contracts/autoplan.json b/evals/parity/contracts/autoplan.json index e7cf23397d..6ef08ed433 100644 --- a/evals/parity/contracts/autoplan.json +++ b/evals/parity/contracts/autoplan.json @@ -15,7 +15,8 @@ 679, 2014, 2023, - 886 + 886, + 703 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/office-hours.json b/evals/parity/contracts/office-hours.json index a1eebb8d6f..89e2f0e132 100644 --- a/evals/parity/contracts/office-hours.json +++ b/evals/parity/contracts/office-hours.json @@ -16,7 +16,8 @@ 2030, 1049, 1116, - 886 + 886, + 703 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/plan-ceo-review.json b/evals/parity/contracts/plan-ceo-review.json index 375a2988b1..8f69e12b4e 100644 --- a/evals/parity/contracts/plan-ceo-review.json +++ b/evals/parity/contracts/plan-ceo-review.json @@ -14,7 +14,8 @@ "overlays": [ 679, 2030, - 886 + 886, + 703 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/plan-devex-review.json b/evals/parity/contracts/plan-devex-review.json index d9507fc907..67f7df867f 100644 --- a/evals/parity/contracts/plan-devex-review.json +++ b/evals/parity/contracts/plan-devex-review.json @@ -14,7 +14,8 @@ "overlays": [ 679, 2030, - 886 + 886, + 703 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/contracts/plan-eng-review.json b/evals/parity/contracts/plan-eng-review.json index 287fde4d76..182e08596a 100644 --- a/evals/parity/contracts/plan-eng-review.json +++ b/evals/parity/contracts/plan-eng-review.json @@ -16,7 +16,8 @@ 1071, 2030, 592, - 886 + 886, + 703 ], "contract": { "question_order": "Preserve the source workflow order; gather prerequisites before consequential questions.", diff --git a/evals/parity/manifest.json b/evals/parity/manifest.json index 156ac168bd..78349a8d18 100644 --- a/evals/parity/manifest.json +++ b/evals/parity/manifest.json @@ -91,7 +91,8 @@ 2030, 1049, 1116, - 886 + 886, + 703 ], "original_source_file": "office-hours/SKILL.md.tmpl", "original_line_range": "1-526", @@ -206,7 +207,8 @@ "overlays": [ 679, 2030, - 886 + 886, + 703 ], "original_source_file": "plan-ceo-review/SKILL.md.tmpl", "original_line_range": "1-427", @@ -349,7 +351,8 @@ 1071, 2030, 592, - 886 + 886, + 703 ], "original_source_file": "plan-eng-review/SKILL.md.tmpl", "original_line_range": "1-158", @@ -469,7 +472,8 @@ "overlays": [ 679, 2030, - 886 + 886, + 703 ], "original_source_file": "plan-devex-review/SKILL.md.tmpl", "original_line_range": "1-462", @@ -604,7 +608,8 @@ 679, 2014, 2023, - 886 + 886, + 703 ], "original_source_file": "autoplan/SKILL.md.tmpl", "original_line_range": "1-916", @@ -7433,6 +7438,19 @@ ], "anchor": "GSTACK2_FIX_886_PROPORTIONAL_PLANNING" }, + { + "pr": 703, + "url": "https://github.com/garrytan/gstack/issues/703", + "title": "Write design docs repo-local and read them from the repo first", + "targets": [ + "office-hours", + "plan-ceo-review", + "plan-eng-review", + "plan-devex-review", + "autoplan" + ], + "anchor": "GSTACK2_FIX_703_REPO_LOCAL_DESIGN_DOCS" + }, { "pr": 452, "url": "https://github.com/garrytan/gstack/pull/452", diff --git a/evals/parity/regressions/pr-703.json b/evals/parity/regressions/pr-703.json new file mode 100644 index 0000000000..a88ea581b6 --- /dev/null +++ b/evals/parity/regressions/pr-703.json @@ -0,0 +1,26 @@ +{ + "pr": 703, + "url": "https://github.com/garrytan/gstack/issues/703", + "title": "Write design docs repo-local and read them from the repo first", + "targets": [ + "office-hours", + "plan-ceo-review", + "plan-eng-review", + "plan-devex-review", + "autoplan" + ], + "anchor": "GSTACK2_FIX_703_REPO_LOCAL_DESIGN_DOCS", + "body": "### Repo-local design artifacts\n\nWhen the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `\"${GSTACK_HOME:-$HOME/.gstack}\"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist.", + "regression": { + "input": { + "in_repository": true, + "artifact": "design-doc" + }, + "expected": { + "canonical_path": "docs/designs/", + "gstack_home_copy": true, + "approval_names_visible_path": true, + "reviewer_prefers": "repo-local" + } + } +} diff --git a/evals/parity/transcripts/deterministic/ceo-review.json b/evals/parity/transcripts/deterministic/ceo-review.json index d71bbbd4c6..a80d8eb058 100644 --- a/evals/parity/transcripts/deterministic/ceo-review.json +++ b/evals/parity/transcripts/deterministic/ceo-review.json @@ -102,6 +102,13 @@ "reproduced_defect": "Scale planning machinery to the printed build scale", "regression_fixture": "evals/parity/regressions/pr-886.json", "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/703", + "reproduced_defect": "Write design docs repo-local and read them from the repo first", + "regression_fixture": "evals/parity/regressions/pr-703.json", + "explanation": "### Repo-local design artifacts\n\nWhen the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `\"${GSTACK_HOME:-$HOME/.gstack}\"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist." } ] } diff --git a/evals/parity/transcripts/deterministic/dx-review.json b/evals/parity/transcripts/deterministic/dx-review.json index 59dd48ff0d..90fc8ac7e6 100644 --- a/evals/parity/transcripts/deterministic/dx-review.json +++ b/evals/parity/transcripts/deterministic/dx-review.json @@ -103,6 +103,13 @@ "reproduced_defect": "Scale planning machinery to the printed build scale", "regression_fixture": "evals/parity/regressions/pr-886.json", "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/703", + "reproduced_defect": "Write design docs repo-local and read them from the repo first", + "regression_fixture": "evals/parity/regressions/pr-703.json", + "explanation": "### Repo-local design artifacts\n\nWhen the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `\"${GSTACK_HOME:-$HOME/.gstack}\"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist." } ] } diff --git a/evals/parity/transcripts/deterministic/engineering-review.json b/evals/parity/transcripts/deterministic/engineering-review.json index 0f19705161..181da792e4 100644 --- a/evals/parity/transcripts/deterministic/engineering-review.json +++ b/evals/parity/transcripts/deterministic/engineering-review.json @@ -116,6 +116,13 @@ "reproduced_defect": "Scale planning machinery to the printed build scale", "regression_fixture": "evals/parity/regressions/pr-886.json", "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/703", + "reproduced_defect": "Write design docs repo-local and read them from the repo first", + "regression_fixture": "evals/parity/regressions/pr-703.json", + "explanation": "### Repo-local design artifacts\n\nWhen the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `\"${GSTACK_HOME:-$HOME/.gstack}\"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist." } ] } diff --git a/evals/parity/transcripts/deterministic/office-hours.json b/evals/parity/transcripts/deterministic/office-hours.json index 0c1b8956c3..54fa1e7516 100644 --- a/evals/parity/transcripts/deterministic/office-hours.json +++ b/evals/parity/transcripts/deterministic/office-hours.json @@ -116,6 +116,13 @@ "reproduced_defect": "Scale planning machinery to the printed build scale", "regression_fixture": "evals/parity/regressions/pr-886.json", "explanation": "### Proportional planning for the printed build scale\n\nThe /plan dispatcher prints a `Scale:` header line classified from fifteen build-scale vectors (its Build scale section). This rule authorizes every planning specialist to size its machinery to that scale while keeping every STOP gate and approval boundary; a polite user answering every question is not evidence the full machinery is wanted, and the user can always ask for the complete treatment.\n\n- `session` and `hobby`: batch every question the initial prompt left unanswered into one AskUserQuestion round (two rounds for hobby); skip web or landscape research, outside voices, second opinions, and visual sketches unless the user asks (privacy gates are unchanged whenever they run); cap any adversarial or spec review loop at one iteration; keep the decision artifact near one page with next steps sized in hours (session) or days (hobby), never a phased multi-week roadmap or a distribution plan the user did not ask for.\n- `project`: run the specialist's default workflow, batching question rounds where its source authorizes smart skips; size the roadmap in weeks.\n- `product` and `venture`: the full specialist workflow and its complete question pressure apply; this rule removes nothing.\n- Never run a questioning round merely to classify scale. Classify from the prompt and cheap repository evidence, defaulting unknown vectors low; a specialist's own later questions may raise the scale mid-session, and an upgrade restores the full workflow from that point.\n\nFor office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration." + }, + { + "classification": "INTENTIONAL_IMPROVEMENT", + "issue_or_pr": "https://github.com/garrytan/gstack/issues/703", + "reproduced_defect": "Write design docs repo-local and read them from the repo first", + "regression_fixture": "evals/parity/regressions/pr-703.json", + "explanation": "### Repo-local design artifacts\n\nWhen the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `\"${GSTACK_HOME:-$HOME/.gstack}\"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist." } ] } diff --git a/skills/plan/references/legacy/autoplan.md b/skills/plan/references/legacy/autoplan.md index 64a12bd3a3..053c81f175 100644 --- a/skills/plan/references/legacy/autoplan.md +++ b/skills/plan/references/legacy/autoplan.md @@ -1105,3 +1105,13 @@ The /plan dispatcher prints a `Scale:` header line classified from fifteen build For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + + +## Upstream judgment port: issue #703 + +[Write design docs repo-local and read them from the repo first](https://github.com/garrytan/gstack/issues/703) + +### Repo-local design artifacts + +When the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `"${GSTACK_HOME:-$HOME/.gstack}"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist. + diff --git a/skills/plan/references/legacy/office-hours.md b/skills/plan/references/legacy/office-hours.md index 2ffe6aadaf..1ce41a132e 100644 --- a/skills/plan/references/legacy/office-hours.md +++ b/skills/plan/references/legacy/office-hours.md @@ -787,3 +787,13 @@ The /plan dispatcher prints a `Scale:` header line classified from fifteen build For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + + +## Upstream judgment port: issue #703 + +[Write design docs repo-local and read them from the repo first](https://github.com/garrytan/gstack/issues/703) + +### Repo-local design artifacts + +When the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `"${GSTACK_HOME:-$HOME/.gstack}"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist. + diff --git a/skills/plan/references/legacy/plan-ceo-review.md b/skills/plan/references/legacy/plan-ceo-review.md index 78361745ab..9c63956c28 100644 --- a/skills/plan/references/legacy/plan-ceo-review.md +++ b/skills/plan/references/legacy/plan-ceo-review.md @@ -664,3 +664,13 @@ The /plan dispatcher prints a `Scale:` header line classified from fifteen build For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + + +## Upstream judgment port: issue #703 + +[Write design docs repo-local and read them from the repo first](https://github.com/garrytan/gstack/issues/703) + +### Repo-local design artifacts + +When the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `"${GSTACK_HOME:-$HOME/.gstack}"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist. + diff --git a/skills/plan/references/legacy/plan-devex-review.md b/skills/plan/references/legacy/plan-devex-review.md index bedf5b9a69..9d5e3adc9e 100644 --- a/skills/plan/references/legacy/plan-devex-review.md +++ b/skills/plan/references/legacy/plan-devex-review.md @@ -702,3 +702,13 @@ The /plan dispatcher prints a `Scale:` header line classified from fifteen build For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + + +## Upstream judgment port: issue #703 + +[Write design docs repo-local and read them from the repo first](https://github.com/garrytan/gstack/issues/703) + +### Repo-local design artifacts + +When the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `"${GSTACK_HOME:-$HOME/.gstack}"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist. + diff --git a/skills/plan/references/legacy/plan-eng-review.md b/skills/plan/references/legacy/plan-eng-review.md index e4c9efef3e..3b23256771 100644 --- a/skills/plan/references/legacy/plan-eng-review.md +++ b/skills/plan/references/legacy/plan-eng-review.md @@ -312,3 +312,13 @@ The /plan dispatcher prints a `Scale:` header line classified from fifteen build For office-hours specifically: at session or hobby scale, batch the Phase 2B questions (this refines the one-at-a-time rule, whose pressure exists for startup diagnostics), default-skip the Phase 2.75 landscape search, gate the visual sketch and outside design voices on an explicit ask, and cap the Spec Review Loop at one iteration. + + +## Upstream judgment port: issue #703 + +[Write design docs repo-local and read them from the repo first](https://github.com/garrytan/gstack/issues/703) + +### Repo-local design artifacts + +When the session produces a design or plan document and the working directory is inside a repository, write it to `docs/designs/.md` in that repository (create `docs/designs/` if needed) and name that path every time the document is presented or approval is requested. A hashed home-directory path is never the thing the user is asked to open. Keep writing the cross-session copy under `"${GSTACK_HOME:-$HOME/.gstack}"/projects//` with the existing filename convention — downstream skills, prior-design lookup, and cross-team discovery depend on that store — but the repo-local file is the canonical one the user owns and edits. Outside a repository, the `$GSTACK_HOME` path remains the only copy; print it in full when asking for approval. When reviewing, prefer a repo-local design doc (`docs/designs/`, `docs/plans/`, or an explicitly provided path) over the `$GSTACK_HOME` store whenever both exist. + From 183990beab5f0ff472a62b4ccfaba0b61c960386 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:20:46 -0700 Subject: [PATCH 10/12] release: note repo-local design docs in v1.61.0.0 Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c90d767176..dbce423c46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ Small ideas stop costing big-idea tokens and big-idea patience. You can throw a - **Build-scale classification in /plan.** The dispatcher's execution header gains a `Scale:` line (session, hobby, project, product, venture) classified from fifteen scale vectors before any questioning begins. Highest vector wins; unknown vectors default low; explicit statements dominate inference. - **Proportional-planning judgment port (#886)** across all six planning specialists (office-hours, plan-ceo-review, plan-eng-review, plan-devex-review, spec, autoplan): question batching, research and outside-voice gating, review-iteration caps, artifact size, and step units keyed to the printed Scale. product and venture scale change nothing; STOP and approval gates are unchanged everywhere. +- **Design docs land in your repo (#703).** When you plan inside a repository, the design doc is written to `docs/designs/.md` and approval questions name that path, not a hashed directory under `~/.gstack`. The cross-session copy in `~/.gstack/projects/` is still written so downstream skills and prior-design discovery keep working, and plan reviews now prefer the repo-local doc when both exist. #### For contributors From 069af0a7332817ede65152d70f4d1cfee678c131 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:36:07 -0700 Subject: [PATCH 11/12] fix(gstack2): self-heal missing pinned-base objects with a depth-1 sha fetch GSTACK2_BASE_SHA is only reachable from codex/* branches, so any workflow or checkout that didn't fetch those refs fails every git show against the pinned tree. pinnedText now retries once after fetching the pinned sha directly, which fixes the class for all workflows instead of patching fetch steps into each one. The explicit step stays in gstack2-gate.yml for the read-only devcontainer mount, which cannot fetch at generation time. Co-Authored-By: Claude Fable 5 --- scripts/gstack2/render-legacy.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/gstack2/render-legacy.ts b/scripts/gstack2/render-legacy.ts index fb4cfc6033..f5e08d3945 100644 --- a/scripts/gstack2/render-legacy.ts +++ b/scripts/gstack2/render-legacy.ts @@ -32,13 +32,29 @@ export function legacyRelativePath(source: string): string { return repositoryRelativePath(legacyTemplatePath(source)); } +let pinnedBaseFetchAttempted = false; + function pinnedText(relativePath: string): string { - const result = Bun.spawnSync({ + const show = () => Bun.spawnSync({ cmd: ['git', 'show', pinnedRevisionPath(relativePath)], cwd: ROOT, stdout: 'pipe', stderr: 'pipe', }); + let result = show(); + if (result.exitCode !== 0 && !pinnedBaseFetchAttempted) { + // CI and shallow checkouts only fetch the PR refs; GSTACK2_BASE_SHA is + // reachable from codex/* branches only, so its objects may be absent. + // A depth-1 fetch of the pinned sha restores git show for every caller. + pinnedBaseFetchAttempted = true; + Bun.spawnSync({ + cmd: ['git', 'fetch', '--no-tags', '--depth=1', 'origin', GSTACK2_BASE_SHA], + cwd: ROOT, + stdout: 'pipe', + stderr: 'pipe', + }); + result = show(); + } if (result.exitCode !== 0) throw new Error(`Unable to read ${relativePath} at ${GSTACK2_BASE_SHA}: ${result.stderr.toString()}`); return result.stdout.toString(); } From c47d3fbb9034b7b5f7300e5b3c5687e4dbae079e Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:36:07 -0700 Subject: [PATCH 12/12] fix(gstack2): report drift paths posix-normalized so Windows output matches assertions Co-Authored-By: Claude Fable 5 --- scripts/gstack2/generate-skill-tree.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/gstack2/generate-skill-tree.ts b/scripts/gstack2/generate-skill-tree.ts index ed942b4ada..760c55283e 100644 --- a/scripts/gstack2/generate-skill-tree.ts +++ b/scripts/gstack2/generate-skill-tree.ts @@ -1013,12 +1013,12 @@ function runCheck(): void { } catch { disk = null; } - if (!disk) drift.push(`missing ${path.relative(ROOT, abs)}`); - else if (!disk.equals(bytes)) drift.push(`stale ${path.relative(ROOT, abs)}`); + if (!disk) drift.push(`missing ${normalizeRepositoryPath(path.relative(ROOT, abs))}`); + else if (!disk.equals(bytes)) drift.push(`stale ${normalizeRepositoryPath(path.relative(ROOT, abs))}`); } for (const root of cleaned) { for (const abs of diskFiles(root)) { - if (!files.has(abs)) drift.push(`orphaned ${path.relative(ROOT, abs)}`); + if (!files.has(abs)) drift.push(`orphaned ${normalizeRepositoryPath(path.relative(ROOT, abs))}`); } } drift.sort();