From 25098d0a26e28953da451a86b86e7b27c27022a5 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:25:30 -0700 Subject: [PATCH 1/3] =?UTF-8?q?feat(gstack2):=20overlay=20#2000=20?= =?UTF-8?q?=E2=80=94=20design=20docs=20in-repo,=20one=20page,=20decisions?= =?UTF-8?q?=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Office-hours design docs were written to ~/.gstack/projects// and followed a 15-section template that re-argued approaches the user had already ruled out in conversation (upstream #2000, #1422; observed on the Examripper fixmatch doc). The overlay makes the repo docs/designs/ copy canonical, keeps the state-dir copy for downstream discovery, requires the absolute path whenever the doc is mentioned, and caps the doc at one page with ruled-out approaches collapsed to a single line each. Co-Authored-By: Claude Fable 5 --- scripts/gstack2/bug-fix-overlays.ts | 30 ++++++++++++++++++++++++++ scripts/gstack2/generate-skill-tree.ts | 10 ++++----- scripts/gstack2/run-parity.ts | 9 ++++---- test/gstack2-skills.test.ts | 2 +- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/scripts/gstack2/bug-fix-overlays.ts b/scripts/gstack2/bug-fix-overlays.ts index 031bb4893a..802e6075c2 100644 --- a/scripts/gstack2/bug-fix-overlays.ts +++ b/scripts/gstack2/bug-fix-overlays.ts @@ -356,6 +356,28 @@ Before scope-drift detection, read a \`## Review\` section from the project CLAU expected: { apply_repo_rules: true, silent_skip_if_absent: true }, }, }, + { + pr: 2000, + url: 'https://github.com/garrytan/gstack/issues/2000', + title: 'Design docs live in the repo, fit one page, and record decisions only', + targets: ['office-hours'], + anchor: 'GSTACK2_FIX_2000_DESIGN_DOC_PLACEMENT_AND_LENGTH', + body: `### Design-doc placement and length + +The design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at \`docs/designs/\` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the \`{user}-{branch}-design-{datetime}\` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to "the design doc" without saying where it is. + +Default to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness.`, + regression: { + input: { in_git_repo: true, ruled_out_approaches: 3 }, + expected: { + canonical_location: 'repo-docs-designs', + state_dir_copy_for_discovery: true, + absolute_path_announced: true, + ruled_out_max_lines_each: 1, + one_page_default: true, + }, + }, + }, ]; export function overlaysForSource(source: string): BugFixOverlay[] { @@ -531,6 +553,14 @@ 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 2000: + return { + canonical_location: input.in_git_repo === true ? 'repo-docs-designs' : 'state-dir', + state_dir_copy_for_discovery: true, + absolute_path_announced: true, + ruled_out_max_lines_each: 1, + one_page_default: true, + }; 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 f80fbb7a45..0713282ff4 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 { @@ -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 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: @@ -772,7 +772,7 @@ The suite verifies: - immutable full 1.x render hashes plus canonical specialist-render equality, with the excluded onboarding wrapper and lazy section references asserted explicitly; - preservation of nine behavioral contract dimensions per module; - 25 structured non-keyword routing fixtures with active/skipped modules, depth, mutation, and web context; -- 25 upstream judgment-port regression fixtures and anchors; +- 26 upstream judgment-port regression fixtures and anchors; - all linked asset copies against their pinned Git blobs; - frontmatter and \`agents/openai.yaml\` schema for each public skill. @@ -922,7 +922,7 @@ function main(): void { schema_version: 1, base_sha: GSTACK2_BASE_SHA, public_skills: [...TREE_NAMES], - counts: { public_skills: 6, mandatory_inputs: 31, templates: 55, section_templates: 16, packaged_section_copies: sectionCopies.length, internal_execution_adapters: 1, scenarios: 25, bug_fix_ports: 25, assets: assets.length, dependency_copies: dependencyCopies.length, runtime_helpers: runtimeHelpers.length }, + counts: { public_skills: 6, mandatory_inputs: 31, templates: 55, section_templates: 16, packaged_section_copies: sectionCopies.length, internal_execution_adapters: 1, scenarios: 25, bug_fix_ports: 26, assets: assets.length, dependency_copies: dependencyCopies.length, runtime_helpers: runtimeHelpers.length }, sources: sourceRecords, sections: sectionRecords, section_copies: sectionCopies, diff --git a/scripts/gstack2/run-parity.ts b/scripts/gstack2/run-parity.ts index 252ce95197..1ccfa3c19a 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 #2000 +// design-doc placement/length overlay (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 e8510eafb8bf17fb9e309cab8739525cbbe35fd3 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:25:30 -0700 Subject: [PATCH 2/3] chore(gstack2): regenerate for overlay #2000 Co-Authored-By: Claude Fable 5 --- docs/gstack-2/JUDGMENT-PARITY.md | 4 ++-- docs/gstack-2/JUDGMENT-PROVENANCE.json | 14 +++++++++-- docs/gstack-2/SKILL-MIGRATION.md | 4 ++-- evals/parity/contracts/office-hours.json | 3 ++- evals/parity/manifest.json | 14 +++++++++-- evals/parity/regressions/pr-2000.json | 23 +++++++++++++++++++ .../deterministic/office-hours.json | 7 ++++++ skills/plan/references/legacy/office-hours.md | 12 ++++++++++ 8 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 evals/parity/regressions/pr-2000.json diff --git a/docs/gstack-2/JUDGMENT-PARITY.md b/docs/gstack-2/JUDGMENT-PARITY.md index c0aed2787e..fdcf6f31f2 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: @@ -11,7 +11,7 @@ The suite verifies: - immutable full 1.x render hashes plus canonical specialist-render equality, with the excluded onboarding wrapper and lazy section references asserted explicitly; - preservation of nine behavioral contract dimensions per module; - 25 structured non-keyword routing fixtures with active/skipped modules, depth, mutation, and web context; -- 25 upstream judgment-port regression fixtures and anchors; +- 26 upstream judgment-port regression fixtures and anchors; - all linked asset copies against their pinned Git blobs; - frontmatter and `agents/openai.yaml` schema for each public skill. diff --git a/docs/gstack-2/JUDGMENT-PROVENANCE.json b/docs/gstack-2/JUDGMENT-PROVENANCE.json index ac3b722559..fb112ec96f 100644 --- a/docs/gstack-2/JUDGMENT-PROVENANCE.json +++ b/docs/gstack-2/JUDGMENT-PROVENANCE.json @@ -17,7 +17,7 @@ "packaged_section_copies": 17, "internal_execution_adapters": 1, "scenarios": 25, - "bug_fix_ports": 25, + "bug_fix_ports": 26, "assets": 78, "dependency_copies": 4, "runtime_helpers": 41 @@ -90,7 +90,8 @@ 679, 2030, 1049, - 1116 + 1116, + 2000 ], "original_source_file": "office-hours/SKILL.md.tmpl", "original_line_range": "1-526", @@ -7421,6 +7422,15 @@ "review" ], "anchor": "GSTACK2_FIX_452_CLAUDEMD_REVIEW_SECTION" + }, + { + "pr": 2000, + "url": "https://github.com/garrytan/gstack/issues/2000", + "title": "Design docs live in the repo, fit one page, and record decisions only", + "targets": [ + "office-hours" + ], + "anchor": "GSTACK2_FIX_2000_DESIGN_DOC_PLACEMENT_AND_LENGTH" } ] } diff --git a/docs/gstack-2/SKILL-MIGRATION.md b/docs/gstack-2/SKILL-MIGRATION.md index 0f90b0b46d..f6c2f504cc 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, #2000 | | `/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 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..1e6fbf2d19 100644 --- a/evals/parity/contracts/office-hours.json +++ b/evals/parity/contracts/office-hours.json @@ -15,7 +15,8 @@ 679, 2030, 1049, - 1116 + 1116, + 2000 ], "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..fb112ec96f 100644 --- a/evals/parity/manifest.json +++ b/evals/parity/manifest.json @@ -17,7 +17,7 @@ "packaged_section_copies": 17, "internal_execution_adapters": 1, "scenarios": 25, - "bug_fix_ports": 25, + "bug_fix_ports": 26, "assets": 78, "dependency_copies": 4, "runtime_helpers": 41 @@ -90,7 +90,8 @@ 679, 2030, 1049, - 1116 + 1116, + 2000 ], "original_source_file": "office-hours/SKILL.md.tmpl", "original_line_range": "1-526", @@ -7421,6 +7422,15 @@ "review" ], "anchor": "GSTACK2_FIX_452_CLAUDEMD_REVIEW_SECTION" + }, + { + "pr": 2000, + "url": "https://github.com/garrytan/gstack/issues/2000", + "title": "Design docs live in the repo, fit one page, and record decisions only", + "targets": [ + "office-hours" + ], + "anchor": "GSTACK2_FIX_2000_DESIGN_DOC_PLACEMENT_AND_LENGTH" } ] } diff --git a/evals/parity/regressions/pr-2000.json b/evals/parity/regressions/pr-2000.json new file mode 100644 index 0000000000..4c891e086a --- /dev/null +++ b/evals/parity/regressions/pr-2000.json @@ -0,0 +1,23 @@ +{ + "pr": 2000, + "url": "https://github.com/garrytan/gstack/issues/2000", + "title": "Design docs live in the repo, fit one page, and record decisions only", + "targets": [ + "office-hours" + ], + "anchor": "GSTACK2_FIX_2000_DESIGN_DOC_PLACEMENT_AND_LENGTH", + "body": "### Design-doc placement and length\n\nThe design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to \"the design doc\" without saying where it is.\n\nDefault to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness.", + "regression": { + "input": { + "in_git_repo": true, + "ruled_out_approaches": 3 + }, + "expected": { + "canonical_location": "repo-docs-designs", + "state_dir_copy_for_discovery": true, + "absolute_path_announced": true, + "ruled_out_max_lines_each": 1, + "one_page_default": true + } + } +} diff --git a/evals/parity/transcripts/deterministic/office-hours.json b/evals/parity/transcripts/deterministic/office-hours.json index 2dfa0becfa..7af18c9674 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/2000", + "reproduced_defect": "Design docs live in the repo, fit one page, and record decisions only", + "regression_fixture": "evals/parity/regressions/pr-2000.json", + "explanation": "### Design-doc placement and length\n\nThe design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to \"the design doc\" without saying where it is.\n\nDefault to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness." } ] } diff --git a/skills/plan/references/legacy/office-hours.md b/skills/plan/references/legacy/office-hours.md index 4909fd0501..baf3955b78 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: PR #2000 + +[Design docs live in the repo, fit one page, and record decisions only](https://github.com/garrytan/gstack/issues/2000) + +### Design-doc placement and length + +The design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to "the design doc" without saying where it is. + +Default to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness. + From 4cb849789676cabe2d227408dd14c3f46f9d1359 Mon Sep 17 00:00:00 2001 From: Sinabina Date: Wed, 22 Jul 2026 16:37:48 -0700 Subject: [PATCH 3/3] =?UTF-8?q?fix(gstack2):=20overlay=20#2000=20=E2=80=94?= =?UTF-8?q?=20concision=20rule=20instead=20of=20hard=20one-page=20cap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per user feedback: no fixed page limit; bullets over paragraphs, every word earns its place, ruled-out approaches still one line each. Co-Authored-By: Claude Fable 5 --- docs/gstack-2/JUDGMENT-PROVENANCE.json | 2 +- evals/parity/manifest.json | 2 +- evals/parity/regressions/pr-2000.json | 6 +++--- evals/parity/transcripts/deterministic/office-hours.json | 4 ++-- scripts/gstack2/bug-fix-overlays.ts | 8 ++++---- skills/plan/references/legacy/office-hours.md | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/gstack-2/JUDGMENT-PROVENANCE.json b/docs/gstack-2/JUDGMENT-PROVENANCE.json index fb112ec96f..feda81ef90 100644 --- a/docs/gstack-2/JUDGMENT-PROVENANCE.json +++ b/docs/gstack-2/JUDGMENT-PROVENANCE.json @@ -7426,7 +7426,7 @@ { "pr": 2000, "url": "https://github.com/garrytan/gstack/issues/2000", - "title": "Design docs live in the repo, fit one page, and record decisions only", + "title": "Design docs live in the repo, stay concise, and record decisions only", "targets": [ "office-hours" ], diff --git a/evals/parity/manifest.json b/evals/parity/manifest.json index fb112ec96f..feda81ef90 100644 --- a/evals/parity/manifest.json +++ b/evals/parity/manifest.json @@ -7426,7 +7426,7 @@ { "pr": 2000, "url": "https://github.com/garrytan/gstack/issues/2000", - "title": "Design docs live in the repo, fit one page, and record decisions only", + "title": "Design docs live in the repo, stay concise, and record decisions only", "targets": [ "office-hours" ], diff --git a/evals/parity/regressions/pr-2000.json b/evals/parity/regressions/pr-2000.json index 4c891e086a..f484a11a2b 100644 --- a/evals/parity/regressions/pr-2000.json +++ b/evals/parity/regressions/pr-2000.json @@ -1,12 +1,12 @@ { "pr": 2000, "url": "https://github.com/garrytan/gstack/issues/2000", - "title": "Design docs live in the repo, fit one page, and record decisions only", + "title": "Design docs live in the repo, stay concise, and record decisions only", "targets": [ "office-hours" ], "anchor": "GSTACK2_FIX_2000_DESIGN_DOC_PLACEMENT_AND_LENGTH", - "body": "### Design-doc placement and length\n\nThe design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to \"the design doc\" without saying where it is.\n\nDefault to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness.", + "body": "### Design-doc placement and length\n\nThe design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to \"the design doc\" without saying where it is.\n\nThere is no fixed page limit, but every word must earn its place. Prefer bullet points over paragraphs: one bullet per decision with its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Cut preamble, hedging, and restated context; extra length must be earned by genuinely open questions, not by template completeness.", "regression": { "input": { "in_git_repo": true, @@ -17,7 +17,7 @@ "state_dir_copy_for_discovery": true, "absolute_path_announced": true, "ruled_out_max_lines_each": 1, - "one_page_default": true + "bullets_over_paragraphs": true } } } diff --git a/evals/parity/transcripts/deterministic/office-hours.json b/evals/parity/transcripts/deterministic/office-hours.json index 7af18c9674..e9db07910c 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/2000", - "reproduced_defect": "Design docs live in the repo, fit one page, and record decisions only", + "reproduced_defect": "Design docs live in the repo, stay concise, and record decisions only", "regression_fixture": "evals/parity/regressions/pr-2000.json", - "explanation": "### Design-doc placement and length\n\nThe design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to \"the design doc\" without saying where it is.\n\nDefault to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness." + "explanation": "### Design-doc placement and length\n\nThe design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to \"the design doc\" without saying where it is.\n\nThere is no fixed page limit, but every word must earn its place. Prefer bullet points over paragraphs: one bullet per decision with its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Cut preamble, hedging, and restated context; extra length must be earned by genuinely open questions, not by template completeness." } ] } diff --git a/scripts/gstack2/bug-fix-overlays.ts b/scripts/gstack2/bug-fix-overlays.ts index 802e6075c2..379d8ab91b 100644 --- a/scripts/gstack2/bug-fix-overlays.ts +++ b/scripts/gstack2/bug-fix-overlays.ts @@ -359,14 +359,14 @@ Before scope-drift detection, read a \`## Review\` section from the project CLAU { pr: 2000, url: 'https://github.com/garrytan/gstack/issues/2000', - title: 'Design docs live in the repo, fit one page, and record decisions only', + title: 'Design docs live in the repo, stay concise, and record decisions only', targets: ['office-hours'], anchor: 'GSTACK2_FIX_2000_DESIGN_DOC_PLACEMENT_AND_LENGTH', body: `### Design-doc placement and length The design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at \`docs/designs/\` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the \`{user}-{branch}-design-{datetime}\` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to "the design doc" without saying where it is. -Default to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness.`, +There is no fixed page limit, but every word must earn its place. Prefer bullet points over paragraphs: one bullet per decision with its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Cut preamble, hedging, and restated context; extra length must be earned by genuinely open questions, not by template completeness.`, regression: { input: { in_git_repo: true, ruled_out_approaches: 3 }, expected: { @@ -374,7 +374,7 @@ Default to one page. Record each decision and its why. An approach the user rule state_dir_copy_for_discovery: true, absolute_path_announced: true, ruled_out_max_lines_each: 1, - one_page_default: true, + bullets_over_paragraphs: true, }, }, }, @@ -559,7 +559,7 @@ export function evaluateBugFixRegression(pr: number, rawInput: unknown): Record< state_dir_copy_for_discovery: true, absolute_path_announced: true, ruled_out_max_lines_each: 1, - one_page_default: true, + bullets_over_paragraphs: true, }; default: throw new Error(`No executable GStack 2 regression evaluator for PR #${pr}`); diff --git a/skills/plan/references/legacy/office-hours.md b/skills/plan/references/legacy/office-hours.md index baf3955b78..37a101e5a1 100644 --- a/skills/plan/references/legacy/office-hours.md +++ b/skills/plan/references/legacy/office-hours.md @@ -774,11 +774,11 @@ At the Phase 5 approval gate, print the full design-doc body as direct assistant ## Upstream judgment port: PR #2000 -[Design docs live in the repo, fit one page, and record decisions only](https://github.com/garrytan/gstack/issues/2000) +[Design docs live in the repo, stay concise, and record decisions only](https://github.com/garrytan/gstack/issues/2000) ### Design-doc placement and length The design doc is a decision record for the user, not a transcript of the session. When the working directory is a git repository, write the canonical doc inside it at `docs/designs/` (or the design-doc directory the project's CLAUDE.md names), where it is visible, reviewable, and versioned with the code; fall back to the state directory only outside a repository. Keep the `{user}-{branch}-design-{datetime}` state-directory copy solely so downstream skills discover it. Whenever the doc is mentioned, give its absolute repo path — never refer to "the design doc" without saying where it is. -Default to one page. Record each decision and its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Length beyond a page must be earned by genuinely open questions, not by template completeness. +There is no fixed page limit, but every word must earn its place. Prefer bullet points over paragraphs: one bullet per decision with its why. An approach the user ruled out during the session gets at most one line — name plus rejection reason — never its own section, comparison matrix, or re-argued case. Omit template sections that are empty or that restate what the conversation already settled. Cut preamble, hedging, and restated context; extra length must be earned by genuinely open questions, not by template completeness.