superlab 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +8 -2
  2. package/README.zh-CN.md +8 -3
  3. package/lib/auto_contracts.cjs +4 -2
  4. package/lib/context.cjs +155 -13
  5. package/lib/i18n.cjs +89 -15
  6. package/lib/install.cjs +2 -0
  7. package/package-assets/claude/commands/lab-write.md +1 -1
  8. package/package-assets/claude/commands/lab.md +2 -1
  9. package/package-assets/codex/prompts/lab-write.md +1 -1
  10. package/package-assets/codex/prompts/lab.md +2 -1
  11. package/package-assets/shared/lab/.managed/scripts/validate_manuscript_delivery.py +175 -0
  12. package/package-assets/shared/lab/.managed/templates/artifact-status.md +28 -0
  13. package/package-assets/shared/lab/.managed/templates/final-report.md +0 -11
  14. package/package-assets/shared/lab/.managed/templates/paper-figure.tex +6 -0
  15. package/package-assets/shared/lab/.managed/templates/paper-references.bib +9 -0
  16. package/package-assets/shared/lab/.managed/templates/paper-table.tex +13 -0
  17. package/package-assets/shared/lab/context/auto-mode.md +2 -2
  18. package/package-assets/shared/lab/context/session-brief.md +1 -1
  19. package/package-assets/shared/lab/context/state.md +19 -13
  20. package/package-assets/shared/lab/context/workflow-state.md +19 -0
  21. package/package-assets/shared/lab/system/core.md +4 -2
  22. package/package-assets/shared/skills/lab/SKILL.md +19 -14
  23. package/package-assets/shared/skills/lab/references/paper-writing/examples/conclusion/conservative-claim-boundary.md +27 -0
  24. package/package-assets/shared/skills/lab/references/paper-writing/examples/conclusion-examples.md +16 -0
  25. package/package-assets/shared/skills/lab/references/paper-writing/examples/experiments/figure-placeholder-and-discussion.md +44 -0
  26. package/package-assets/shared/skills/lab/references/paper-writing/examples/experiments/main-results-and-ablation-latex.md +83 -0
  27. package/package-assets/shared/skills/lab/references/paper-writing/examples/experiments-examples.md +17 -0
  28. package/package-assets/shared/skills/lab/references/paper-writing/examples/index.md +12 -3
  29. package/package-assets/shared/skills/lab/references/paper-writing/examples/related-work/closest-prior-gap-template.md +20 -0
  30. package/package-assets/shared/skills/lab/references/paper-writing/examples/related-work/topic-comparison-template.md +24 -0
  31. package/package-assets/shared/skills/lab/references/paper-writing/examples/related-work-examples.md +17 -0
  32. package/package-assets/shared/skills/lab/references/paper-writing-integration.md +19 -10
  33. package/package-assets/shared/skills/lab/stages/report.md +5 -2
  34. package/package-assets/shared/skills/lab/stages/write.md +34 -1
  35. package/package.json +1 -1
package/README.md CHANGED
@@ -180,7 +180,7 @@ superlab auto stop
180
180
 
181
181
  - `run` and `iterate` must change persistent outputs under `results_root`
182
182
  - `review` must update canonical review context
183
- - `report` must write `<deliverables_root>/report.md` and `<deliverables_root>/main-tables.md`
183
+ - `report` must write `<deliverables_root>/report.md`, `<deliverables_root>/main-tables.md`, and `<deliverables_root>/artifact-status.md`
184
184
  - `write` must produce LaTeX output under `<deliverables_root>/paper/`
185
185
  - a successful promotion must write back into `.lab/context/data-decisions.md`, `.lab/context/decisions.md`, `.lab/context/state.md`, and `.lab/context/session-brief.md`
186
186
  - every run must end with `.lab/context/auto-outcome.md`, including why it stopped, whether the terminal goal was reached, and which artifact is the final outcome
@@ -255,7 +255,7 @@ Stages should follow that file rather than guess language locally.
255
255
  - Python 3.10+
256
256
  - Git
257
257
 
258
- `/lab:write` ships with vendored paper-writing references and the upstream example bank for `abstract`, `introduction`, and `method` under the installed `lab` skill, so it does not depend on an extra runtime skill installation.
258
+ `/lab:write` ships with vendored paper-writing references, the upstream example bank for `abstract`, `introduction`, and `method`, and local manuscript-delivery examples for `related work`, `experiments`, and `conclusion` under the installed `lab` skill, so it does not depend on an extra runtime skill installation.
259
259
 
260
260
  ## Command Set
261
261
 
