diff --git a/CHANGELOG.md b/CHANGELOG.md index ce08707e5..c0854750a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ Run `/gstack-upgrade`, then start `/office-hours` on a new idea. Before the doc ### Itemized changes #### Fixed -- /office-hours reads your builder profile before it logs the session and carries the earlier tier, count and last assignment to the closing. This session is counted as the prior count plus one. If the profile can't be read, it treats the session as your first and tells you so. (#2801) +- /office-hours reads your builder profile before it logs the session and carries the earlier tier, count and last assignment to the closing. This session is counted as the prior count plus one. If the profile can't be read, it treats the session as your first and tells you so. A returning greeting skips "last time" when the profile has no last assignment or project, and just says "Welcome back." (#2801) - /office-hours prints the complete design doc in the conversation before asking you to approve it. (#879) - /office-hours logs `success` only when this run's own design doc exists and isn't empty. It checks the doc's exact path under your gstack state root. A session that ends without a doc is logged as `abort` or `error` with failed step `design_doc`. (#1049) - `/plan-ceo-review`, `/plan-eng-review`, `/plan-devex-review` and `/autoplan` skip the "run /office-hours first?" offer in spawned and headless sessions, where nobody can answer it, and continue with the standard review. (#1958) diff --git a/office-hours/sections/design-and-handoff.md b/office-hours/sections/design-and-handoff.md index 6f24cae95..f001c2576 100644 --- a/office-hours/sections/design-and-handoff.md +++ b/office-hours/sections/design-and-handoff.md @@ -446,6 +446,9 @@ If CROSS_PROJECT is false (same project as last time): If CROSS_PROJECT is true (different project): "Welcome back. Last time we talked about [LAST_PROJECT]. Still on that, or onto something new?" +If the value a greeting names (LAST_ASSIGNMENT or LAST_PROJECT) is empty, skip that clause and +its question and say only "Welcome back." Backfilled profiles can have a tier without them. + Then: "No pitch this time. You already know about YC. Let's talk about your work." **Tone examples (prevent generic AI voice):** @@ -468,6 +471,7 @@ Then proceed to Founder Resources below. Lead with recognition and session count. "Welcome back. This is session [PRIOR_SESSION_COUNT + 1]. Last time: [LAST_ASSIGNMENT]. How'd it go?" +If LAST_ASSIGNMENT is empty, skip the "Last time" clause and its question. **Tone examples:** - GOOD: "You've been at this for 5 sessions now. Your designs keep getting sharper. Let me show you what I've noticed." diff --git a/office-hours/sections/design-and-handoff.md.tmpl b/office-hours/sections/design-and-handoff.md.tmpl index f3c88f914..0a3d51765 100644 --- a/office-hours/sections/design-and-handoff.md.tmpl +++ b/office-hours/sections/design-and-handoff.md.tmpl @@ -292,6 +292,9 @@ If CROSS_PROJECT is false (same project as last time): If CROSS_PROJECT is true (different project): "Welcome back. Last time we talked about [LAST_PROJECT]. Still on that, or onto something new?" +If the value a greeting names (LAST_ASSIGNMENT or LAST_PROJECT) is empty, skip that clause and +its question and say only "Welcome back." Backfilled profiles can have a tier without them. + Then: "No pitch this time. You already know about YC. Let's talk about your work." **Tone examples (prevent generic AI voice):** @@ -314,6 +317,7 @@ Then proceed to Founder Resources below. Lead with recognition and session count. "Welcome back. This is session [PRIOR_SESSION_COUNT + 1]. Last time: [LAST_ASSIGNMENT]. How'd it go?" +If LAST_ASSIGNMENT is empty, skip the "Last time" clause and its question. **Tone examples:** - GOOD: "You've been at this for 5 sessions now. Your designs keep getting sharper. Let me show you what I've noticed." diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index 60b3a0855..d83e84ff0 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -1999,6 +1999,16 @@ describe('office-hours closing reads the builder profile before logging the sess expectAbsent(tiers, ['[SESSION_COUNT]', 'from profile]'], 'tier paths'); }); + test('welcome_back and regular greetings drop a last-session clause whose value is empty', () => { + const welcomeBack = between(handoff, '### If TIER = welcome_back', '### If TIER = regular'); + const regular = between(handoff, '### If TIER = regular', '### If TIER = inner_circle'); + expectTokens(welcomeBack, ['[LAST_ASSIGNMENT]', '[LAST_PROJECT]', '"Welcome back."'], 'welcome_back'); + expectMentions(welcomeBack, [['last_assignment', 'last_project', 'empty', 'skip']], 'welcome_back'); + expectOrdered(welcomeBack, ['Last time we talked about [LAST_PROJECT]', 'empty'], 'welcome_back'); + expectTokens(regular, ['Last time: [LAST_ASSIGNMENT]'], 'regular'); + expectMentions(regular, [['last_assignment', 'empty', 'skip']], 'regular'); + }); + test('executing the rendered blocks in order: a first session reads introduction, a failed read is marked', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'oh-tier-')); try { diff --git a/test/helpers/carve-guards.ts b/test/helpers/carve-guards.ts index 4c34681ab..78dc8dcf9 100644 --- a/test/helpers/carve-guards.ts +++ b/test/helpers/carve-guards.ts @@ -353,7 +353,7 @@ do not launch the downstream skill or open a browser.`, maxSkeletonBytes: 94_900, // Office-hours + sketch outside voices include host guards and completion checks. + v1.91.19.0 wave: Q open-question prose form (#2729, approved Q3), DESIGN_READY --version probe (B4), Aside ~/.local/bin fallback (E7), verdict-form outside voice (INV-1), plus v1.91.17.0's round accounting (#3022) merged in; measured 89,684 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 92,590 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; skeleton measured 92,869 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; skeleton measured 92,930 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; skeleton measured 92,756 (2026-10-07). Merged with the guard area: measured skeleton 93,099 (2026-10-07). + fix wave PR D: the Phase 4.5 builder-profile read before the session log (#2801) and the pre-telemetry design-doc check (#1049); measured skeleton 94,877 (2026-10-07). minUnionBytes: 115_800, // Phase 4 wave 4; measured union 118,175 mustContain: ['design doc', 'problem statement'], - maxSizeRatio: 1.1690, // + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 149,758 / 131,110 = 1.1422 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 150,037 / 131,110 = 1.1444 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 150,098 / 131,110 = 1.1448 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 150,011 / 131,110 = 1.1442 (2026-10-07). Merged with the guard area: measured 150,354 / 131,110 = 1.1468 (2026-10-07). + fix wave PR D: builder-profile read before the session log with Phase 6 using the carried values (#2801), the inline design doc before approval (#879) and the pre-telemetry design-doc check (#1049); measured 153,206 / 131,110 = 1.1685 (2026-10-07). + maxSizeRatio: 1.1710, // + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 149,758 / 131,110 = 1.1422 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 150,037 / 131,110 = 1.1444 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 150,098 / 131,110 = 1.1448 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 150,011 / 131,110 = 1.1442 (2026-10-07). Merged with the guard area: measured 150,354 / 131,110 = 1.1468 (2026-10-07). + fix wave PR D: builder-profile read before the session log with Phase 6 using the carried values (#2801), the inline design doc before approval (#879) and the pre-telemetry design-doc check (#1049); measured 153,206 / 131,110 = 1.1685 (2026-10-07). + empty LAST_ASSIGNMENT/LAST_PROJECT guards in the welcome_back and regular greetings (backfilled profiles); measured 153,469 / 131,110 = 1.1705 (2026-10-08). }, 'document-release': { skill: 'document-release',