workflow-loop 0.3.5__tar.gz → 0.3.7__tar.gz

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 (109) hide show
  1. {workflow_loop-0.3.5/src/workflow_loop.egg-info → workflow_loop-0.3.7}/PKG-INFO +11 -9
  2. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/README.md +10 -8
  3. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/pyproject.toml +1 -1
  4. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/__init__.py +2 -2
  5. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/artifact_validation.py +115 -2
  6. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/cli.py +308 -12
  7. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/acceptance/acceptance.md +2 -0
  8. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/acceptance/acceptance_plan.md +4 -2
  9. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/impl/code_implementation.md +1 -1
  10. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/impl/impl.md +2 -2
  11. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/qa/test_plan.md +2 -0
  12. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/spec/spec.md +3 -0
  13. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/acceptance/acceptance_plan.md +1 -1
  14. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/acceptance/acceptance_result.md +2 -0
  15. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/impl/impl.md +19 -1
  16. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/qa/test.md +2 -2
  17. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/qa/test_plan.md +3 -3
  18. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/reproduce/reproduce.md +1 -1
  19. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/spec/spec.md +3 -1
  20. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/spike/spike.md +1 -1
  21. workflow_loop-0.3.7/src/workflow_loop/records.py +2884 -0
  22. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/rollback.py +219 -88
  23. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/stages/stages.py +230 -11
  24. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/state.py +4 -0
  25. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/test_execution.py +154 -20
  26. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/test_mapping.py +103 -1
  27. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/topic.py +41 -1
  28. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/traceability.py +313 -1
  29. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/verification.py +191 -20
  30. {workflow_loop-0.3.5 → workflow_loop-0.3.7/src/workflow_loop.egg-info}/PKG-INFO +11 -9
  31. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop.egg-info/SOURCES.txt +3 -0
  32. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_commands.py +10 -1
  33. workflow_loop-0.3.7/tests/test_records.py +1189 -0
  34. workflow_loop-0.3.7/tests/test_return_rework_flow.py +924 -0
  35. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_rollback.py +176 -0
  36. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_verification.py +68 -0
  37. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/LICENSE +0 -0
  38. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/setup.cfg +0 -0
  39. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/acceptance_records.py +0 -0
  40. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/artifact_paths.py +0 -0
  41. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/bug_record.py +0 -0
  42. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/code_design/code_design.md +0 -0
  43. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/code_design/project_design_init.md +0 -0
  44. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/code_design/update_code_design.md +0 -0
  45. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/global/document_writing.md +0 -0
  46. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/global/workflow_lifecycle.md +0 -0
  47. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/qa/test.md +0 -0
  48. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/qa/test_code.md +0 -0
  49. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/qa/test_code_implementation.md +0 -0
  50. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/reproduce/reproduce.md +0 -0
  51. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Standardized_Repository/spike/spike.md +0 -0
  52. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/code_design/code_design.md +0 -0
  53. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/data/Template_Repository/code_design/project_design_init_evidence.md +0 -0
  54. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/diagnostics.py +0 -0
  55. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/installer.py +0 -0
  56. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/journal.py +0 -0
  57. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/markdown_links.py +0 -0
  58. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/path_composer.py +0 -0
  59. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/process_runner.py +0 -0
  60. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/project.py +0 -0
  61. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/role_doc.py +0 -0
  62. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/snapshots.py +0 -0
  63. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/spike_reuse.py +0 -0
  64. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/spike_validation.py +0 -0
  65. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/stage_materials.py +0 -0
  66. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/stages/__init__.py +0 -0
  67. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/stages/base.py +0 -0
  68. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/test_entry.py +0 -0
  69. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/test_report.py +0 -0
  70. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/test_runner.py +0 -0
  71. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop/topic_relations.py +0 -0
  72. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop.egg-info/dependency_links.txt +0 -0
  73. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop.egg-info/entry_points.txt +0 -0
  74. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop.egg-info/requires.txt +0 -0
  75. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/src/workflow_loop.egg-info/top_level.txt +0 -0
  76. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_acceptance_records.py +0 -0
  77. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_architecture_validation.py +0 -0
  78. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_artifact_paths.py +0 -0
  79. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_bug_record.py +0 -0
  80. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_bug_validation.py +0 -0
  81. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_current_workflow_contracts.py +0 -0
  82. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_current_workflow_qa.py +0 -0
  83. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_diagnostics.py +0 -0
  84. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_installer.py +0 -0
  85. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_light_task.py +0 -0
  86. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_maintenance.py +0 -0
  87. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_maintenance_scripts.py +0 -0
  88. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_markdown_links.py +0 -0
  89. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_path_composer.py +0 -0
  90. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_process_runner.py +0 -0
  91. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_project.py +0 -0
  92. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_project_design_init.py +0 -0
  93. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_public_project.py +0 -0
  94. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_release_script.py +0 -0
  95. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_release_workflow.py +0 -0
  96. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_snapshots.py +0 -0
  97. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_spike_assets.py +0 -0
  98. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_spike_validation.py +0 -0
  99. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_stage_materials.py +0 -0
  100. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_stages.py +0 -0
  101. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_state.py +0 -0
  102. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_test_entry.py +0 -0
  103. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_test_execution.py +0 -0
  104. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_test_mapping.py +0 -0
  105. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_test_report.py +0 -0
  106. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_test_runner.py +0 -0
  107. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_topic_relations.py +0 -0
  108. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_traceability.py +0 -0
  109. {workflow_loop-0.3.5 → workflow_loop-0.3.7}/tests/test_workflow_acceptance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workflow-loop
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Summary: 为 AI 驱动的软件开发提供有状态、可验证、可回退的工作流管理。
5
5
  Author: yuzyf