@@ -309,8 +309,12 @@ See the source command docs in [commands/codex/lab.md](/Users/zhouhao119/coding/
309
309
 
310
310
  - `docs/research/report.md`
311
311
  - `docs/research/main-tables.md`
312
+ - `docs/research/artifact-status.md`
312
313
  - `docs/research/paper/main.tex`
314
+ - `docs/research/paper/references.bib`
313
315
  - `docs/research/paper/sections/*.tex`
316
+ - `docs/research/paper/tables/*.tex`
317
+ - `docs/research/paper/figures/*.tex`
314
318
 
315
319
  Internal writing-control artifacts stay under:
316
320
 
@@ -322,6 +326,7 @@ If `paper_template_root` is configured, `/lab:write` should inspect that templat
322
326
  If no template is configured, the first manuscript-writing round should ask once whether to continue with the managed default LaTeX scaffold or attach a template directory first.
323
327
  If the user approves the default scaffold, persist that choice in `.lab/config/workflow.json` and stop asking on ordinary rounds.
324
328
  At the final export or final-draft boundary, if the project is still on the default scaffold and no attached template exists, ask one final reminder question before finalizing.
329
+ For final-draft or export rounds, `/lab:write` should materialize real LaTeX tables, figure placeholders with figure intent, a non-empty `references.bib`, and pass `.lab/.managed/scripts/validate_manuscript_delivery.py --paper-dir <deliverables_root>/paper` before stopping.
325
330
 
326
331
  `/lab` treats `.lab/` as the workflow-control layer only. Durable outputs should use natural project roots:
327
332
 
@@ -335,6 +340,7 @@ At the final export or final-draft boundary, if the project is still on the defa
335
340
  - `scripts/eval_report.py` normalizes metrics into a comparable summary.
336
341
  - `scripts/summarize_iterations.py` rolls multiple iteration summaries into one file.
337
342
  - `scripts/validate_results.py` verifies required report fields before publication.
343
+ - `scripts/validate_manuscript_delivery.py` verifies that the paper deliverable contains basic manuscript-ready tables, figures, citations, and bibliography.
338
344
 
339
345
  ## Packaging
340
346
 
package/README.zh-CN.md CHANGED
@@ -178,7 +178,7 @@ superlab auto stop
178
178
 
179
179
  - `run` 和 `iterate` 必须更新 `results_root` 下的持久输出
180
180
  - `review` 必须更新规范的审查上下文
181
- - `report` 必须写出 `<deliverables_root>/report.md` 和 `<deliverables_root>/main-tables.md`
181
+ - `report` 必须写出 `<deliverables_root>/report.md`、`<deliverables_root>/main-tables.md` 和 `<deliverables_root>/artifact-status.md`
182
182
  - `write` 必须写出 `<deliverables_root>/paper/` 下的 LaTeX 论文产物
183
183
  - promotion 成功后必须写回 `.lab/context/data-decisions.md`、`.lab/context/decisions.md`、`.lab/context/state.md` 和 `.lab/context/session-brief.md`
184
184
  - 每次运行都必须写出 `.lab/context/auto-outcome.md`,记录为什么停止、是否达到终止目标,以及哪一个工件是最终结果
@@ -253,7 +253,7 @@ superlab init --lang en
253
253
  - Python 3.10+
254
254
  - Git
255
255
 
256
- `/lab:write` 自带 vendored 的 paper-writing 章节参考,以及 `abstract`、`introduction`、`method` 对应的 upstream example bank,不再依赖额外安装一个运行时写作 skill。
256
+ `/lab:write` 自带 vendored 的 paper-writing 章节参考、`abstract`、`introduction`、`method` 对应的 upstream example bank,以及为 `related work`、`experiments`、`conclusion` 补齐的 manuscript-delivery examples,不再依赖额外安装一个运行时写作 skill。
257
257
 
258
258
  ## 命令集合
259
259
 
@@ -294,8 +294,12 @@ Codex 和 Claude 的命令入口不一样:
294
294
 
295
295
  - `docs/research/report.md`
296
296
  - `docs/research/main-tables.md`
297
+ - `docs/research/artifact-status.md`
297
298
  - `docs/research/paper/main.tex`
299
+ - `docs/research/paper/references.bib`
298
300
  - `docs/research/paper/sections/*.tex`
301
+ - `docs/research/paper/tables/*.tex`
302
+ - `docs/research/paper/figures/*.tex`
299
303
 
300
304
  内部写作控制工件放在:
301
305
 
@@ -307,6 +311,7 @@ Codex 和 Claude 的命令入口不一样:
307
311
  如果没有配置模板,第一次进入论文 `.tex` 写作时应先追问一次:继续使用内置默认 LaTeX scaffold,还是先接入模板目录。
308
312
  如果用户确认先用默认 scaffold,就把这个决定持久化到 `.lab/config/workflow.json`,后续普通轮次不再重复追问。
309
313
  但在最终导出或最终定稿节点,如果项目仍在使用默认 scaffold 且没有接入模板,应再提醒一次,给用户最后切换模板的机会。
314
+ 在最终定稿或导出轮次里,`/lab:write` 还应物化真正的 LaTeX 表格、带图意图的 figure placeholders、非空的 `references.bib`,并在停止前通过 `.lab/.managed/scripts/validate_manuscript_delivery.py --paper-dir <deliverables_root>/paper`。
310
315
 
311
316
  `/lab` 把 `.lab/` 视为工作流控制层,不是正式结果目录。持久输出应按自然根目录放置:
312
317
 
@@ -320,7 +325,7 @@ Codex 和 Claude 的命令入口不一样:
320
325
  - `package-assets/` 是 npm 安装时真正分发到目标项目的命令与 skill 资产。
321
326
  - `skills/lab/` 是仓库开发时使用的共享 workflow 定义。
322
327
  - `templates/` 是研究工件模板。
323
- - `scripts/` 是运行登记、评估汇总和结果校验脚本。
328
+ - `scripts/` 是运行登记、评估汇总和结果校验脚本,其中也包括论文交付校验器。
324
329
  - `results/` 和 `figures/` 是默认的自然结果目录。
325
330
  - `tests/` 是脚本与安装器测试。
326
331
  - `examples/` 是最小端到端示例。
@@ -34,6 +34,7 @@ const FROZEN_CORE_ALIASES = {
34
34
  const REVIEW_CONTEXT_FILES = [
35
35
  path.join(".lab", "context", "decisions.md"),
36
36
  path.join(".lab", "context", "state.md"),
37
+ path.join(".lab", "context", "workflow-state.md"),
37
38
  path.join(".lab", "context", "open-questions.md"),
38
39
  path.join(".lab", "context", "evidence-index.md"),
39
40
  ];
@@ -288,6 +289,7 @@ function stageContractSnapshot(targetDir, stage) {
288
289
  report: [
289
290
  path.join(deliverablesRoot, "report.md"),
290
291
  path.join(deliverablesRoot, "main-tables.md"),
292
+ path.join(deliverablesRoot, "artifact-status.md"),
291
293
  ],
292
294
  write: [
293
295
  path.join(deliverablesRoot, "paper", "main.tex"),
@@ -318,7 +320,7 @@ function verifyStageContract({ stage, snapshot }) {
318
320
  if (stage === "review") {
319
321
  if (changedPaths.length === 0) {
320
322
  throw new Error(
321
- "review stage did not update canonical review context (.lab/context/decisions.md, state.md, open-questions.md, or evidence-index.md)"
323
+ "review stage did not update canonical review context (.lab/context/decisions.md, state.md, workflow-state.md, open-questions.md, or evidence-index.md)"
322
324
  );
323
325
  }
324
326
  return;
@@ -327,7 +329,7 @@ function verifyStageContract({ stage, snapshot }) {
327
329
  if (stage === "report") {
328
330
  const missing = Array.from(snapshot.keys()).filter((absolutePath) => !changedPaths.includes(absolutePath));
329
331
  if (missing.length > 0) {
330
- throw new Error("report stage did not produce the deliverable report.md and main-tables.md under deliverables_root");
332
+ throw new Error("report stage did not produce report.md, main-tables.md, and artifact-status.md under deliverables_root");
331
333
  }
332
334
  return;
333
335
  }
package/lib/context.cjs CHANGED
@@ -206,6 +206,30 @@ function isMeaningful(value) {
206
206
  return !PLACEHOLDER_VALUES.has((value || "").trim().toLowerCase());
207
207
  }
208
208
 
209
+ function hasWorkflowStateShape(text) {
210
+ if (!text) {
211
+ return false;
212
+ }
213
+ return [
214
+ extractValue(text, ["Active stage", "当前阶段", "Stage"]),
215
+ extractValue(text, ["Current objective", "当前目标"]),
216
+ extractValue(text, ["Next required output", "Next required artifact", "下一项必要输出"]),
217
+ extractValue(text, ["Immediate action", "立即要做的动作"]),
218
+ ].some((value) => isMeaningful(value));
219
+ }
220
+
221
+ function readWorkflowStateContext(targetDir) {
222
+ const workflowState = readFileIfExists(contextFile(targetDir, "workflow-state.md"));
223
+ if (hasWorkflowStateShape(workflowState)) {
224
+ return workflowState;
225
+ }
226
+ const legacyState = readFileIfExists(contextFile(targetDir, "state.md"));
227
+ if (hasWorkflowStateShape(legacyState)) {
228
+ return legacyState;
229
+ }
230
+ return workflowState || legacyState;
231
+ }
232
+
209
233
  function readWorkflowConfig(targetDir) {
210
234
  const configPath = path.join(targetDir, ".lab", "config", "workflow.json");
211
235
  if (!fs.existsSync(configPath)) {
@@ -232,6 +256,7 @@ function getCollaboratorDeliverablePaths(targetDir) {
232
256
  deliverablesRoot,
233
257
  reportPath: path.join(deliverablesRoot, "report.md"),
234
258
  mainTablesPath: path.join(deliverablesRoot, "main-tables.md"),
259
+ artifactStatusPath: path.join(deliverablesRoot, "artifact-status.md"),
235
260
  };
236
261
  }
237
262
 
@@ -610,11 +635,16 @@ function labelValue(text, englishLabels, chineseLabels = []) {
610
635
 
611
636
  function collectHydrationSources(targetDir) {
612
637
  const { reportPath, mainTablesPath } = getCollaboratorDeliverablePaths(targetDir);
638
+ const workflowStatePath = hasWorkflowStateShape(readFileIfExists(contextFile(targetDir, "workflow-state.md")))
639
+ ? ".lab/context/workflow-state.md"
640
+ : hasWorkflowStateShape(readFileIfExists(contextFile(targetDir, "state.md")))
641
+ ? ".lab/context/state.md"
642
+ : "";
613
643
  return [
614
644
  fs.existsSync(reportPath) ? path.relative(targetDir, reportPath) : "",
615
645
  fs.existsSync(mainTablesPath) ? path.relative(targetDir, mainTablesPath) : "",
616
646
  readFileIfExists(contextFile(targetDir, "data-decisions.md")) ? ".lab/context/data-decisions.md" : "",
617
- readFileIfExists(contextFile(targetDir, "state.md")) ? ".lab/context/state.md" : "",
647
+ workflowStatePath,
618
648
  readFileIfExists(contextFile(targetDir, "evidence-index.md")) ? ".lab/context/evidence-index.md" : "",
619
649
  ].filter(Boolean);
620
650
  }
@@ -626,7 +656,7 @@ function hydrateMissionContext(targetDir) {
626
656
 
627
657
  const lang = readWorkflowLanguage(targetDir);
628
658
  const missionText = readFileIfExists(contextFile(targetDir, "mission.md"));
629
- const stateText = readFileIfExists(contextFile(targetDir, "state.md"));
659
+ const workflowStateText = readWorkflowStateContext(targetDir);
630
660
  const evidenceText = readFileIfExists(contextFile(targetDir, "evidence-index.md"));
631
661
  const dataDecisions = readFileIfExists(contextFile(targetDir, "data-decisions.md"));
632
662
  const reportText = readFileIfExists(getCollaboratorDeliverablePaths(targetDir).reportPath);
@@ -637,7 +667,7 @@ function hydrateMissionContext(targetDir) {
637
667
  problem: mergePreferred(
638
668
  extractValue(missionText, ["One-sentence problem", "一句话问题"]),
639
669
  extractReportValue(reportText, "problem"),
640
- extractValue(stateText, ["Current objective", "当前目标", "Current objective"])
670
+ extractValue(workflowStateText, ["Current objective", "当前目标", "Current objective"])
641
671
  ),
642
672
  whyItMatters: mergePreferred(
643
673
  extractValue(missionText, ["Why it matters", "为什么重要"]),
@@ -680,7 +710,7 @@ function hydrateMissionContext(targetDir) {
680
710
  currentOwner: extractValue(missionText, ["Current owner or session", "当前 owner 或会话"]),
681
711
  latestStage: mergePreferred(
682
712
  extractValue(missionText, ["Latest stage to update this mission", "最近一次允许更新 mission 的阶段"]),
683
- extractValue(stateText, ["Active stage", "当前阶段", "Stage"])
713
+ extractValue(workflowStateText, ["Active stage", "当前阶段", "Stage"])
684
714
  ),
685
715
  };
686
716
 
@@ -935,6 +965,110 @@ function hydrateCanonicalContext(targetDir) {
935
965
  };
936
966
  }
937
967
 
968
+ function renderResearchState(lang, data) {
969
+ if (lang === "zh") {
970
+ return `# 研究状态
971
+
972
+ ## 已批准方向
973
+
974
+ - One-sentence problem: ${data.problem || "待补充"}
975
+ - Approved direction: ${data.direction || "待补充"}
976
+ - Strongest supported claim: ${data.claim || "待补充"}
977
+
978
+ ## 证据边界
979
+
980
+ - What the current evidence really supports: ${data.reportModeReason || data.direction || "待补充"}
981
+ - What is still outside the boundary: ${data.question || "待补充"}
982
+ - Biggest research risk: ${data.risk || "待补充"}
983
+
984
+ ## 当前研究主线
985
+
986
+ - Current research focus: ${data.immediateAction || data.direction || "待补充"}
987
+ - Primary metric: ${data.evalPrimaryMetrics || data.threshold || "待补充"}
988
+ - Dataset or benchmark scope: ${data.datasetPackage || data.benchmarkRole || "待补充"}
989
+
990
+ ## 当前研究约束
991
+
992
+ - Hard constraints: ${data.boundary || "待补充"}
993
+ - Claim boundary: ${data.evalClaimBoundary || "待补充"}
994
+ - Conditions that require reopening the direction: ${data.humanDecision || "待补充"}
995
+ `;
996
+ }
997
+
998
+ return `# Research State
999
+
1000
+ ## Approved Direction
1001
+
1002
+ - One-sentence problem: ${data.problem || "TBD"}
1003
+ - Approved direction: ${data.direction || "TBD"}
1004
+ - Strongest supported claim: ${data.claim || "TBD"}
1005
+
1006
+ ## Evidence Boundary
1007
+
1008
+ - What the current evidence really supports: ${data.reportModeReason || data.direction || "TBD"}
1009
+ - What is still outside the boundary: ${data.question || "TBD"}
1010
+ - Biggest research risk: ${data.risk || "TBD"}
1011
+
1012
+ ## Active Research Track
1013
+
1014
+ - Current research focus: ${data.immediateAction || data.direction || "TBD"}
1015
+ - Primary metric: ${data.evalPrimaryMetrics || data.threshold || "TBD"}
1016
+ - Dataset or benchmark scope: ${data.datasetPackage || data.benchmarkRole || "TBD"}
1017
+
1018
+ ## Current Research Constraints
1019
+
1020
+ - Hard constraints: ${data.boundary || "TBD"}
1021
+ - Claim boundary: ${data.evalClaimBoundary || "TBD"}
1022
+ - Conditions that require reopening the direction: ${data.humanDecision || "TBD"}
1023
+ `;
1024
+ }
1025
+
1026
+ function renderWorkflowState(lang, data) {
1027
+ if (lang === "zh") {
1028
+ return `# 工作流状态
1029
+
1030
+ ## 当前阶段
1031
+
1032
+ - Active stage: ${data.stage || "待补充"}
1033
+ - 当前目标:${data.workflowObjective || "待补充"}
1034
+ - 下一项必要输出:${data.nextArtifact || "待补充"}
1035
+
1036
+ ## 最近更新
1037
+
1038
+ - 最近完成动作:${data.latestAction || "待补充"}
1039
+ - 最新工件路径:${data.latestArtifactPath || "待补充"}
1040
+ - 最新 run 或 report id:${data.latestRunOrReportId || "待补充"}
1041
+
1042
+ ## 下一步
1043
+
1044
+ - 立即要做的动作:${data.immediateAction || "待补充"}
1045
+ - 当前阻塞:${data.blocker || "待补充"}
1046
+ - 是否需要人工决策:${data.humanDecision || "待补充"}
1047
+ `;
1048
+ }
1049
+
1050
+ return `# Workflow State
1051
+
1052
+ ## Current Stage
1053
+
1054
+ - Active stage: ${data.stage || "TBD"}
1055
+ - Current objective: ${data.workflowObjective || "TBD"}
1056
+ - Next required output: ${data.nextArtifact || "TBD"}
1057
+
1058
+ ## Latest Update
1059
+
1060
+ - Last completed action: ${data.latestAction || "TBD"}
1061
+ - Latest artifact path: ${data.latestArtifactPath || "TBD"}
1062
+ - Latest run or report id: ${data.latestRunOrReportId || "TBD"}
1063
+
1064
+ ## Next Step
1065
+
1066
+ - Immediate next action: ${data.immediateAction || "TBD"}
1067
+ - Blocking issue: ${data.blocker || "TBD"}
1068
+ - Human decision needed: ${data.humanDecision || "TBD"}
1069
+ `;
1070
+ }
1071
+
938
1072
  function renderSummary(lang, data) {
939
1073
  if (lang === "zh") {
940
1074
  return `# 研究摘要
@@ -1220,7 +1354,7 @@ ${data.problem || "待补充"}
1220
1354
  ## 先读这些文件
1221
1355
 
1222
1356
  1. \`.lab/context/mission.md\`
1223
- 2. \`.lab/context/state.md\`
1357
+ 2. \`.lab/context/workflow-state.md\`
1224
1358
  3. \`.lab/context/evidence-index.md\`
1225
1359
 
1226
1360
  ## 不要静默修改
@@ -1309,7 +1443,7 @@ ${data.problem || "TBD"}
1309
1443
  ## Read First
1310
1444
 
1311
1445
  1. \`.lab/context/mission.md\`
1312
- 2. \`.lab/context/state.md\`
1446
+ 2. \`.lab/context/workflow-state.md\`
1313
1447
  3. \`.lab/context/evidence-index.md\`
1314
1448
 
1315
1449
  ## Do Not Change Silently
@@ -1322,7 +1456,7 @@ ${data.problem || "TBD"}
1322
1456
  function buildContextSnapshot(targetDir) {
1323
1457
  const reportStatus = getCollaboratorReportStatus(targetDir);
1324
1458
  const mission = readFileIfExists(contextFile(targetDir, "mission.md"));
1325
- const state = readFileIfExists(contextFile(targetDir, "state.md"));
1459
+ const workflowState = readWorkflowStateContext(targetDir);
1326
1460
  const evidence = readFileIfExists(contextFile(targetDir, "evidence-index.md"));
1327
1461
  const questions = readFileIfExists(contextFile(targetDir, "open-questions.md"));
1328
1462
  const dataDecisions = readFileIfExists(contextFile(targetDir, "data-decisions.md"));
@@ -1390,16 +1524,22 @@ function buildContextSnapshot(targetDir) {
1390
1524
  return {
1391
1525
  problem: extractValue(mission, ["One-sentence problem", "一句话问题"]),
1392
1526
  direction: extractValue(mission, ["Approved direction", "已批准方向"]),
1393
- stage: extractValue(state, ["Active stage", "当前阶段", "Stage"]),
1394
- nextArtifact: extractValue(state, ["Next required artifact", "下一项必要输出"]),
1395
- immediateAction: extractValue(state, ["Immediate action", "立即要做的动作"]),
1396
- blocker: extractValue(state, ["Current blocker", "当前阻塞"]),
1397
- humanDecision: extractValue(state, ["Human decision needed", "是否需要人工决策"]),
1527
+ stage: extractValue(workflowState, ["Active stage", "当前阶段", "Stage"]),
1528
+ workflowObjective: extractValue(workflowState, ["Current objective", "当前目标"]),
1529
+ nextArtifact: extractValue(workflowState, ["Next required artifact", "下一项必要输出"]),
1530
+ latestAction: extractValue(workflowState, ["Latest completed action", "Last completed action", "最近完成动作"]),
1531
+ latestArtifactPath: extractValue(workflowState, ["Latest artifact path", "最新工件路径"]),
1532
+ latestRunOrReportId: extractValue(workflowState, ["Latest run or report id", "最新 run 或 report id"]),
1533
+ immediateAction: extractValue(workflowState, ["Immediate action", "立即要做的动作"]),
1534
+ blocker: extractValue(workflowState, ["Current blocker", "Blocking issue", "当前阻塞"]),
1535
+ humanDecision: extractValue(workflowState, ["Human decision needed", "是否需要人工决策"]),
1398
1536
  threshold: extractValue(mission, ["Success threshold", "成功阈值"]),
1399
1537
  boundary: extractValue(mission, ["Hard constraints", "硬约束"]),
1400
1538
  claim: extractClaim(evidence),
1401
1539
  question: extractOpenQuestion(questions),
1402
- risk: extractValue(questions, ["Why it matters", "为什么重要"]) || extractValue(state, ["Current blocker", "当前阻塞"]),
1540
+ risk:
1541
+ extractValue(questions, ["Why it matters", "为什么重要"]) ||
1542
+ extractValue(workflowState, ["Current blocker", "Blocking issue", "当前阻塞"]),
1403
1543
  datasetPackage:
1404
1544
  extractValue(dataDecisions, ["Approved dataset package", "已批准数据集包"]) ||
1405
1545
  extractValue(dataDecisions, ["Approved datasets", "已批准数据集"]),
@@ -1583,6 +1723,8 @@ function refreshContext({ targetDir }) {
1583
1723
  hydrateCanonicalContext(targetDir);
1584
1724
  const lang = readWorkflowLanguage(targetDir);
1585
1725
  const snapshot = buildContextSnapshot(targetDir);
1726
+ writeContextFile(targetDir, "state.md", renderResearchState(lang, snapshot));
1727
+ writeContextFile(targetDir, "workflow-state.md", renderWorkflowState(lang, snapshot));
1586
1728
  writeContextFile(targetDir, "summary.md", renderSummary(lang, snapshot));
1587
1729
  writeContextFile(targetDir, "next-action.md", renderNextAction(lang, snapshot));
1588
1730
  writeContextFile(targetDir, "session-brief.md", renderSessionBrief(lang, snapshot));
package/lib/i18n.cjs CHANGED
@@ -55,12 +55,12 @@ const ZH_CONTENT = {
55
55
  [path.join(".codex", "prompts", "lab-report.md")]: codexPrompt(
56
56
  "基于验证后的迭代工件生成最终报告",
57
57
  "report context",
58
- "使用已安装的 `lab` 技能:`.codex/skills/lab/SKILL.md`。\n\n立刻针对用户当前给出的参数执行 `/lab:report`,不要只推荐别的 `/lab` 阶段。只有在缺少阻塞性前提时,才明确指出缺什么,并且一次最多追问一个问题。\n\n本命令运行 `/lab:report` 阶段。它必须生成给用户直接阅读的最终实验报告和受管的 `main-tables.md`,明确写出主指标、次级指标和必要终局证据,并用白话解释这些指标分别衡量什么、哪些只是健康度或支持性指标、以及每张主表到底证明了什么和没证明什么。"
58
+ "使用已安装的 `lab` 技能:`.codex/skills/lab/SKILL.md`。\n\n立刻针对用户当前给出的参数执行 `/lab:report`,不要只推荐别的 `/lab` 阶段。只有在缺少阻塞性前提时,才明确指出缺什么,并且一次最多追问一个问题。\n\n本命令运行 `/lab:report` 阶段。它必须生成给用户直接阅读的最终实验报告、受管的 `main-tables.md`,以及单独的内部 `artifact-status.md`。主报告要明确写出主指标、次级指标和必要终局证据,并用白话解释这些指标分别衡量什么、哪些只是健康度或支持性指标、以及每张主表到底证明了什么和没证明什么。"
59
59
  ),
60
60
  [path.join(".codex", "prompts", "lab-write.md")]: codexPrompt(
61
61
  "把验证过的研究工件转成论文 section,并按小步方式修订",
62
62
  "section or writing target",
63
- "使用已安装的 `lab` 技能:`.codex/skills/lab/SKILL.md`。\n\n立刻针对用户当前给出的参数执行 `/lab:write`,不要只推荐别的 `/lab` 阶段。只有在缺少阻塞性前提时,才明确指出缺什么,并且一次最多追问一个问题。\n\n本命令运行 `/lab:write` 阶段。它必须先有来自 `/lab:framing` 的已批准 framing artifact,再读取 `.codex/skills/lab/references/paper-writing/` 下与当前 section 对应的参考文件;如果当前是 `abstract`、`introduction` `method`,还必须继续读取 `.codex/skills/lab/references/paper-writing/examples/index.md`、对应的 examples index,以及 1-2 个具体 example 文件。然后结合 `paper-review.md` 与 `does-my-writing-flow-source.md`,先写 mini-outline,再只修改一个 section。第一次进入会产出论文 `.tex` 的路径时,如果 `paper_template_root` 为空,必须先问一次:继续使用默认 LaTeX scaffold,还是先接入模板目录。"
63
+ "使用已安装的 `lab` 技能:`.codex/skills/lab/SKILL.md`。\n\n立刻针对用户当前给出的参数执行 `/lab:write`,不要只推荐别的 `/lab` 阶段。只有在缺少阻塞性前提时,才明确指出缺什么,并且一次最多追问一个问题。\n\n本命令运行 `/lab:write` 阶段。它必须先有来自 `/lab:framing` 的已批准 framing artifact,再读取 `.codex/skills/lab/references/paper-writing/` 下与当前 section 对应的参考文件;如果当前 section bundled example bank,还必须继续读取 `.codex/skills/lab/references/paper-writing/examples/index.md`、对应的 examples index,以及 1-2 个具体 example 文件。然后结合 `paper-review.md` 与 `does-my-writing-flow-source.md`,先写 mini-outline,先规划该 section 需要的表、图和 citation,再只修改一个 section。最终定稿或导出轮次必须运行 `.lab/.managed/scripts/validate_manuscript_delivery.py --paper-dir <deliverables_root>/paper`。第一次进入会产出论文 `.tex` 的路径时,如果 `paper_template_root` 为空,必须先问一次:继续使用默认 LaTeX scaffold,还是先接入模板目录。"
64
64
  ),
65
65
  [path.join(".claude", "commands", "lab-idea.md")]: claudeCommand(
66
66
  "lab-idea",
@@ -102,7 +102,7 @@ const ZH_CONTENT = {
102
102
  "lab-report",
103
103
  "基于验证后的迭代工件生成最终报告",
104
104
  "report context",
105
- "使用已安装的 `lab` 技能:`.claude/skills/lab/SKILL.md`。\n\n立刻针对用户当前给出的参数执行 `report` 阶段,不要只推荐别的 lab 阶段。只有在缺少阻塞性前提时,才明确指出缺什么,并且一次最多追问一个问题。\n\n本命令运行 lab workflow 的 `report` 阶段。它必须生成给用户直接阅读的最终实验报告和受管的 `main-tables.md`,明确写出主指标、次级指标和必要终局证据,并用白话解释这些指标分别衡量什么、哪些只是健康度或支持性指标、以及每张主表到底证明了什么和没证明什么。"
105
+ "使用已安装的 `lab` 技能:`.claude/skills/lab/SKILL.md`。\n\n立刻针对用户当前给出的参数执行 `report` 阶段,不要只推荐别的 lab 阶段。只有在缺少阻塞性前提时,才明确指出缺什么,并且一次最多追问一个问题。\n\n本命令运行 lab workflow 的 `report` 阶段。它必须生成给用户直接阅读的最终实验报告、受管的 `main-tables.md`,以及单独的内部 `artifact-status.md`。主报告要明确写出主指标、次级指标和必要终局证据,并用白话解释这些指标分别衡量什么、哪些只是健康度或支持性指标、以及每张主表到底证明了什么和没证明什么。"
106
106
  ),
107
107
  [path.join(".claude", "commands", "lab-write.md")]: claudeCommand(
108
108
  "lab-write",
@@ -300,6 +300,7 @@ const ZH_SKILL_FILES = {
300
300
  - 实验设置
301
301
  - 已验证主结果
302
302
  - 位于 \`<deliverables_root>/main-tables.md\` 的受管主表工件
303
+ - 位于 \`<deliverables_root>/artifact-status.md\` 的内部工件状态
303
304
  - 怎么看主表的阅读指引
304
305
  - 消融
305
306
  - 失败尝试
@@ -311,6 +312,7 @@ const ZH_SKILL_FILES = {
311
312
 
312
313
  - \`.lab/context/mission.md\`
313
314
  - \`.lab/context/state.md\`
315
+ - \`.lab/context/workflow-state.md\`
314
316
  - \`.lab/context/decisions.md\`
315
317
  - \`.lab/context/evidence-index.md\`
316
318
  - \`.lab/context/eval-protocol.md\`
@@ -320,6 +322,7 @@ const ZH_SKILL_FILES = {
320
322
  - \`.lab/context/mission.md\`
321
323
  - \`.lab/context/eval-protocol.md\`
322
324
  - \`.lab/context/state.md\`
325
+ - \`.lab/context/workflow-state.md\`
323
326
  - \`.lab/context/evidence-index.md\`
324
327
 
325
328
  ## 证据规则
@@ -337,14 +340,14 @@ const ZH_SKILL_FILES = {
337
340
  - 方法概述必须用协作者能读懂的话说明:我们的方法大致怎么做、相对 closest prior work 或 strongest baseline 改了什么、这些 prior 方法各自做了什么,以及它们为什么在当前 claim 下仍然不够。
338
341
  - 只保留少量最关键的 prior work/baseline 锚点;每个锚点都要用一句话交代它做了什么和它的局限。
339
342
  - 在“背景来源”“方法与基线来源”“指标来源”里,每个锚点都必须包含:引用、它做了什么或衡量什么、以及至少一个局限或 caveat。
340
- - 内部 provenance 只能放到 \`工件状态\` 或 \`.lab/context/evidence-index.md\`,不能塞进来源章节。
343
+ - 内部 provenance 只能放到 \`<deliverables_root>/artifact-status.md\` 或 \`.lab/context/evidence-index.md\`,不能塞进来源章节。
341
344
  - 在起草报告前,先检查 \`.lab/context/mission.md\` 和 \`.lab/context/eval-protocol.md\` 是否仍是模板空壳。
342
345
  - 如果 canonical context 还是空壳,要先根据 frozen result artifacts、data-decisions、evidence-index 和已批准上下文回填“最小可信版本”,再写报告。
343
346
  - 如果回填后仍缺少协作者可读所需的关键字段,就必须把输出降级成 \`artifact-anchored interim report\`,不能冒充最终协作者报告。
344
347
  - 如果现有的 \`report.md\` 或 \`main-tables.md\` 缺少受管模板要求的协作者可读章节,也必须视为报告缺陷;rerun 需要补齐这些缺失块,不能直接宣称“正文无变化”或把这次 rerun 当成 no-op。
345
348
  - 报告起草或 rerun 完成后,必须运行 \`.lab/.managed/scripts/validate_collaborator_report.py --report <deliverables_root>/report.md --main-tables <deliverables_root>/main-tables.md\`。如果校验失败,就继续补正文,不能停在“只新增审计痕迹”的状态。
346
349
  - 如果报告依赖了对原始指标或原始实现的偏差,必须明确写出这个偏差。
347
- - workflow 工件状态、rerun id 或 LaTeX 骨架状态不能混进“已验证主结果”;这些内容必须单列到工件状态部分。
350
+ - workflow 工件状态、rerun id 或 LaTeX 骨架状态不能混进“已验证主结果”;这些内容必须单列到 \`<deliverables_root>/artifact-status.md\`。
348
351
  - 如果 workflow language 是中文,\`report.md\` 和 \`<deliverables_root>/main-tables.md\` 也应使用中文,除非文件路径、代码标识符或字面指标名必须保持原样。
349
352
  - 解释优先保守,不要写成营销文案。
350
353
  - 要给 \`/lab:write\` 留下清晰 handoff,尤其是 section draft 可以直接引用的证据链接。
@@ -814,11 +817,6 @@ const ZH_SKILL_FILES = {
814
817
  - 最终表现摘要:
815
818
  - 主表覆盖情况:
816
819
 
817
- ## 工件状态
818
-
819
- - 已就绪的交付物或工作流工件:
820
- - 这些工件状态为什么不是科学结论:
821
-
822
820
  ## 主要结果
823
821
 
824
822
  - 主要发现 1:
@@ -833,6 +831,36 @@ const ZH_SKILL_FILES = {
833
831
 
834
832
  - Claim:
835
833
  - 缺失支持:
834
+ `,
835
+ [path.join(".lab", ".managed", "templates", "artifact-status.md")]:
836
+ `# 工件状态
837
+
838
+ ## 交付物状态
839
+
840
+ - 协作者报告路径:
841
+ - 受管主表路径:
842
+ - 当前报告模式:
843
+ - 为什么当前状态是合理的:
844
+
845
+ ## 工作流审计
846
+
847
+ - 最近完成动作:
848
+ - 最新工件路径:
849
+ - 最新 run 或 report id:
850
+ - rerun 或校验备注:
851
+
852
+ ## 内部溯源
853
+
854
+ - 使用的冻结结果工件:
855
+ - 已刷新 canonical context:
856
+ - Evidence index 锚点:
857
+
858
+ ## 论文交接
859
+
860
+ - 已可进入 \`/lab:write\` 的 sections:
861
+ - 可引用的证据包:
862
+ - 仍需要更强支持的 claims:
863
+ - 仍未完成的 paper-finishing 项:
836
864
  `,
837
865
  [path.join(".lab", ".managed", "templates", "main-tables.md")]:
838
866
  `# 主表工件
@@ -1056,6 +1084,33 @@ const ZH_SKILL_FILES = {
1056
1084
  - 协作者可读状态:
1057
1085
  `,
1058
1086
  [path.join(".lab", "context", "state.md")]:
1087
+ `# 研究状态
1088
+
1089
+ ## 已批准方向
1090
+
1091
+ - One-sentence problem:
1092
+ - Approved direction:
1093
+ - Strongest supported claim:
1094
+
1095
+ ## 证据边界
1096
+
1097
+ - What the current evidence really supports:
1098
+ - What is still outside the boundary:
1099
+ - Biggest research risk:
1100
+
1101
+ ## 当前研究主线
1102
+
1103
+ - Current research focus:
1104
+ - Primary metric:
1105
+ - Dataset or benchmark scope:
1106
+
1107
+ ## 当前研究约束
1108
+
1109
+ - Hard constraints:
1110
+ - Claim boundary:
1111
+ - Conditions that require reopening the direction:
1112
+ `,
1113
+ [path.join(".lab", "context", "workflow-state.md")]:
1059
1114
  `# 工作流状态
1060
1115
 
1061
1116
  ## 当前阶段
@@ -1172,8 +1227,8 @@ const ZH_SKILL_FILES = {
1172
1227
 
1173
1228
  - Run stage contract: write persistent outputs under \`results_root\`.
1174
1229
  - Iterate stage contract: update persistent outputs under \`results_root\`.
1175
- - Review stage contract: update canonical review context such as \`.lab/context/decisions.md\`、\`state.md\`、\`open-questions.md\` or \`evidence-index.md\`.
1176
- - Report stage contract: write the final report to \`<deliverables_root>/report.md\`.
1230
+ - Review stage contract: update canonical review context such as \`.lab/context/decisions.md\`、\`state.md\`、\`workflow-state.md\`、\`open-questions.md\` or \`evidence-index.md\`.
1231
+ - Report stage contract: write \`<deliverables_root>/report.md\`、\`<deliverables_root>/main-tables.md\` and \`<deliverables_root>/artifact-status.md\`.
1177
1232
  - Write stage contract: write LaTeX output under \`<deliverables_root>/paper/\`.
1178
1233
 
1179
1234
  ## 升格策略
@@ -1284,7 +1339,7 @@ ZH_CONTENT[path.join(".lab", "system", "core.md")] = `# Lab 系统核心
1284
1339
 
1285
1340
  1. \`.lab/context/session-brief.md\`
1286
1341
  2. \`.lab/context/mission.md\`
1287
- 3. \`.lab/context/state.md\`
1342
+ 3. \`.lab/context/workflow-state.md\`
1288
1343
  4. \`.lab/context/evidence-index.md\`
1289
1344
  5. \`.lab/context/data-decisions.md\`(当问题涉及数据集、benchmark 或对比方法时)
1290
1345
  6. \`.lab/context/auto-mode.md\` 和 \`.lab/context/auto-status.md\`(当任务涉及自动模式时)
@@ -1293,13 +1348,15 @@ ZH_CONTENT[path.join(".lab", "system", "core.md")] = `# Lab 系统核心
1293
1348
 
1294
1349
  ## 工作流边界
1295
1350
 
1296
- - \`.lab/context/\` 保存持久研究状态。
1351
+ - \`.lab/context/\` 同时保存持久研究状态和轻量工作流状态。
1297
1352
  - \`.lab/changes/\`、\`.lab/iterations/\`、\`.lab/writing/\` 保存工作流控制工件、轻量 manifest 和 change-local harness。
1298
1353
  - \`.lab/.managed/\` 保存工具托管模板和脚本。
1299
1354
  - 持久 run 输出应写到 \`results_root\`,不要写进 \`.lab/changes/\`。
1300
1355
  - 图表和可视化应写到 \`figures_root\`,不要写进 \`.lab/changes/\`。
1301
1356
  - 最终交付物应写到 \`deliverables_root\`,不要写进 \`.lab/context/\`。
1302
1357
  - change-local 的 \`data/\` 目录只应用来放轻量 manifest 或 batch spec,不要当正式数据集入口。
1358
+ - \`.lab/context/state.md\` 保存持久研究状态;\`.lab/context/workflow-state.md\` 保存当前工作流状态。
1359
+ - \`.lab/context/summary.md\` 是长期项目摘要;\`.lab/context/session-brief.md\` 是下一次会话启动简报。
1303
1360
  - \`.lab/context/auto-mode.md\` 定义自动模式边界,\`.lab/context/auto-status.md\` 记录自动运行状态,二者都属于项目状态。
1304
1361
  - 如果用户提供了 LaTeX 模板目录,先校验并通过 \`paper_template_root\` 接入,再开始写作。
1305
1362
  - 已接入的模板目录视为用户资产,默认不要改模板文件,除非用户明确要求。
@@ -1391,7 +1448,7 @@ ZH_CONTENT[path.join(".lab", "context", "session-brief.md")] = `# 会话简报
1391
1448
  ## 先读这些文件
1392
1449
 
1393
1450
  1. \`.lab/context/mission.md\`
1394
- 2. \`.lab/context/state.md\`
1451
+ 2. \`.lab/context/workflow-state.md\`
1395
1452
  3. \`.lab/context/evidence-index.md\`
1396
1453
 
1397
1454
  ## 不要静默修改
@@ -1526,8 +1583,20 @@ ZH_CONTENT[path.join(".codex", "skills", "lab", "stages", "write.md")] = `# \`/l
1526
1583
  - 如果用户在最终提醒里仍确认继续使用默认 scaffold,就把 \`paper_template_final_reminder_acknowledged\` 持久化为 \`true\`。
1527
1584
  - 只加载当前 section guide,不要一次加载全部章节参考。
1528
1585
  - 如果当前 section 是 \`abstract\`、\`introduction\` 或 \`method\`,还必须继续读取本地 example bank:\`references/paper-writing/examples/index.md\`、对应的 examples index,以及 1-2 个具体 example 文件。
1586
+ - 如果当前 section 是 \`related work\`、\`experiments\` 或 \`conclusion\`,也要读取对应的本地 example bank:\`references/paper-writing/examples/index.md\`、对应的 examples index,以及 1-2 个具体 example 文件。
1529
1587
  - 例子只能复用结构、段落角色和句法逻辑,不能直接复用原句。
1530
1588
  - 先写 mini-outline 再写 prose。
1589
+ - 如果当前 section 带方法或实验 claim,先规划需要的表格、figure placeholders 和 citations,再写 prose。
1590
+ - 最终定稿或导出轮次里,必须维护非空的 \`references.bib\`,并把关键实验结果物化成真正的 LaTeX 表格:
1591
+ - \`<deliverables_root>/paper/tables/main-results.tex\`
1592
+ - \`<deliverables_root>/paper/tables/ablations.tex\`
1593
+ - 方法或实验章节还必须物化带 caption、label 和图意图的 figure placeholders:
1594
+ - \`<deliverables_root>/paper/figures/method-overview.tex\`
1595
+ - \`<deliverables_root>/paper/figures/results-overview.tex\`
1596
+ - 不要把纯 prose section 当成论文交付完成。
1597
+ - 论文源码里不要出现绝对本地路径、workflow provenance、shell 日志或 \`+/-\` 这类工程记法;应改成 paper-facing LaTeX 表达。
1598
+ - 在最终定稿或导出轮次结束前,必须运行 \`.lab/.managed/scripts/validate_manuscript_delivery.py --paper-dir <deliverables_root>/paper\`;如果失败,就继续补表、图、引用和正文。
1599
+ - 如果本地有 LaTeX 工具链,就再跑一次 compile smoke test;如果没有,也要在 write iteration artifact 里记录该限制。
1531
1600
  - 如果缺少 framing artifact,不要继续写作,直接回到 \`/lab:framing\`。
1532
1601
  - 如果某个 claim 没有证据支撑,就削弱或删除。
1533
1602
 
@@ -1537,7 +1606,12 @@ ZH_CONTENT[path.join(".codex", "skills", "lab", "stages", "write.md")] = `# \`/l
1537
1606
  - \`.lab/writing/plan.md\`
1538
1607
  - \`.lab/writing/iterations/<n>.md\`
1539
1608
  - \`<deliverables_root>/paper/main.tex\`
1609
+ - \`<deliverables_root>/paper/references.bib\`
1540
1610
  - \`<deliverables_root>/paper/sections/<section>.tex\`
1611
+ - \`<deliverables_root>/paper/tables/main-results.tex\`
1612
+ - \`<deliverables_root>/paper/tables/ablations.tex\`
1613
+ - \`<deliverables_root>/paper/figures/method-overview.tex\`
1614
+ - \`<deliverables_root>/paper/figures/results-overview.tex\`
1541
1615
  `;
1542
1616
 
1543
1617
  ZH_CONTENT[path.join(".claude", "skills", "lab", "stages", "write.md")] =
package/lib/install.cjs CHANGED
@@ -36,6 +36,7 @@ const PROJECT_OWNED_LOCALIZED_PATHS = [
36
36
  path.join(".lab", "config", "workflow.json"),
37
37
  path.join(".lab", "context", "mission.md"),
38
38
  path.join(".lab", "context", "state.md"),
39
+ path.join(".lab", "context", "workflow-state.md"),
39
40
  path.join(".lab", "context", "decisions.md"),
40
41
  path.join(".lab", "context", "evidence-index.md"),
41
42
  path.join(".lab", "context", "open-questions.md"),
@@ -542,6 +543,7 @@ function localizeInstalledAssets(targetDir, lang, { newlyCreatedProjectOwnedPath
542
543
  path.join(".lab", ".managed", "templates", "review-checklist.md"),
543
544
  path.join(".lab", ".managed", "templates", "final-report.md"),
544
545
  path.join(".lab", ".managed", "templates", "main-tables.md"),
546
+ path.join(".lab", ".managed", "templates", "artifact-status.md"),
545
547
  path.join(".lab", ".managed", "templates", "paper-plan.md"),
546
548
  path.join(".lab", ".managed", "templates", "paper-section.md"),
547
549
  path.join(".lab", ".managed", "templates", "write-iteration.md"),
@@ -7,4 +7,4 @@ argument-hint: section or writing target
7
7
  Use the installed `lab` skill at `.claude/skills/lab/SKILL.md`.
8
8
 
9
9
  Execute the requested `/lab-write` command against the user's argument now. Do not only recommend another lab stage. If a blocking prerequisite is missing, say exactly what is missing and ask at most one clarifying question.
10
- This command runs the `write` stage of the lab workflow. It requires an approved framing artifact from the `framing` stage, must read the matching section reference from `.claude/skills/lab/references/paper-writing/`, and for `abstract`, `introduction`, or `method` it must also read `.claude/skills/lab/references/paper-writing/examples/index.md` plus the matching examples index and 1-2 concrete example files. Then it should run `paper-review.md` and `does-my-writing-flow-source.md`, build a mini-outline, and revise only one section.
10
+ This command runs the `write` stage of the lab workflow. It requires an approved framing artifact from the `framing` stage, must read the matching section reference from `.claude/skills/lab/references/paper-writing/`, and for any section with a bundled example bank it must also read `.claude/skills/lab/references/paper-writing/examples/index.md` plus the matching examples index and 1-2 concrete example files. Then it should run `paper-review.md` and `does-my-writing-flow-source.md`, build a mini-outline, plan the section's paper-facing tables/figures/citations, and revise only one section. Final-draft or export rounds must run `.lab/.managed/scripts/validate_manuscript_delivery.py --paper-dir <deliverables_root>/paper` before stopping.