首页
/ gstack /office-hours 深度解析:AI 编码 Agent 的"YC Office Hours"双模式头脑风暴工作流

gstack /office-hours 深度解析:AI 编码 Agent 的"YC Office Hours"双模式头脑风暴工作流

2026-09-06 15:07:17作者:贡沫苏Truman

在 gstack(Garry Tan 的 Claude Code 工具集)中,/office-hours 是整条工作流的起点技能:它在任何代码写之前,先用"YC 办公室时间"式的追问把产品想法逼问清楚。本文基于仓库中的 office-hours/SKILL.md 及其按需加载的 design-and-handoff 章节,完整梳理这个技能的两种模式(Startup 创业诊断 / Builder 构建者共创)、六个强制性追问、跨模型第二意见、设计文档双写与对抗性评审闭环,以及它如何被下游技能消费——读完你能理解一套"从模糊想法到可评审设计文档"的 Agent 工作流是如何被定义、门禁与测试验证的。

一、技能定位与硬性约束:只产出设计文档,不写一行代码

office-hours/SKILL.md 的 frontmatter 声明了技能的基本契约(SKILL.md#L1-L47):

  • name: office-hoursversion: 2.0.0preamble-tier: 3
  • allowed-tools 限定为 Bash、Read、Grep、Glob、Write、Edit、AskUserQuestion、WebSearch;
  • triggers 触发词包括 brainstorm thisis this worth buildinghelp me think throughoffice hours
  • gbrain 块声明了 4 条上下文查询(schema 1):本仓库历史的 ceo-plan 会话(prior-sessions,limit 5)、构建者画像快照(builder-profile,取 ~/.gstack/builder-profile.jsonl 最后一行)、本项目最近的设计文档(design-doc-history,glob ~/.gstack/projects/{repo_slug}/*-design-*.md,limit 3)、最近的 eureka 时刻(prior-eureka,tail 5)。

技能正文开头就立下不可协商的硬门禁(HARD GATE,SKILL.md#L916-L918):

You are a YC office hours partner. ... This skill produces design docs, not code. HARD GATE: Do NOT invoke any implementation skill, write any code, scaffold any project, or take any implementation action. Your only output is a design document.

结尾的 "Important Rules"(SKILL.md#L1730-L1739)再次收口:

  1. Never start implementation — 连脚手架都不许搭;
  2. Questions ONE AT A TIME — 绝不把多个问题塞进一次 AskUserQuestion;
  3. The assignment is mandatory — 每次会话必须以一个真实世界的行动收尾,而不是"去构建吧";
  4. 即使用户给出了完整方案,也必须跑 Phase 3(前提挑战)和 Phase 4(备选方案生成);
  5. 完成状态必须用四值协议报告:DONE(文档获批)、DONE_WITH_CONCERNSNEEDS_CONTEXTBLOCKED

从仓库结构看,这个技能采用"骨架 + 按需章节"(sectioned skill)设计:SKILL.md 是决策树骨架,遇到特定情况才去读 office-hours/sections/design-and-handoff.md,章节清单登记在 office-hours/sections/manifest.json 中(trigger 字段写明"写作设计文档并执行分层关系交接(Phases 5-6)时读取")。文末还有一条自检:如果设计文档和交接流程是凭记忆产出的、没有实际 Read 过该章节文件,必须停下来重读——该章节才是这一步的唯一事实来源。

二、Preamble:技能启动前采集了什么

与 gstack 其他技能一致,office-hours 的第一步是执行一段 Bash preamble(SKILL.md#L66-L182)。它不做业务逻辑,只把会话环境探测齐备并回显给模型,主要包括:

  • 会话与仓库状态:当前 git 分支(BRANCH)、会话类型 SESSION_KINDinteractive / headless / spawned,非法值回退为 interactive)、REPO_MODE(solo / collaborative / unknown,决定发现问题时主动修还是只上报);
  • 配置开关PROACTIVE(是否允许技能主动建议)、SKILL_PREFIXTELEMETRYEXPLAIN_LEVELdefault / terse,非这两值一律归一为 default)、QUESTION_TUNINGUPDATE_CHECKCHECKPOINT_MODE
  • Plan mode 探测:依据 CLAUDE_PLAN_FILE / GSTACK_PLAN_MODE 环境变量导出 GSTACK_PLAN_MODE=active|inactive,供按 plan 模式切换行为的技能读取;
  • 首次运行检测:仅在 ACTIVATED=no 且非 headless 时跑一次项目形态检测器(gstack-first-task-detect),避免每次运行都走冷路径;
  • 遥测与时间线:向 ~/.gstack/analytics/skill-usage.jsonl 追加一条本地记录,并用 gstack-timeline-log 后台记录 started 事件;
  • 经验回放:若 ~/.gstack/projects/$SLUG/learnings.jsonl 超过 5 条,自动 gstack-learnings-search --limit 3 把历史教训带进上下文。

紧随其后的是 "Artifacts Sync(skill start)" 块(SKILL.md#L499-L631):探测 ~/.gstack/.git 是否存在以判断是否配置了跨机 artifacts 同步仓;检测 gbrain 的 remote-MCP 模式(直接读 ~/.claude.json 的 mcpServers.gbrain 条目,按 url|http|ssestdio 区分 remote-http / local-stdio);本地模式则做带 24 小时节流(.brain-last-pull)的 git fetch + merge --ff-only,再 gstack-brain-sync --once。若输出 ARTIFACTS_SYNC: off 且从未询问过,会触发一次隐私门禁三选一(Everything allowlisted / Only artifacts / Decline),对应 gstack-config set artifacts_sync_mode <choice>

技能进入提问之前还有一段 Brain Context(preflight)SKILL.md#L924-L959),从脑缓存拉取五份摘要:

eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
{
  printf '## Brain Context\n\n'
  printf '\n### %s\n\n' "product"
  ~/.claude/skills/gstack/bin/gstack-brain-cache get product --project "$SLUG" 2>/dev/null || printf '_(no product digest available yet)_\n'
  printf '\n### %s\n\n' "goals"
  ~/.claude/skills/gstack/bin/gstack-brain-cache get goals --project "$SLUG" 2>/dev/null || printf '_(no goals digest available yet)_\n'
  printf '\n### %s\n\n' "user-profile"
  ~/.claude/skills/gstack/bin/gstack-brain-cache get user-profile  2>/dev/null || printf '_(no user-profile digest available yet)_\n'
  printf '\n### %s\n\n' "recent-decisions"
  ~/.claude/skills/gstack/bin/gstack-brain-cache get recent-decisions --project "$SLUG" 2>/dev/null || printf '_(no recent-decisions digest available yet)_\n'
  printf '\n### %s\n\n' "salience"
  ~/.claude/skills/gstack/bin/gstack-brain-cache get salience --project "$SLUG" 2>/dev/null || printf '_(no salience digest available yet)_\n'
} > /tmp/.gstack-brain-context-$$.md 2>/dev/null
[ -s /tmp/.gstack-brain-context-$$.md ] && cat /tmp/.gstack-brain-context-$$.md
rm -f /tmp/.gstack-brain-context-$$.md 2>/dev/null || true

使用规则很明确:product 摘要里已写了价值主张/目标用户/阶段就不重复问;goals 摘要列了活跃目标就据此校准建议;recent-decisions 与本次方向冲突时必须指出;摘要缺失(no ... digest available yet)则视为冷启动,向用户提问。隐私上,salience 摘要经过白名单过滤(默认仅 projects/gstack/concepts/)。

三、Phase 1:上下文收集与模式判定

技能自称是"决策树骨架"(Section index,SKILL.md#L1046-L1054)。Phase 1 做四件准备(SKILL.md#L962-L1040):

  1. CLAUDE.mdTODOS.md(若存在),跑 git log --oneline -30git diff origin/main --stat 理解近期上下文,用 Grep/Glob 圈定代码面;
  2. 列出本项目的既有设计文档(ls -t ~/.gstack/projects/$SLUG/*-design-*.md),若存在则向用户报"Prior designs for this project: [标题 + 日期]";
  3. Prior Learnings:按 cross_project_learnings 配置决定是否带 --cross-project 参数搜索历史教训;首次遇到 unset 时会弹一次 AskUserQuestion(启用跨项目学习 / 仅项目内),选择写入 gstack-config set cross_project_learnings true|false。命中历史教训时要求显式展示 "Prior learning applied: [key] (confidence N/10, from [date])",让复利效应可见;
  4. 真正的分岔点:问"你想用它做什么?"。六个选项映射到两种模式:
用户目标 模式
Building a startup(或考虑中) Startup mode(Phase 2A)
Intrapreneurship(公司内部项目,要快速交付) Startup mode(Phase 2A)
Hackathon / demo Builder mode(Phase 2B)
Open source / research Builder mode(Phase 2B)
Learning Builder mode(Phase 2B)
Having fun(side project) Builder mode(Phase 2B)

只有 Startup/intrapreneurship 模式需要评估产品阶段(Pre-product / Has users / Has paying customers)。Phase 1 的交付物是一段"Here's what I understand about this project and the area you want to change: ..."的理解陈述。

四、Phase 2A:Startup 模式 —— 六个强制性追问

这是整个技能最核心的部分(SKILL.md#L1056-L1217)。它的运行原则(Operating Principles)被定义为"不可协商":

  • Specificity is the only currency — "医疗企业"不是客户,"所有人都会需要"等于找不到人;
  • Interest is not demand — 等待列表、注册、"挺有意思"都不算数;付费、行为、服务宕机时用户来电话才算;
  • 用户的语言胜过创始人的 pitch — 最好的客户描述价值的方式与营销文案不同,就重写文案;
  • Watch, don't demo — 引导式演示学不到真东西,坐在用户后面看他挣扎并忍住插话才行;
  • 现状是你真正的竞争对手 — 不是别的创业公司,而是用户现在用电子表格加 Slack 消息拼凑的 workaround;
  • Narrow beats wide, early — 最小到"本周就有人付真钱"的版本比完整平台愿景更有价值。

响应姿态(Response Posture)要求"直接到让人不舒服"、每个回答都表态并说明什么证据会改变立场、"校准式认可而非表扬"(好答案的最好奖励是更难的追问)、点名常见失败模式、以作业(assignment)收尾。文档还列出一组 Anti-Sycophancy Rules:诊断阶段禁止说 "That's an interesting approach"、"There are many ways to think about this"、"You might want to consider..."、"That could work"、"I can see why you'd think that",并给出了 5 组软探索 vs 严格诊断的对照话术(Pushback Patterns),例如:

  • 模糊市场 → "现在有一万种 AI 开发者工具。具体哪个开发者每周浪费 2 小时以上的哪个任务被你消灭了?说出那个人。"
  • 社交证明 → "喜欢一个想法是免费的。有人提出付费吗?有人问什么时候上线吗?原型坏了有人发火吗?Love is not demand."
  • 平台愿景 → "这是红旗。如果更小版本无法产生价值,通常说明价值主张还不清晰——不是产品需要更大。用户本周愿意为什么付钱?"
  • 增长率当愿景 → "增长率不是愿景。你赛道里每个竞争对手都能引用同一个数字。"
  • 未定义术语 → "'Seamless' 不是产品功能,是一种感觉。哪个具体步骤导致用户流失?流失率多少?你看过吗?"

六个问题与智能路由

六个问题必须一次只问一个,每个都追问到答案具体、有证据、且不舒服为止。文档给出按产品阶段的路由表——不是每次都要问满六个:

产品阶段 需要问的问题
Pre-product(有想法,无用户) Q1, Q2, Q3
Has users(有用户,未付费) Q2, Q4, Q5
Has paying customers Q4, Q5, Q6
纯工程/基础设施 Q2, Q4

内部项目(intrapreneurship)的适配:Q4 改写为"什么是最小的、能让你的 VP/赞助人批准立项的 demo";Q6 改写为"如果重组、你的支持者离开,这个项目还活着吗"。

六个问题的原文问法与红旗信号(红标即典型错误答案):

  1. Q1 Demand Reality(需求现实):"你最有力的证据是什么——不是'感兴趣'、不是'注册了等待列表',而是它明天消失他会真的生气?"追问到具体行为:有人付费、有人扩大用量、有人把工作流程建在它上面。红旗:"人们说挺有意思"、"500 个等待列表注册"、"VC 对这个赛道兴奋"。创始人第一次回答 Q1 后还要做三项框架检查:术语是否精确定义、隐含假设是什么("我需要融资"假设了必须有资本)、是真实痛点还是思想实验。若框架不精确,要在 60 秒内"建设性重述"而非解散问题。
  2. Q2 Status Quo(现状):"你的用户现在靠什么解决这问题——哪怕很烂?这个 workaround 花掉他们什么?"追问到具体工作流、小时数、浪费的钱、为了手工完成而雇的人。红旗:"没有解决方案,所以机会很大"——如果真的什么都没有、没人做,问题大概率不够痛。
  3. Q3 Desperate Specificity(绝望的具体性):"说出最需要它的那个真实的人。他的职位?什么让他升职?什么让他被炒?什么让他失眠?"追问到名字、角色、不解决就面临的后果,最好是他亲口说的。红旗:类目级答案——"医疗企业"、"SMB"、"市场团队","类目是过滤器,不是人,你不能给一个类目发邮箱"。文档特别给出 FORCING 版本的示范:把"职业后果 / 日常痛点 / 周末项目"按领域(B2B / 消费 / 爱好开源)匹配,"压力在叠加里——不要把它压缩成单句提问"。
  4. Q4 Narrowest Wedge(最窄楔子):"最小的版本是什么,有人本周就为它付真钱——而不是等你建完平台?"追问到一个功能、一条工作流,甚至一封每周邮件。附加追问:"如果用户什么都不用做就能得到价值呢?没有登录、没有集成、没有配置。"红旗:"建完平台前没人能用"、"砍掉就不差异化了"。
  5. Q5 Observation & Surprise(观察与惊讶):"你真的坐下去看过某个人无帮助地使用它吗?他们做了什么让你惊讶?"红旗:"我们发了问卷"、"我们做了几次 demo 通话"、"没什么惊喜,一切如预期"。问卷在撒谎,demo 是表演,"如预期"意味着答案被既有假设过滤过。金子:用户拿产品做它没被设计来做的事——那常常是真正的产品在浮现。
  6. Q6 Future-Fit(未来契合):"如果三年后世界看起来显著不同——它会不同——你的产品变得更必需还是更边缘?"红旗:"市场每年增长 20%"(那是每个对手都能说的 rising tide 论证)。

流程细节:每个问题后 STOP 等回答;Smart-skip(前面的回答已覆盖后面的问题就跳过);Escape hatch——用户表现出不耐烦时,先坚持("硬问题才是价值,跳过它们就像跳过考试直接开处方"),从路由表补问最多 2 个关键问题后进入 Phase 3;用户第二次反抗就尊重,直接进 Phase 3;只有 0 个剩余问题时才直接进,且只有当用户给出带真实证据(现有用户、收入数字、具名客户)的完整方案时才允许完全跳过提问——即便如此 Phase 3 与 Phase 4 仍必须运行。

五、Phase 2B:Builder 模式 —— 设计伙伴式共创

面向为乐趣、学习、开源、黑客松或研究而构建的用户(SKILL.md#L1220-L1262)。四条运行原则:Delight is the currency(什么让人说"whoa")、Ship something you can show people最好的 side project 解决你自己的问题Explore before you optimize。文档用一组对照示范界定语气边界:

  • 应避免的 STRUCTURED:"考虑加一个分享功能,能通过病毒传播提升留存。"
  • 应追求的 WILD:"哦——如果还能把可视化作为 live URL 分享呢?或者灌进 Slack 线程?或者让生成过程动画化,观众看着它自己画出来?每个都是 30 分钟的解锁,任何一个都能把它从'我用过的工具'变成'我给朋友看过的东西'。"

两者都是结果导向,但只有一个有"whoa"。Builder 模式的工作是浮现想法里最令人兴奋的版本,而非战略上最优的版本。提问是生成式而非审讯式(同样一次一个):这个最酷的版本是什么?你想给谁看?最快能得到可用/可分享产物的路径?现有最接近的东西是什么、你的差异化在哪?如果时间无限你会加什么(10x 版本)?

两个重要出口:用户说"just do it"或给出完整方案时,快速通道跳到 Phase 4;会话中途氛围漂移("其实这可能是个真公司"、提到客户/收入/融资)时,自然升级回 Startup 模式——"Okay, now we're talking — let me ask you some harder questions."

六、Phase 2.5 与 Phase 2.75:关联设计发现与格局感知

Phase 2.5 Related Design DiscoverySKILL.md#L1266-L1282):从用户的问题陈述中抽 3-5 个关键词,在设计文档里 grep:

setopt +o nomatch 2>/dev/null || true  # zsh compat
grep -li "<keyword1>\|<keyword2>\|<keyword3>" ~/.gstack/projects/$SLUG/*-design-*.md 2>/dev/null

命中则读出来并向用户报告(标题、作者、日期、分支、重叠要点),并 AskUserQuestion 问"基于这个已有设计还是从头开始"——这支撑了同一项目多人探索时的跨人发现。

Phase 2.75 Landscape AwarenessSKILL.md#L1286-L1319):先理解问题,再搜索"世界怎么看这个领域"。文档强调这不是竞品研究(那是 /design-consultation 的职责),而是理解世俗共识以便判断哪里可能是错的。关键约束:

  • 隐私门禁:搜索前必须 AskUserQuestion,说明只会发送"泛化的类别词(而非你的具体想法)",选项 A 搜索 / B 保持本会话私密(选 B 则整段跳过,只用分布内知识);
  • 搜索词只用泛化类别词,永不包含用户的具体产品名或保密概念;
  • Startup 模式搜三类查询:"[problem space] startup approach {年份}"、"[problem space] common mistakes"、"why [incumbent solution] fails/works";Builder 模式搜现有方案、开源替代与最佳实践;
  • 读前 2-3 条结果后做三层综合:Layer 1 大家都已经知道什么?Layer 2 搜索结果与当下讨论说什么?Layer 3 结合 Phase 2A/2B 学到的东西,世俗做法是否有错的理由?
  • Eureka 检查:若 Layer 3 出现真洞察,显式命名("EUREKA: 所有人都做 X 因为假设 [A],但 [会话证据] 表明这里错了,意味着 [推论]")并按 preamble 的模板记入 ~/.gstack/analytics/eureka.jsonl(jq 构造含 ts/skill/branch/insight 的 JSON 行);没有 eureka 就明说"世俗共识站得住,我们在它之上构建"。

该阶段的结果直接喂给 Phase 3:发现的"世俗做法为何失败"成为待挑战的前提;世俗共识坚固则抬高反驳它的门槛。WebSearch 不可用时跳过并注明"仅用分布内知识"。

七、Phase 3 前提挑战 与 Phase 3.5 跨模型第二意见

Phase 3 Premise ChallengeSKILL.md#L1323-L1342)在提方案前挑战前提,五个检查点:这是不是正确的问题(换个框定会不会简单得多)?什么都不做会怎样(真实痛点还是假设痛点)?哪些既有代码已经部分解决了(映射可复用的模式/工具/流程)?如果交付物是新工件(CLI、库、包、镜像、移动应用)——用户怎么拿到它(无分发的代码是没人在用的代码,设计必须含分发渠道与 CI/CD,或显式推迟)?仅 Startup 模式追加:Phase 2A 的诊断证据是否支持这个方向、缺口在哪?前提以"PREMISES: 1. [陈述] — agree/disagree?"格式输出,经 AskUserQuestion 确认,不同意就修理解并回环。

Phase 3.5 Cross-Model Second OpinionSKILL.md#L1345-L1445,可选)先做二进制探测 command -v codex,然后用 AskUserQuestion 询问是否要一个独立 AI 的第二意见("它没看过这段对话,只拿到结构化摘要,通常 2-5 分钟")。选 A 时的执行细节体现了一堆工程考量:

  1. 从 Phase 1-3 组装结构化上下文块(模式、问题陈述、关键问答含用户原话、格局发现、已同意前提、代码库背景);
  2. 写入临时文件防 shell 注入CODEX_PROMPT_FILE=$(mktemp /tmp/gstack-codex-oh-XXXXXXXX)),且提示词必须以文件系统边界声明开头——禁止 Codex 去读 ~/.claude/.claude/skills/ 等技能定义目录("那是给另一套 AI 系统的 Claude Code 技能定义……会浪费你的时间");
  3. 按模式注入不同指令:Startup 版要求 Codex 做四件事(钢人化最强版本、指出回答中最有揭示力的一点并引用原文、点名一个你认为错的前提及证据、48 小时一个工程师的原型方案,"直接、简洁、无前言");Builder 版则问最酷版本、什么最能激发表达者、哪个开源项目能到 50%、周末先构建什么;
  4. 执行命令(read-only 沙箱 + 5 分钟超时):
TMPERR_OH=$(mktemp /tmp/codex-oh-err-XXXXXXXX)
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
codex exec "$(cat "$CODEX_PROMPT_FILE")" -C "$_REPO_ROOT" -s read-only -c 'model_reasoning_effort="high"' -c 'web_search="cached"' < /dev/null 2>"$TMPERR_OH"
  1. 错误处理全部非阻塞(第二意见是质量增强,不是前置条件):认证失败提示 codex login、超时 5 分钟、空响应——任一情况都回退到 Claude subagent(经 Agent 工具派发,"全新上下文即真正的独立性");
  2. 输出必须逐字完整展示("do not truncate or summarize"),随后给出 3-5 条跨模型综合(哪里一致、哪里不一致、被挑战的前提是否改变建议);
  3. 前提修订检查:若 Codex 挑战了某条已同意前提,AskUserQuestion 问 A 修订 / B 保留原前提——选 B 且用户能阐述为什么不同意时,这本身是创始人信号(无理由的驳回不算数)。

八、Phase 4:备选方案生成(强制)与视觉探索

Phase 4(SKILL.md#L1449-L1481)是强制步骤:"Produce 2-3 distinct implementation approaches. This is NOT optional." 每个方案按固定格式描述:

APPROACH A: [Name]
  Summary: [1-2 sentences]
  Effort:  [S/M/L/XL]
  Risk:    [Low/Med/High]
  Pros:    [2-3 bullets]
  Cons:    [2-3 bullets]
  Reuses:  [existing code/patterns leveraged]

规则:至少 2 个、非平凡设计建议 3 个;必须有一个 "minimal viable"(文件最少、diff 最小、最快上线);必须有一个 "ideal architecture"(长期轨迹最佳、最优雅);可以有一个 creative/lateral(意想不到的路径,若 Phase 3.5 的第二意见提了原型,考虑作为起点)。最后给出一行 RECOMMENDATION: Choose [X] because [映射到创始人声明目标的一句话理由],并发出一次 AskUserQuestion 列出全部备选。这里有一个醒目的 STOP 门禁:在用户回答之前,不得进入 Phase 4.5、5、6 或任何设计文档生成——"看起来必胜的方案"依然是方案决策,写成聊天散文然后继续前进,正是这个门禁要防的失败模式。

Visual Design ExplorationSKILL.md#L1485-L1558)先探测 design 二进制:优先 <repo>/.claude/skills/gstack/design/dist/design,回退 ~/.claude/skills/gstack/design/dist/design。可用时的流程:$D variants --brief "<assembled brief>" --count 3 --output-dir "$_DESIGN_DIR/"(约 40 秒生成 3 个风格变体,_DESIGN_DIR~/.gstack/projects/$SLUG/designs/mockup-$(date +%Y%m%d);若仓库有 DESIGN.md 用它约束视觉风格,否则宽方向探索);$D compare --images ... --serve 打开对比板并阻塞到收到反馈(stdout 出结构化 JSON);"regenerated": true 时读 regenerateAction/remixSpec$D iterate 重新生成并 POST 到运行中的看板(daemon 路径 BOARD_URL: http://127.0.0.1:N/boards/<id>/curl -X POST "${BOARD_URL}api/reload"),否则保存批准结果 approved.json(含 approved_variant、feedback、date、screen、branch)供设计文档引用。

Visual Sketch(仅 UI 想法)SKILL.md#L1562-L1648):纯后端/基础设施则静默跳过。有 UI 时生成"故意粗糙"的自包含 HTML 线框(系统字体、细灰边、无颜色、手绘感;内联 CSS、无 CDN;最多 1-3 屏;用真实占位内容而非 Lorem ipsum;HTML 注释解释设计决策),落到 /tmp/gstack-sketch-$(date +%s).html,再用浏览二进制渲染截图($B goto "file://$SKETCH_FILE" && $B screenshot /tmp/gstack-sketch.png),展示后迭代;批准后可选"外部设计声音"(Codex 出视觉论点/内容计划/两个交互点,model_reasoning_effort="medium",Claude subagent 出备选美学方向),截图引用进设计文档的 Recommended Approach 部分,供 /plan-design-review/design-review 追溯"最初设想是什么"。

九、Phase 4.5:创始人信号综合

写文档前,先清点本次会话观察到的信号(SKILL.md#L1652-L1693),共 8 种:陈述了真实存在的问题(非假设)、点名了具体用户(人名不是类目)、对前提推了回(信念而非顺从)、项目解决他人也需要的问题、具备领域专长、展现品味(在意细节做对)、展现能动性(真在构建而非只规划)、在跨模型挑战下用推理捍卫了前提(Codex 不同意时保留原前提且能说出具体理由——无理由的驳回不算)。

信号清点后通过 gstack-developer-profile --log-session 追加一条 JSON 到 ~/.gstack/developer-profile.jsonsessions[](原子 mktemp+mv 写入),字段包括:datemode(startup/builder)、project_slugsignal_countsignals(信号名数组)、design_doc(Phase 5 将写入的路径,现在先构造好)、assignment(将布置的作业)、resources_shown(此刻置空,Phase 6 选完资源后再补一条 mode: "resources" 的记录)、topics(2-3 个主题词)。该画像被声明为"所有收尾状态的唯一事实来源"(层级、资源去重、旅程追踪)。

十、Phase 5:设计文档双写、脱敏扫描与对抗性评审

Phase 5 在按需章节 design-and-handoff.md 中(L3-L47)。写入位置:

eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" && mkdir -p ~/.gstack/projects/$SLUG
USER=$(whoami)
DATETIME=$(date +%Y%m%d-%H%M%S)
# 写入 ~/.gstack/projects/{slug}/{user}-{branch}-design-{datetime}.md

三条值得注意的机制:

  1. 设计谱系(lineage):写前检查本分支既有设计文档(ls -t ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md | head -1),若存在则新文档带 Supersedes: 字段引用它,形成可追溯的修订链;
  2. 仓库副本双写(dual-write,#703 + #2000):在 git 仓库内运行时,同时把文档写进仓库的 docs/designs/{topic-slug}.md——可见、可提交、团队可共享;~/.gstack 副本照写(记忆摄取与跨会话发现依赖它)。规则:先扫描再落盘——写临时文件后跑 gstack-redact --from-file <tmp>,退出码 3(HIGH)阻止仓库副本(保留私有副本并告知用户原因),退出码 2(MEDIUM)逐条确认;只读检出、非 git 目录、写入失败或 MEDIUM 未确认都是非阻塞回退——保留 ~/.gstack 副本并一句话说明跳过原因,交接照常继续;
  3. 决策记录的精简原则(#2000):文档是决策记录不是逐字稿——每个决策一条要点加理由;会话中被用户否决的方案只留一行(名字 + 否决理由),不复活整节重新论证;空模板章节直接省略;没有页数上限,但超出的篇幅必须来自真正未决的问题。

写完后向用户报路径(两处都写时注明"cross-session copy in ~/.gstack"),并说明 /plan-ceo-review/plan-eng-review 会自动找到它。

两套设计文档模板design-and-handoff.md#L49-L163)共享头部(# Design: {title} / Generated by /office-hours on {date} / Branch / Repo / Status: DRAFT / Mode / Supersedes)与尾部("## What I noticed about how you think"——观察式、导师式的反思,要求引用用户原话而非行为定性,2-4 条)。Startup 模板的章节序列:Problem Statement、Demand Evidence(Q1 的引用/数字/行为)、Status Quo(Q2 的当前工作流)、Target User & Narrowest Wedge(Q3+Q4)、Constraints、Premises、Cross-Model Perspective(仅当第二意见实际运行时出现,否则整节省略)、Approaches Considered(A/B)、Recommended Approach、Open Questions、Success Criteria、Distribution Plan(交付物如何到达用户 + CI/CD;已有部署流水线的 Web 服务可省略)、Dependencies、The Assignment(一个具体的真实世界行动,而非"去构建吧")。Builder 模板的对应差异:Demand Evidence 换为 What Makes This Cool(核心 delight/"whoa" 因子)、Dependencies 换为 Next Steps(具体的构建顺序:先做一二三)。

Spec Review Loopdesign-and-handoff.md#L167-L231)在把文档呈给用户之前跑一轮对抗性审查:派一个全新上下文的 reviewer subagent(它只能看到文档本身,看不到头脑风暴对话,保证真正的对抗独立性),按 5 个维度审查——Completeness(需求与边缘案例是否全覆盖)、Consistency(前后是否矛盾)、Clarity(工程师能否不问问题就实现)、Scope(是否越过原问题范围、YAGNI 违例)、Feasibility(隐藏复杂度)——每个维度记 PASS 或列具体问题加修复建议,最后给 1-10 总分。有 issue 则修复后重派,最多 3 轮;收敛守卫:连续两轮返回相同 issue 就停止循环,把未决问题固化为文档里的 "## Reviewer Concerns" 章节(下游技能看得到)。subagent 失败/超时则跳过整个循环并告知用户"Spec review unavailable — presenting unreviewed doc"——文档已落盘,评审是质量加成而非门禁。结束后把指标(iterations / issues_found / issues_fixed / remaining / quality_score)追加到 ~/.gstack/analytics/spec-review.jsonl。最后用 AskUserQuestion 呈交:A 批准(Status 改为 APPROVED)/ B 修订指定章节(回环)/ C 推倒重来(回 Phase 2)。

章节文件还包含两段 brain 侧写逻辑:Brain Calibration Write-Back(当技能做出值得追踪的类型化预测时,可写一条 kind: bet 的 take 进 brain,受双重门控:端点 brain 信任策略为 personalBRAIN_CALIBRATION_WRITEBACK 特性开关打开——文档注明今天为 false,待上游 gbrain v0.42+ 提供 takes_add MCP 操作后翻转),以及技能收尾后的 Brain Cache 后台刷新(gstack-brain-cache refresh --project "$SLUG" 放入后台,非阻塞,让下次调用受益)。

十一、Phase 6:分层关系交接

设计文档 APPROVED 后进入 Phase 6(design-and-handoff.md#L293-L448)。它先读 builder profile(gstack-builder-profile),按 SESSION_TIER 走且只走一条分层路径:

  • introduction(第 1 次会话):Beat 1 信号回映 + "黄金时代"框架(必须引用用户说过的原话——反水文规则给了 GOOD/BAD 对照,"你说了 Sarah,50 人物流公司里的运营经理"是好的,"你展现了出色的用户具体性"是坏的);Beat 2 一句 "One more thing." 重置注意力;Beat 3 "Garry's Personal Note"——按 Phase 4.5 的信号数选 top/middle/base 三档措辞(top 档:3+ 信号且点名了具体用户/收入/需求证据,随后 AskUserQuestion 是否考虑申请 Y Combinator),全部层级随后进入创始人资源环节;
  • welcome_back(第 2-3 次):以认出对方开场("Welcome back. Last time you were working on [LAST_ASSIGNMENT]...";跨项目则用 LAST_PROJECT),明确"这次没有 pitch",然后是信号回映与设计文档轨迹("你第一个设计是 [X],现在你到了 [Y]");
  • regular(第 4-7 次):报会话数、跨会话的弧线级信号回映("第 1 次你说'小型企业',现在你说'Sarah at Acme Corp'——这个具体性迁移就是信号")、累积信号可视化、条件性的 builder-to-founder 推动(仅当 profile 的 NUDGE_ELIGIBLE 为 true,且"必须让人觉得是挣来的,不是广播");第 5 次起自动生成 ~/.gstack/builder-journey.md 叙事弧线(第二人称讲故事而非数据表)并打开;
  • inner_circle(第 8 次+):"你已经做了 [N] 次会话、迭代了 [M] 份设计。呈现这种模式的人大多最终发布了。"数据说话,无需 pitch。

Founder Resources(所有层级)L452-L579)先跑常设退出检查:gstack-config get founder_resourcesfalse整节静默跳过("用户说了永不;配置比会话上下文与记忆指令活得久,所以永不言永不")。否则从 34 个资源池(Garry Tan 视频、YC Backstory / How to Build the Future、Lightcone 播客、YC Startup School、Paul Graham essays 五类)选 2-3 个,规则是混合类别、绝不重复已展示过的(去重日志 RESOURCES_SHOWN,34 个耗尽后整节跳过)、按会话情境匹配(犹豫要不要辞职、在做 AI 产品、苦于想法生成、觉得自己不像创始人、担心技术背景单一、不知道从哪开始、过度思考不发布、找联合创始人、初次创始人需要全景图)。展示后一句话常设选择("要我打开吗——或者说'再也不要给我看这些',这节就永远消失"),退出则写 founder_resources false读回验证后才许承诺。选定资源记入 builder profile(mode: "resources" 条目)与分析日志,再 AskUserQuestion 提供打开(A 全开 / B/C/D 单开 / E 跳过)。

Next-skill recommendationsL581-L630)把用户接回工作流闭环:按设计文档模式映射推荐(野心型 → /plan-ceo-review 压力测试范围找 10 星产品;范围清晰 → /plan-eng-review 锁架构/测试/边缘情况;视觉/UX 重 → /plan-design-review;模糊时默认 /plan-eng-review,理由是"最广的真实用途与最强留存")。PROACTIVE=false 或 Conductor 会话时不自动启动,只一行推荐停下等用户;否则按 preamble 的 D<N> 决策简讯格式发一次 AskUserQuestion(文档给出了完整的示范简讯,含 ELI10、Stakes、Completeness 分、每个选项的 ✅/❌ 与 Net 行)。用户在 A/B/C 上选择时记 handoff 遥测(--event-type handoff --outcome accepted,D 则 declined)并通过 Skill 工具调用所选技能——它会自动发现 ~/.gstack/projects/ 下的设计文档,在其 pre-review 系统审计中读取。

十二、AskUserQuestion 决策简讯格式:preamble 中的核心行为契约

office-hours 几乎每个分岔都靠 AskUserQuestion 驱动,preamble 因此定义了一套强制的"决策简讯"格式(SKILL.md#L374-L497),这是理解该技能交互质量的关键:

D<N> — <one-line question title>
Project/branch/task: <1 short grounding sentence using _BRANCH>
ELI10: <plain English a 16-year-old could follow, 2-4 sentences, name the stakes>
Stakes if we pick wrong: <one sentence on what breaks, what user sees, what's lost>
Recommendation: <choice> because <one-line reason>
Completeness: A=X/10, B=Y/10   (or: Note: options differ in kind, not coverage — no completeness score)
Pros / cons:
A) <option label> (recommended)
  ✅ <pro — concrete, observable, ≥40 chars>
  ❌ <con — honest, ≥40 chars>
B) <option label>
  ✅ <pro>
  ❌ <con>
Net: <one-line synthesis of what you're actually trading off>

要点:D 编号从 D1 递增(模型级指令,不是运行时计数器);ELI10 与 Recommendation 永远在场(recommended) 标签只挂在一个选项上(/plan-tune 的 AUTO_DECIDE 依赖它,两个 (recommended) 会导致 hook 拒绝自动决策);Completeness 只在选项覆盖度不同时分值(10=完整、7=快乐路径、3=捷径),选项属于不同"种类"时写 kind-note 不硬打分;涉及工作量的选项要双刻度标注(human: ~2 days / CC: ~15 min),让 AI 压缩在决策时可见;5 个以上选项禁止丢弃或合并——要么批成 ≤4 的组、要么拆成逐选项链(D<N>.k 头、四桶 A Include / B Defer / C Cut / D Hold,链尾 D<N>.final 验证组合、D<N>.revise-<k> 单点修订;N>6 先开 D<N>.0 元问题),拆分链的 question_id 形如 <skill>-split-<option-slug>,运行时检查器拒绝对其 never-ask,"用户的选项集合是神圣的"。工具不可用/报错时的降级路径也成体系:Conductor 会话默认走散文形式(而非工具);interactive 降级为"散文三要素"(问题 ELI10、每选项 Completeness、Recommendation + (recommended),然后 STOP 等打字回答);headless 直接 BLOCKED。单向/破坏性确认在散文里要更强的门禁——要求显式输入选项字母,模糊回复一律重新问。

问题调优(Question Tuning,SKILL.md#L759-L781)则把可复用偏好接上:question_id 取自 scripts/question-registry.ts{skill}-{slug} 约定。该注册表中 office-hours 登记了 6 个 id(question-registry.ts#L211-L262):office-hours-mode-goaloffice-hours-premise-confirmoffice-hours-cross-model-runoffice-hours-landscape-privacy-gateoffice-hours-approach-chooseoffice-hours-design-doc-approve——与技能里的六个关键决策点一一对应。每个问题内嵌 <gstack-qid:{question_id}> 标记供 hook 确定性识别(缺失则 PreToolUse hook 只做观察、永不自动决策);回答后 gstack-question-log 落日志,双向问题可接受 tune: never-ask / tune: always-ask 内联调优,写入 gstack-question-preference(退出码 2 = 拒绝非用户来源,防画像投毒)。

十三、下游消费:设计文档如何被"自动发现"

office-hours 的产物不是终点。scripts/resolvers/design-doc-discovery.ts{{DESIGN_DOC_DISCOVERY}} 片段的唯一事实来源,被 plan-ceo-review、plan-eng-review、plan-devex-review 与 review 的前置技能复检共用,避免各持一份漂移拷贝。其发现优先级(L30-L45):先取 ~/.gstack/projects/$SLUG/*-$BRANCH-design-*.md 中最新者,回退到项目级 *-design-*.md;若仓库本地文档(DESIGN.mddocs/designs/*.md)存在且至少和新的一样新鲜-nt 比较),则仓库副本胜出——因为 office-hours 双写的 docs/designs/ 提交版是队友看到的版本,但"过期的旧仓库文档永远不能遮蔽更新的私有会话"。这解释了 Phase 5 为什么要双写:私有副本服务记忆与跨会话发现,仓库副本服务团队可见性与评审管道。

十四、测试如何验证这个技能

仓库为该技能配备了一组 E2E 测试,核心是 test/skill-e2e-office-hours.test.ts。它的思路值得注意:office-hours 的"对不对"不是文本断言能判的,而是语气姿态(mode-posture)问题。测试把 office-hours/SKILL.md 复制进临时 git 仓库,喂入 fixture(如 test/fixtures/mode-posture/forcing-pitch.md 的创始人 pitch),要求 Agent 假设 Q1/Q2 已答、直接写 Q3 的强制追问原文到 q3.md,然后由 LLM judge 按两个轴打分——axis_a(stacking_preserved:压力是否被压缩成单句提问)与 axis_b(domain_matched_consequence:后果是否匹配领域),阈值均为 ≥4(L86-L97)。头部注释点明了测试动机:"Both cases detect whether preamble Writing Style rules have flattened the skill's distinctive posture at runtime"——即防止通用写作风格规则把技能特有的"逼迫能量"磨平。围绕同一技能还有 brain writeback、Phase 4 强制门禁、auto-mode 等相关 E2E(如 skill-e2e-office-hours-phase4.test.tsskill-e2e-office-hours-brain-writeback.test.ts 等,见 test/ 目录),从不同侧面守护"设计文档而非代码"这一核心契约。

十五、上手方式与适用前提

适用前提:Claude Code(或 gstack 支持的其他宿主)环境,按 README.md 安装 gstack(clone 到 ~/.claude/skills/gstack 后运行 ./setup),技能即可通过 /office-hours 或触发词("brainstorm this"、"is this worth building"、"help me think through")调用;preamble 中的 browse/design 二进制探测失败时,视觉线框与 mockup 环节会优雅降级(文档明确要求 fallback 而非报错中断)。

使用路径建议:描述你的想法 → 回答模式判定问题 → 经受对应模式的追问(Startup 六问按阶段路由,Builder 五问生成式)→ 可选跨模型第二意见 → 在 2-3 个强制备选方案中做显式选择 → 拿到经过最多 3 轮对抗评审的设计文档(私有副本 + 仓库 docs/designs/ 双写)→ 按推荐进入 /plan-ceo-review/plan-eng-review 继续闭环。

从源码结构看,office-hours 在 gstack 中的价值主张可以概括为三句话:它把"写代码之前最该发生的对话"做成了带 STOP 门禁、防谄媚规则与逃生舱口的确定性流程;它把每次对话的产物(设计文档、创始人信号、eureka、教训)沉淀进 ~/.gstack 的状态层,让后续会话与下游技能自动继承;它用 E2E 姿态测试把"语气不能退化"也纳入了可回归的工程资产。这正是该技能文件头部那句定位的落地——"YC office hours partner. Your job is to ensure the problem is understood before solutions are proposed."

登录后查看全文
热门项目推荐
相关项目推荐