6
6
  License-Expression: MIT
@@ -34,6 +34,7 @@ Workflow Loop 把一次软件修改拆成有顺序的工作环节,并用程序
34
34
 
35
35
  - **保存进度**:在项目的 `.workflow_loop/` 目录保存当前工作环节、确认状态和机器执行记录,下一次对话可以从真实状态继续。
36
36
  - **控制推进**:完整研发任务的每个环节依次经过讨论完成、程序检查和用户确认三道门;无需开发任务走独立的讨论、执行、结果确认简单流程。
37
+ - **工作记录表**:程序在环节开始时生成机器可校验的填空表并预填固定事实,AI 只填空位;正式文档由程序按表生成,门禁检查表并检测文档被直接修改,消除格式反复。
37
38
  - **一次说明门禁问题**:完整研发门禁失败时,一次列出当前能够独立确认的全部问题;每项写明位置、预期、实际、证据、影响和下一动作,无法可靠判断的项目标为“未检查”并说明依赖。同一状态重复检查时,问题清单和顺序保持一致,要求先修改后再检查。
38
39
  - **给出唯一下一步**:每条命令结束时只给出一条完整有效的下一命令,并说明执行者、是否会自动执行测试或其它实际动作、以及成功条件。AI 必须原样执行,不能追加管道、截断、重定向或命令串联。
39
40
  - **连接交付证据**:把产品设计、验收条件、测试项、实施记录和最终结果放进同一条可追踪链路。
@@ -94,29 +95,29 @@ flowchart TD
94
95
  - 安装时能够访问 GitHub 和 PyPI(Python 公共软件包仓库)。
95
96
  - 执行安装命令前,先进入要由 Workflow Loop 管理的项目根目录。
96
97
 
97
- ## 安装 0.3.5
98
+ ## 安装 0.3.7
98
99
 
99
100
  安装器先进行只读检查并列出项目侧和电脑侧可能发生的全部持久修改。用户确认一次后,安装器才安装或复用全局 `workflow` 命令,并把智能体契约、产物模板和工作规范写入当前项目;用户取消或安装失败时不会留下只完成一部分的安装。
100
101
 
101
102
  ### macOS
102
103
 
103
104
  ```bash
104
- curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.5/install.sh | bash
105
+ curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.7/install.sh | bash
105
106
  ```
106
107
 
107
108
  ### Linux
108
109
 
109
110
  ```bash
110
- curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.5/install.sh | bash
111
+ curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.7/install.sh | bash
111
112
  ```
