
printing-press-retro
热门在生成 CLI 后执行复盘(retro)。识别对 Printing Press 的系统性改进点 —— 包括模板、Go 二进制文件、Skill 指令以及工作流文档 —— 从而让下一次生成的 CLI 质量更高。当存在需要修复 Printing Press 的问题时,自动创建一个包含可落地改进意见的 GitHub issue。可在任何 /printing-press 运行后使用。触发词:"retro", "retrospective", "what went wrong", "improve the press", "post-mortem", "lessons learned", "what can we improve", "file a retro", "submit findings"。
在生成 CLI 后执行复盘(retro)。识别对 Printing Press 的系统性改进点 —— 包括模板、Go 二进制文件、Skill 指令以及工作流文档 —— 从而让下一次生成的 CLI 质量更高。当存在需要修复 Printing Press 的问题时,自动创建一个包含可落地改进意见的 GitHub issue。可在任何 /printing-press 运行后使用。触发词:"retro", "retrospective", "what went wrong", "improve the press", "post-mortem", "lessons learned", "what can we improve", "file a retro", "submit findings"。
/printing-press-retro
对 Printing Press 的运行过程进行分析,找出改进 CLI 生产系统(Go 二进制文件、模板、Skill 和工作流文档)的切入点。这里的重点不是去修复刚刚打出来的那个具体 CLI,而是进行系统性改进,让下一个生成的 CLI 表现更强。
Printing Press 的目标绝非“不靠任何人工微调就生成完美无瑕的 CLI”。 这本身就是系统设定。我们期望 Agent 在生成的 CLI 基础上进行推理、针对具体 API 做定制开发、构建新功能并持续迭代。每次运行中存在一定程度的手工修改是完全正常的。
复盘(retro)的核心职责,是从这些人工修改中筛出**系统本可以真正提高下限(raise the floor)**的场景 —— 例如为 Agent 提供更好的初始代码起点、彻底规避某类问题,或是消除在下一次生成 CLI 时还会重复出现的摩擦。符合以下两种明确情况之一的,即可入选:
- 系统本可以完全避免该问题,且该模式具备普适性,能推广到多个生成的 CLI 中。 提交 issue。
- 系统本可以显著提升下限 —— 比如提供更合理的默认值、部分脚手架、或能吸收样板代码的 Helper 函数 —— 且你能举出明确证据证明其能惠及多个 CLI。 提交 issue。
除此之外的手工作业都属于正常的迭代行为,不应产生改进项。有些提案最终会落地为系统层面的修复,有些则不会。复盘的作用,就是把这两者精准过滤出来。
复盘会将通过筛查与对抗性校验(adversarial check)的改进项连同产物(artifacts)一起,在 printing-press 仓库中创建 GitHub issue,以便维护者(或 AI agent)对 Printing Press 进行修复。
术语定义
- The Printing Press:生产 CLI 的整个系统。在所有面向用户的输出(issue、复盘文档、prompt)中统一使用该名称。它包含四大子系统:
- Generator(生成器) —— 输出 Go 代码的模板(
internal/generator/) - Scorer(打分器) —— 对输出结果进行评级的工具:verify、dogfood、scorecard
- Skills —— 在生成过程中引导 Claude 的 SKILL.md 指令
- Binary(二进制) —— Go CLI 本身:命令、标志、解析器(
cmd/cli-printing-press/)
- Generator(生成器) —— 输出 Go 代码的模板(
- Printed CLI:Printing Press 针对特定 API 生成的 CLI(例如
notion-pp-cli)。关于 Printed-CLI 的修复只能帮到对应的这一个 CLI。
在讨论整体系统时请使用“the Printing Press”;在指引开发者去修复具体模块时请使用具体的子系统名称 —— “修复 scorer” 和 “修复 generator” 属于完全不同的 PR。
铁律(Cardinal rules)
- Issue 内容和复盘文档属于公开内容。在引用前务必脱敏所有真实密钥与个人可识别信息(PII)。 Manuscript(文稿)中可能包含凭据、账号标识符、真实邮箱和线上 API 响应数据 —— 这正是
references/secret-scrubbing.md会在上传产物前对其进行清洗的原因。Issue 正文会直接发布到公开的 GitHub issue 中,而复盘文档本身会被保留在 manuscript proofs 中,并可能作为 zip 包上传。 当你引用扫描器输出、dogfood 载荷、Greptile 评审评论或 API 响应体作为“证据”时,必须在粘贴之前将敏感子字符串替换为<REDACTED:<kind>>。对于关于密钥/PII 泄露的发现,这一点尤其重要:人们直觉上总想引用泄露的实际值来证明泄露确实存在 —— 但这会导致敏感信息在公开 issue 中再次泄露。Phase 5(复盘文档编写)和 Phase 6(发布前二次脱敏)会通过机械化流程强制执行此规则;而本规则是这一机械化执行背后的文字宪章。脱敏模式与替换格式请参阅references/secret-scrubbing.md中的 "Layer 0"。 - 默认原则是“不改动系统”。 Printing Press 已经相当成熟 —— 已生成 30+ 个 CLI,绝大多数模板都在各种形态下得到了充分检验。举证责任在于发现的改进点本身,而非跳过(Skip)路径。你在生成单个 CLI 过程中遇到的绝大多数问题,都是该 API 的特殊性(quirks)、迭代杂音或上游 API 的行为导致,并非生成器漏洞。只有当跨 CLI 的证据确凿,且该发现通过了 Phase 3 的对抗性校验(Step G)时,才建议对系统进行改动。
- 一份包含 3 个精准改进点的复盘,远比包含 10 个质量参差不齐改进点的复盘更有价值。 每一个提交的 issue 都会消耗维护者的精力。如果你发现自己写出了“每个发现都值得采取行动”,或者出现了零剔除、零跳过的情况,请立即暂停并重新评估 —— 这种情况正是本 Skill 旨在防止的失败模式。
- 复盘提出的改进方案必须能够帮到多个生成的 CLI。不要针对刚刚发布的这一个 CLI 提出直接修改建议,也不要提出仅对该 CLI 的特殊行为有价值的系统级修改提案 —— 那不过是穿了生成器外衣的单体 CLI 修复而已。
- 绝不上传未脱敏的产物。 所有产物在上传前必须经过密钥脱敏程序。
- 绝不修改源码目录。 Manuscript 和 library 目录均为只读。脱敏操作一律在临时副本上进行。
- 绝不跳过密钥脱敏步骤, 即使生成流水线此前已经执行过脱敏。必须保持多重防御。
- 绝不通过规避手段绕过 Printing Press 中 scorer 的 Bug。 如果评分工具做出了错误的扣分判定,修复代码必须落在评分工具本身。
环境初始化(Setup)
<!-- RETRO_SETUP_START -->
# 仅做路径相关配置 — 无需检测二进制文件。
# retro skill 只负责读取 manuscripts 并运行 gh/curl,不会调用
# cli-printing-press 二进制文件。这样可以避免那些安装了插件但未安装 Go 二进制文件的用户报错中断。
_scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
_scope_dir="$(cd "$_scope_dir" && pwd -P)"
PRESS_HOME="${PRINTING_PRESS_HOME:-$HOME/printing-press}"
PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"
PRESS_LIBRARY="$PRESS_HOME/library"
RETRO_SCRATCH_DIR="/tmp/printing-press/retro"
mkdir -p "$PRESS_MANUSCRIPTS" "$PRESS_LIBRARY" "$RETRO_SCRATCH_DIR"
# 检测是否处于 printing-press 仓库内部
IN_REPO=false
if [ -f "$_scope_dir/cmd/cli-printing-press/main.go" ]; then
IN_REPO=true
REPO_ROOT="$_scope_dir"
echo "Running from printing-press repo: $REPO_ROOT"
fi
<!-- RETRO_SETUP_END -->
防护栅栏(Guard rails)
无可复盘内容
if [ ! -d "$PRESS_MANUSCRIPTS" ] || [ -z "$(ls -A "$PRESS_MANUSCRIPTS" 2>/dev/null)" ]; then
echo "No manuscripts found. Run /printing-press first to generate a CLI."
exit 1
fi
解析目标 API
如果用户将 API 名称作为参数传入,则直接使用该名称。验证以防止路径穿越:
# 拒绝包含 /、\ 或 .. 的名称
if echo "$USER_API_NAME" | grep -qE '[/\\]|\.\.'; then
echo "Invalid API name: '$USER_API_NAME'. Names cannot contain path separators or '..'."
exit 1
fi
# 确保解析后的路径仍在 PRESS_MANUSCRIPTS 目录下
RESOLVED="$(cd "$PRESS_MANUSCRIPTS/$USER_API_NAME" 2>/dev/null && pwd -P)"
case "$RESOLVED" in
"$PRESS_MANUSCRIPTS"/*) ;; # OK
*) echo "Invalid API name: path resolves outside manuscripts directory."; exit 1 ;;
esac
如果未提供 API 名称且存在多个 API,列出它们及其最近的运行日期,并提示用户选择:
echo "Multiple APIs found in manuscripts:"
for api_dir in "$PRESS_MANUSCRIPTS"/*/; do
api_name=$(basename "$api_dir")
latest=$(ls -t "$api_dir" 2>/dev/null | head -1)
echo " - $api_name (latest run: $latest)"
done
使用 AskUserQuestion 让用户进行选择。
解析目标运行记录(Run)
如果该 API 存在多次运行记录,默认使用最新的一次。如果用户指定了 run ID,则使用指定的 ID。否则:
API_DIR="$PRESS_MANUSCRIPTS/$API_NAME"
RUN_ID=$(ls -t "$API_DIR" 2>/dev/null | head -1)
RUN_DIR="$API_DIR/$RUN_ID"
echo "Retro for: $API_NAME (run $RUN_ID)"
echo "Manuscripts: $RUN_DIR"
解析 CLI 目录
API_SLUG="$API_NAME"
CLI_NAME="${API_SLUG}-pp-cli"
CLI_DIR="$PRESS_LIBRARY/$CLI_NAME"
if [ ! -d "$CLI_DIR" ]; then
# 尝试使用不带 -pp-cli 后缀的旧版命名格式
CLI_DIR="$PRESS_LIBRARY/$API_NAME"
fi
if [ ! -d "$CLI_DIR" ]; then
echo "WARNING: CLI directory not found at $PRESS_LIBRARY/$CLI_NAME"
echo "Proceeding with manuscripts only — CLI source will not be included in artifacts."
CLI_DIR=""
fi
执行时机
最佳效果是在生成 CLI 的同一个对话上下文(完成 shipcheck 之后)中运行 —— 此时复盘可以从完整的对话历史中挖掘错误、重试、手工修改和新发现。
如果是在新的对话上下文中运行,复盘将仅基于 manuscript 证据继续进行。Phase 2 会将依赖上下文会话的发现标记为“evidence: manuscripts only”。
阶段 1:收集证据(Phase 1: Gather evidence)
读取本次运行产生的所有产物:
- Research brief(调研简报) ——
$RUN_DIR/research/*brief* - Absorb manifest(吸收清单) ——
$RUN_DIR/research/*absorb* - Shipcheck proof(发版检查证明) ——
$RUN_DIR/proofs/*shipcheck* - Build log(构建日志) ——
$RUN_DIR/proofs/*build-log*(若存在) - Live smoke log(线上冒烟测试日志) ——
$RUN_DIR/proofs/*live-smoke*(若存在) - 生成的 CLI 源码 ——
$CLI_DIR/(若可用)
同时收集 scorecard、verify 通过率和 dogfood 报告(可从 shipcheck 证明中提取;若 IN_REPO 为 true 且二进制文件可用,也可重新运行对应工具获取)。
阶段 2:挖掘会话记录(Phase 2: Mine the session)
扫描对话历史中的 6 类信号,梳理出一份候选清单(candidate list)。候选清单不是最终的发现清单 —— Phase 2.5 的初筛会对其剔除,Phase 3 还会进一步剔除质量不高的遗留项。大多数候选项最终都不会留下来。
在收集过程中,注意区分以下几类情况:
- 迭代杂音(Iteration noise) —— 长时间生成过程中的单次重试、拼写错误、正常试错。即使在候选阶段也应直接跳过,它们不可能通过初筛。
- 单 CLI 特殊性(Per-CLI quirks) —— 仅与当前 API 特性绑定的行为(独特的鉴权逻辑、未公开的 Endpoint、厂商专属的数据包格式),在其他 spec 上不会复现。可带上“looks per-CLI”标签加入候选清单 —— 大多数都会在初筛时被剔除。
- 系统性摩擦(Systemic friction) —— 有很大可能在下一次生成 CLI 时再次出现的模式(模板缺陷、需要调整的默认配置、误导了你的 Skill 指令)。这才是复盘旨在揭示的核心内容。
如果是在没有生成历史的新对话中运行: 请记录这一点,并仅依靠 manuscript 证据继续进行。重点关注 manuscript 揭示的内容 —— scorecard 缺口、verify 失败项、dogfood 问题以及 CLI 源码中显而易见的模板模式。将依赖会话上下文的发现标记为“evidence: manuscripts only”。
2a. 报错与重试
统计命令失败并重新运行、构建中断、或者 Printing Press 生成了无法编译的代码的所有情况。发生了什么报错?又是如何修复的?
2b. 代码手工修改
在迭代过程中进行手工修改是正常的 —— Agent 会对生成的 CLI 进行推理并做针对性微调。为了处理特定 CLI 的奇葩特性而进行单次修改属于标准工作流。
对于每一次手工修改,都需要发问:系统在这里本可以提高下限吗?
- 系统本可以完全避免这次修改吗? 比如默认值对绝大多数 API 都不适用、模板生成了存在 Bug 的代码、解析器遗漏了某种常见模式。如果答案是肯定的,并且你能举出证据证明多个 CLI 都有此修改需求 → 计入候选。
- 系统本可以提供更好的起始代码,让修改更小、更简单,或者在常见场景下直接免除修改吗? 即使后续仍需微调,提高下限也能在未来的多个 CLI 中产生叠加收益。如果答案是肯定的,且具备普适性 → 计入候选。
- 这是否只是预期中 Agent 针对特定 API 应该做的定制开发? 剔除。
- 这是否只是迭代杂音(拼写错误、重试、临时混淆)? 剔除。
初筛的核心问题在于,系统提升下限是否能在未来的多个 CLI 中产生叠加收益。