112
113
 
113
114
  ### 原生 Windows
114
115
 
115
116
  ```powershell
116
- powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/yuzyf/workflow_loop/releases/download/v0.3.5/install.ps1 | iex"
117
+ powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/yuzyf/workflow_loop/releases/download/v0.3.7/install.ps1 | iex"
117
118
  ```
118
119
 
119
- 安装命令固定读取 `v0.3.5` 正式发布中的脚本;不会跟随内容可能变化的 `latest`(最新版本)地址。
120
+ 安装命令固定读取 `v0.3.7` 正式发布中的脚本;不会跟随内容可能变化的 `latest`(最新版本)地址。
120
121
 
121
122
  ## 更新与卸载
122
123
 
@@ -124,7 +125,7 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/y
124
125
 
125
126
  ```bash
126
127
  workflow update
127
- workflow update --version 0.3.5
128
+ workflow update --version 0.3.7
128
129
  ```
129
130
 
130
131
  更新按需补齐电脑全局命令和当前项目,只直接覆盖项目根 `AGENTS.md`、`.workflow_loop/Template_Repository/`、`.workflow_loop/Standardized_Repository/`,以及 `.workflow_loop/project.json` 中的安装版本字段。更新不创建备份,不回滚已经完成的步骤;当前轮次状态、历史、回退资料、业务代码和正式产物保持不变。失败后重新执行同一命令即可继续补齐。
@@ -197,6 +198,7 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/y
197
198
  | `workflow discuss` | 加载当前环节必须遵守的模板、规范和项目材料 |
198
199
  | `workflow gate <stage> --discuss-done` | 通过当前环节的讨论完成门;`<stage>` 表示当前环节标识 |
199
200
  | `workflow gate <stage>` | 让程序检查当前环节的文件、结构和可验证事实 |
201
+ | `workflow scaffold` | 为当前环节生成或补齐工作记录表;已填内容不覆盖 |
200
202
  | `workflow gate <stage> --confirmed` | 记录用户对当前环节的最终确认并进入下一环节 |
201
203
  | `workflow status` | 显示当前轮次、环节、门禁状态和下一步 |
202
204
  | `workflow test ...` | 登记统一测试入口、准备测试项或执行受控测试 |
@@ -227,10 +229,10 @@ uv run python -m build
227
229
 
228
230
  ## 发布正式版本
229
231
 
230
- 项目维护者确认当前仓库内容可以直接发布后,在仓库根目录执行下面的命令,并把 `0.3.5` 替换成要发布的新版本号:
232
+ 项目维护者确认当前仓库内容可以直接发布后,在仓库根目录执行下面的命令,并把 `0.3.7` 替换成要发布的新版本号:
231
233
 
232
234
  ```bash
233
- uv run python scripts/release.py 0.3.5
235
+ uv run python scripts/release.py 0.3.7
234
236
  ```
235
237
 
236
238
  运行这条命令本身就表示维护者接受当前仓库状态并承担跳过本地发布检查的风险。脚本不会再次确认,也不会在本地运行测试、构建或远程版本查询。它依次执行:
@@ -15,6 +15,7 @@ Workflow Loop 把一次软件修改拆成有顺序的工作环节,并用程序
15
15
 
16
16
  - **保存进度**:在项目的 `.workflow_loop/` 目录保存当前工作环节、确认状态和机器执行记录,下一次对话可以从真实状态继续。
17
17
  - **控制推进**:完整研发任务的每个环节依次经过讨论完成、程序检查和用户确认三道门;无需开发任务走独立的讨论、执行、结果确认简单流程。
18
+ - **工作记录表**:程序在环节开始时生成机器可校验的填空表并预填固定事实,AI 只填空位;正式文档由程序按表生成,门禁检查表并检测文档被直接修改,消除格式反复。
18
19
  - **一次说明门禁问题**:完整研发门禁失败时,一次列出当前能够独立确认的全部问题;每项写明位置、预期、实际、证据、影响和下一动作,无法可靠判断的项目标为“未检查”并说明依赖。同一状态重复检查时,问题清单和顺序保持一致,要求先修改后再检查。
19
20
  - **给出唯一下一步**:每条命令结束时只给出一条完整有效的下一命令,并说明执行者、是否会自动执行测试或其它实际动作、以及成功条件。AI 必须原样执行,不能追加管道、截断、重定向或命令串联。
20
21
  - **连接交付证据**:把产品设计、验收条件、测试项、实施记录和最终结果放进同一条可追踪链路。
@@ -75,29 +76,29 @@ flowchart TD
75
76
  - 安装时能够访问 GitHub 和 PyPI(Python 公共软件包仓库)。
76
77
  - 执行安装命令前,先进入要由 Workflow Loop 管理的项目根目录。
77
78
 
78
- ## 安装 0.3.5
79
+ ## 安装 0.3.7
79
80
 
80
81
  安装器先进行只读检查并列出项目侧和电脑侧可能发生的全部持久修改。用户确认一次后,安装器才安装或复用全局 `workflow` 命令,并把智能体契约、产物模板和工作规范写入当前项目;用户取消或安装失败时不会留下只完成一部分的安装。
81
82
 
82
83
  ### macOS
83
84
 
84
85
  ```bash
85
- curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.5/install.sh | bash
86
+ curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.7/install.sh | bash
86
87
  ```
87
88
 
88
89
  ### Linux
89
90
 
90
91
  ```bash
91
- curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.5/install.sh | bash
92
+ curl -fsSL https://github.com/yuzyf/workflow_loop/releases/download/v0.3.7/install.sh | bash
92
93
  ```
93
94
 
94
95
  ### 原生 Windows
95
96
 
96
97
  ```powershell
97
- powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/yuzyf/workflow_loop/releases/download/v0.3.5/install.ps1 | iex"
98
+ powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/yuzyf/workflow_loop/releases/download/v0.3.7/install.ps1 | iex"
98
99
  ```
99
100
 
100
- 安装命令固定读取 `v0.3.5` 正式发布中的脚本;不会跟随内容可能变化的 `latest`(最新版本)地址。
101
+ 安装命令固定读取 `v0.3.7` 正式发布中的脚本;不会跟随内容可能变化的 `latest`(最新版本)地址。
101
102
 
102
103
  ## 更新与卸载
103
104
 
@@ -105,7 +106,7 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/y
105
106
 
106
107
  ```bash
107
108
  workflow update
108
- workflow update --version 0.3.5
109
+ workflow update --version 0.3.7
109
110
  ```
110
111
 
111
112
  更新按需补齐电脑全局命令和当前项目,只直接覆盖项目根 `AGENTS.md`、`.workflow_loop/Template_Repository/`、`.workflow_loop/Standardized_Repository/`,以及 `.workflow_loop/project.json` 中的安装版本字段。更新不创建备份,不回滚已经完成的步骤;当前轮次状态、历史、回退资料、业务代码和正式产物保持不变。失败后重新执行同一命令即可继续补齐。
@@ -178,6 +179,7 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/y
178
179
  | `workflow discuss` | 加载当前环节必须遵守的模板、规范和项目材料 |
179
180
  | `workflow gate <stage> --discuss-done` | 通过当前环节的讨论完成门;`<stage>` 表示当前环节标识 |
180
181
  | `workflow gate <stage>` | 让程序检查当前环节的文件、结构和可验证事实 |
182
+ | `workflow scaffold` | 为当前环节生成或补齐工作记录表;已填内容不覆盖 |
181
183
  | `workflow gate <stage> --confirmed` | 记录用户对当前环节的最终确认并进入下一环节 |
182
184
  | `workflow status` | 显示当前轮次、环节、门禁状态和下一步 |
183
185
  | `workflow test ...` | 登记统一测试入口、准备测试项或执行受控测试 |
@@ -208,10 +210,10 @@ uv run python -m build
208
210
 
209
211
  ## 发布正式版本
210
212
 
211
- 项目维护者确认当前仓库内容可以直接发布后,在仓库根目录执行下面的命令,并把 `0.3.5` 替换成要发布的新版本号:
213
+ 项目维护者确认当前仓库内容可以直接发布后,在仓库根目录执行下面的命令,并把 `0.3.7` 替换成要发布的新版本号:
212
214
 
213
215
  ```bash
214
- uv run python scripts/release.py 0.3.5
216
+ uv run python scripts/release.py 0.3.7
215
217
  ```
216
218
 
217
219
  运行这条命令本身就表示维护者接受当前仓库状态并承担跳过本地发布检查的风险。脚本不会再次确认,也不会在本地运行测试、构建或远程版本查询。它依次执行:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "workflow-loop"
3
- version = "0.3.5"
3
+ version = "0.3.7"
4
4
  description = "为 AI 驱动的软件开发提供有状态、可验证、可回退的工作流管理。"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  # 包版本号,用于 pip/uv 安装时版本匹配
2
- __version__ = "0.3.5"
2
+ __version__ = "0.3.7"
3
3
  # 产品身份标识:workflow --version 输出、安装脚本身份核对和安装事务校验共用同一组常量
4
- # 本次发布版本为 0.3.5;后续发布使用尚未被 PyPI 占用的新版本号
4
+ # 本次发布版本为 0.3.7;后续发布使用尚未被 PyPI 占用的新版本号
5
5
  PRODUCT_NAME = "workflow-loop"
6
6
  PRODUCT_IDENTITY = f"{PRODUCT_NAME} {__version__}"
@@ -1873,12 +1873,83 @@ def validate_downstream_traceability(
1873
1873
  return traceability_mod.validate_structure(project_root, workflow_id, topics)
1874
1874
 
1875
1875
 
1876
+ def _table_mode_qa(project_root: str, workflow_id: str, topics: list[str]) -> bool:
1877
+ """全部主题都有已填测试工作记录表时,qa 的文档校验走表核对。"""
1878
+ from . import records as records_mod
1879
+
1880
+ if not topics:
1881
+ return False
1882
+ for topic in topics:
1883
+ relative = records_mod.table_relative_path(
1884
+ project_root, workflow_id, "test_plan", topic
1885
+ )
1886
+ if not records_mod.table_exists(project_root, relative):
1887
+ return False
1888
+ try:
1889
+ table = records_mod.load_table(os.path.join(project_root, relative))
1890
+ except records_mod.RecordsError:
1891
+ return False
1892
+ if not (table.get("测试项") or table.get("测试范围说明")):
1893
+ return False
1894
+ return True
1895
+
1896
+
1897
+ def _validate_test_plan_from_tables(
1898
+ project_root: str,
1899
+ workflow_id: str,
1900
+ topics: list[str],
1901
+ ) -> tuple[bool, str]:
1902
+ """表模式:核对每条验收条件在测试计划表中有测试项覆盖。"""
1903
+ import re as _re
1904
+
1905
+ from . import records as records_mod
1906
+ from .topic import topic_paths
1907
+
1908
+ failures: list[str] = []
1909
+ for topic in topics:
1910
+ relative = records_mod.table_relative_path(
1911
+ project_root, workflow_id, "test_plan", topic
1912
+ )
1913
+ table = records_mod.load_table(os.path.join(project_root, relative))
1914
+ rows = table.get("测试项", [])
1915
+ if not rows:
1916
+ # 纯人工主题:自动化验证由最终全量回归承担,验收条件在主题验收人工核对
1917
+ continue
1918
+ coverage: dict[str, int] = {}
1919
+ for row in rows:
1920
+ if not isinstance(row, dict):
1921
+ continue
1922
+ for criterion_id in _re.findall(r"AC-\d+", str(row.get("对应验收条件", ""))):
1923
+ coverage[criterion_id] = coverage.get(criterion_id, 0) + 1
1924
+ acceptance_rel = topic_paths(project_root, topic)["acceptance_plan"]
1925
+ acceptance_full = os.path.join(project_root, acceptance_rel)
1926
+ if not os.path.isfile(acceptance_full):
1927
+ failures.append(f"{topic}:上游验收计划 {acceptance_rel} 不存在")
1928
+ continue
1929
+ criterion_ids = ACCEPTANCE_CRITERION_RE.findall(
1930
+ _read_text(project_root, acceptance_rel)
1931
+ )
1932
+ for criterion_id in criterion_ids:
1933
+ if coverage.get(criterion_id, 0) == 0:
1934
+ failures.append(
1935
+ f"{topic} 的测试工作记录表没有覆盖 {criterion_id}"
1936
+ )
1937
+ if failures:
1938
+ return False, _format_validation_failures(failures)
1939
+ return True, f"{len(topics)} 个主题的测试计划表覆盖全部验收条件"
1940
+
1941
+
1876
1942
  def validate_test_plan_documents(
1877
1943
  project_root: str,
1878
1944
  workflow_id: str,
1879
1945
  topics: list[str],
1880
1946
  ) -> tuple[bool, str]:
1881
- """校验测试计划结构,以及每条 AC 到 TC 的覆盖关系。"""
1947
+ """校验测试计划结构,以及每条 AC 到 TC 的覆盖关系。
1948
+
1949
+ 全部主题都已填写测试工作记录表时,表是真本,按表核对覆盖关系。
1950
+ """
1951
+ if _table_mode_qa(project_root, workflow_id, topics):
1952
+ return _validate_test_plan_from_tables(project_root, workflow_id, topics)
1882
1953
  qa_index = artifact_paths_mod.QA_INDEX_DOC
1883
1954
  index_path = os.path.join(project_root, qa_index)
1884
1955
  failures: list[str] = []
@@ -2022,7 +2093,49 @@ def _validate_topic_acceptance_result(
2022
2093
  workflow_id: str,
2023
2094
  topic: str,
2024
2095
  ) -> tuple[bool, str]:
2025
- """校验正式主题验收结果只包含全部通过的当前验收条件。"""
2096
+ """校验正式主题验收结果只包含全部通过的当前验收条件。
2097
+
2098
+ 验收结果工作记录表启用时,表是真本:按表核对结论,不读旧文档/状态记录。
2099
+ """
2100
+ from . import records as records_mod
2101
+
2102
+ table_relative = records_mod.table_relative_path(
2103
+ project_root, workflow_id, "acceptance_result", topic
2104
+ )
2105
+ if records_mod.table_exists(project_root, table_relative):
2106
+ table = records_mod.load_table(os.path.join(project_root, table_relative))
2107
+ failures: list[str] = []
2108
+ plan_relative = topic_paths(project_root, topic)["acceptance_plan"]
2109
+ plan_ids = [
2110
+ match.group(1)
2111
+ for match in ACCEPTANCE_CRITERION_RE.finditer(
2112
+ _read_text(project_root, plan_relative)
2113
+ if os.path.isfile(os.path.join(project_root, plan_relative))
2114
+ else ""
2115
+ )
2116
+ ]
2117
+ result_ids = [
2118
+ str(row.get("验收条件编号", "")).strip()
2119
+ for row in table.get("验收结果", [])
2120
+ if isinstance(row, dict) and str(row.get("验收条件编号", "")).strip()
2121
+ ]
2122
+ if plan_ids and result_ids != plan_ids:
2123
+ failures.append(
2124
+ f"{topic} 的验收条件必须与验收计划一致: 计划={plan_ids}, 结果={result_ids}"
2125
+ )
2126
+ for row in table.get("验收结果", []):
2127
+ if not isinstance(row, dict):
2128
+ continue
2129
+ ac = str(row.get("验收条件编号", "")).strip()
2130
+ if str(row.get("验收结论", "")).strip() != "passed":
2131
+ failures.append(f"{topic} / {ac} 验收结论不是 passed")
2132
+ elif not _has_real_text(str(row.get("实际观察结果", ""))):
2133
+ failures.append(f"{topic} / {ac} 缺少实际观察结果")
2134
+ elif not _has_real_text(str(row.get("证据", ""))):
2135
+ failures.append(f"{topic} / {ac} 缺少证据")
2136
+ if failures:
2137
+ return False, _format_validation_failures(failures)
2138
+ return True, f"{topic} 的验收结果表全部通过"
2026
2139
  paths = topic_paths(project_root, topic)
2027
2140
  rel_path = paths["acceptance_result"]
2028
2141
  failures: list[str] = []