@chenmk/superflow 0.3.0 → 0.5.0
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.
- package/INSTALL.en.md +54 -12
- package/INSTALL.md +59 -33
- package/README.md +192 -49
- package/README.zh-CN.md +166 -46
- package/assets/brand/managed-review-loop.png +0 -0
- package/assets/manifest.json +15 -9
- package/assets/prompts/superflow-design.md +3 -0
- package/assets/prompts/superflow-docs.md +4 -1
- package/assets/scripts/superflow-coding-ready.mjs +135 -0
- package/assets/scripts/superflow-dependency-update-hook.sh +81 -8
- package/assets/scripts/superflow-document-audit.mjs +240 -0
- package/assets/scripts/superflow-environment-preflight.mjs +398 -0
- package/assets/scripts/superflow-hook-guard.sh +40 -1
- package/assets/scripts/superflow-managed-command-guard.py +309 -0
- package/assets/scripts/superflow-managed-executor-preflight.mjs +421 -0
- package/assets/scripts/superflow-managed-owner-verification.sh +117 -0
- package/assets/scripts/superflow-managed-work-check.mjs +455 -0
- package/assets/scripts/superflow-managed-work-guard.sh +17 -0
- package/assets/skills/openspec-propose/SKILL.md +11 -0
- package/assets/skills/superflow-clarify/SKILL.md +14 -0
- package/assets/skills/superflow-design/SKILL.md +46 -12
- package/assets/skills/superflow-docs/SKILL.md +109 -2
- package/assets/skills/superflow-pipeline/SKILL.md +205 -2
- package/assets/skills/superflow-pipeline/references/batch-prompt-template.md +17 -9
- package/assets/skills/superflow-pipeline/references/document-readiness.md +157 -0
- package/assets/skills/superflow-pipeline/references/document-templates.md +17 -5
- package/assets/skills/superflow-pipeline/references/feature-gated-workflow.md +14 -0
- package/assets/skills/superflow-pipeline/references/implementation-prompt-template.md +20 -11
- package/assets/skills/superflow-pipeline/references/managed-work.md +166 -0
- package/assets/skills/superflow-pipeline/references/orchestration.md +2 -2
- package/assets/skills/superflow-pipeline/references/p0-baseline-template.md +3 -2
- package/assets/skills/superflow-pipeline/references/quality-gate.md +8 -5
- package/assets/skills/superflow-pipeline/references/reviewer-checklist.md +7 -0
- package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +10 -0
- package/assets/skills/superflow-pipeline/scripts/superflow-archive.sh +1 -1
- package/assets/skills/superflow-pipeline/scripts/superflow-guard.sh +282 -16
- package/assets/skills/superflow-pipeline/scripts/superflow-handoff.sh +7 -4
- package/assets/skills/superflow-requirement-review/SKILL.md +178 -0
- package/assets/skills/superflow-requirement-review/agents/openai.yaml +4 -0
- package/assets/skills-en/openspec-propose/SKILL.md +14 -0
- package/assets/skills-en/superflow-clarify/SKILL.md +17 -0
- package/assets/skills-en/superflow-design/SKILL.md +40 -11
- package/assets/skills-en/superflow-docs/SKILL.md +115 -0
- package/assets/skills-en/superflow-pipeline/SKILL.md +202 -0
- package/assets/skills-en/superflow-pipeline/references/batch-prompt-template.md +4 -0
- package/assets/skills-en/superflow-pipeline/references/document-readiness.md +125 -0
- package/assets/skills-en/superflow-pipeline/references/document-templates.md +15 -0
- package/assets/skills-en/superflow-pipeline/references/feature-gated-workflow.md +7 -0
- package/assets/skills-en/superflow-pipeline/references/implementation-prompt-template.md +7 -0
- package/assets/skills-en/superflow-pipeline/references/managed-work.md +184 -0
- package/assets/skills-en/superflow-pipeline/references/quality-gate.md +20 -0
- package/assets/skills-en/superflow-pipeline/references/reviewer-checklist.md +7 -0
- package/assets/skills-en/superflow-pipeline/references/superpower-technical-design-template.md +11 -0
- package/assets/skills-en/superflow-pipeline/scripts/superflow-archive.sh +1 -1
- package/assets/skills-en/superflow-pipeline/scripts/superflow-guard.sh +279 -14
- package/assets/skills-en/superflow-pipeline/scripts/superflow-handoff.sh +7 -4
- package/assets/skills-en/superflow-requirement-review/SKILL.md +99 -0
- package/assets/skills-en/superflow-requirement-review/agents/openai.yaml +4 -0
- package/dist/app/cli.js +176 -103
- package/dist/app/cli.js.map +1 -1
- package/dist/app/commands/change-guard.js +19 -2
- package/dist/app/commands/change-guard.js.map +1 -1
- package/dist/app/commands/check.js +107 -45
- package/dist/app/commands/check.js.map +1 -1
- package/dist/app/commands/docs.js +7 -3
- package/dist/app/commands/docs.js.map +1 -1
- package/dist/app/commands/doctor.js +174 -198
- package/dist/app/commands/doctor.js.map +1 -1
- package/dist/app/commands/eval.js +64 -0
- package/dist/app/commands/eval.js.map +1 -0
- package/dist/app/commands/implement.js +7 -3
- package/dist/app/commands/implement.js.map +1 -1
- package/dist/app/commands/init.js +16 -24
- package/dist/app/commands/init.js.map +1 -1
- package/dist/app/commands/managed-service.js +5 -0
- package/dist/app/commands/managed-service.js.map +1 -0
- package/dist/app/commands/mcp.js +167 -0
- package/dist/app/commands/mcp.js.map +1 -0
- package/dist/app/commands/pipeline.js +757 -3
- package/dist/app/commands/pipeline.js.map +1 -1
- package/dist/app/commands/requirement-review.js +6 -0
- package/dist/app/commands/requirement-review.js.map +1 -0
- package/dist/app/commands/status.js +262 -77
- package/dist/app/commands/status.js.map +1 -1
- package/dist/app/commands/uninstall.js +8 -5
- package/dist/app/commands/uninstall.js.map +1 -1
- package/dist/app/commands/update.js +114 -15
- package/dist/app/commands/update.js.map +1 -1
- package/dist/domains/agent.js +3 -11
- package/dist/domains/agent.js.map +1 -1
- package/dist/domains/config/cli-help.js +145 -73
- package/dist/domains/config/cli-help.js.map +1 -1
- package/dist/domains/config/i18n.js +6 -8
- package/dist/domains/config/i18n.js.map +1 -1
- package/dist/domains/config/manifest.js +0 -3
- package/dist/domains/config/manifest.js.map +1 -1
- package/dist/domains/deps.js +70 -8
- package/dist/domains/deps.js.map +1 -1
- package/dist/domains/hook.js +71 -38
- package/dist/domains/hook.js.map +1 -1
- package/dist/domains/managed-work/completion-policy.js +174 -0
- package/dist/domains/managed-work/completion-policy.js.map +1 -0
- package/dist/domains/managed-work/context-manifest.js +208 -0
- package/dist/domains/managed-work/context-manifest.js.map +1 -0
- package/dist/domains/managed-work/contract.js +349 -0
- package/dist/domains/managed-work/contract.js.map +1 -0
- package/dist/domains/managed-work/control-signals.js +34 -0
- package/dist/domains/managed-work/control-signals.js.map +1 -0
- package/dist/domains/managed-work/control.js +628 -0
- package/dist/domains/managed-work/control.js.map +1 -0
- package/dist/domains/managed-work/evaluation.js +497 -0
- package/dist/domains/managed-work/evaluation.js.map +1 -0
- package/dist/domains/managed-work/evidence-path.js +14 -0
- package/dist/domains/managed-work/evidence-path.js.map +1 -0
- package/dist/domains/managed-work/execution-contract.js +167 -0
- package/dist/domains/managed-work/execution-contract.js.map +1 -0
- package/dist/domains/managed-work/executor-policy.js +65 -0
- package/dist/domains/managed-work/executor-policy.js.map +1 -0
- package/dist/domains/managed-work/failure.js +65 -0
- package/dist/domains/managed-work/failure.js.map +1 -0
- package/dist/domains/managed-work/host-review.js +77 -0
- package/dist/domains/managed-work/host-review.js.map +1 -0
- package/dist/domains/managed-work/human-messages.js +31 -0
- package/dist/domains/managed-work/human-messages.js.map +1 -0
- package/dist/domains/managed-work/i18n.js +12 -0
- package/dist/domains/managed-work/i18n.js.map +1 -0
- package/dist/domains/managed-work/input.js +137 -0
- package/dist/domains/managed-work/input.js.map +1 -0
- package/dist/domains/managed-work/journal.js +196 -0
- package/dist/domains/managed-work/journal.js.map +1 -0
- package/dist/domains/managed-work/lock.js +106 -0
- package/dist/domains/managed-work/lock.js.map +1 -0
- package/dist/domains/managed-work/notifications.js +38 -0
- package/dist/domains/managed-work/notifications.js.map +1 -0
- package/dist/domains/managed-work/pair-admission.js +108 -0
- package/dist/domains/managed-work/pair-admission.js.map +1 -0
- package/dist/domains/managed-work/paths.js +18 -0
- package/dist/domains/managed-work/paths.js.map +1 -0
- package/dist/domains/managed-work/prompts.js +453 -0
- package/dist/domains/managed-work/prompts.js.map +1 -0
- package/dist/domains/managed-work/redaction.js +90 -0
- package/dist/domains/managed-work/redaction.js.map +1 -0
- package/dist/domains/managed-work/review-convergence.js +41 -0
- package/dist/domains/managed-work/review-convergence.js.map +1 -0
- package/dist/domains/managed-work/review-facts.js +181 -0
- package/dist/domains/managed-work/review-facts.js.map +1 -0
- package/dist/domains/managed-work/rule-selection.js +84 -0
- package/dist/domains/managed-work/rule-selection.js.map +1 -0
- package/dist/domains/managed-work/runner.js +2418 -0
- package/dist/domains/managed-work/runner.js.map +1 -0
- package/dist/domains/managed-work/schemas.js +155 -0
- package/dist/domains/managed-work/schemas.js.map +1 -0
- package/dist/domains/managed-work/service.js +190 -0
- package/dist/domains/managed-work/service.js.map +1 -0
- package/dist/domains/managed-work/state.js +280 -0
- package/dist/domains/managed-work/state.js.map +1 -0
- package/dist/domains/managed-work/storage.js +223 -0
- package/dist/domains/managed-work/storage.js.map +1 -0
- package/dist/domains/managed-work/types.js +19 -0
- package/dist/domains/managed-work/types.js.map +1 -0
- package/dist/domains/managed-work/verification-categories.js +39 -0
- package/dist/domains/managed-work/verification-categories.js.map +1 -0
- package/dist/domains/managed-work/verification-policy.js +116 -0
- package/dist/domains/managed-work/verification-policy.js.map +1 -0
- package/dist/domains/managed-work/wait.js +58 -0
- package/dist/domains/managed-work/wait.js.map +1 -0
- package/dist/domains/managed-work/workspace-binding.js +133 -0
- package/dist/domains/managed-work/workspace-binding.js.map +1 -0
- package/dist/domains/sdd-readiness.js +44 -0
- package/dist/domains/sdd-readiness.js.map +1 -0
- package/dist/domains/skill/deploy.js +0 -6
- package/dist/domains/skill/deploy.js.map +1 -1
- package/dist/domains/skill/scripts.js +0 -8
- package/dist/domains/skill/scripts.js.map +1 -1
- package/dist/domains/state.js +1 -2
- package/dist/domains/state.js.map +1 -1
- package/dist/mcp/runtime-identity.js +21 -0
- package/dist/mcp/runtime-identity.js.map +1 -0
- package/dist/mcp/server.js +369 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/platform/agent-process.js +769 -0
- package/dist/platform/agent-process.js.map +1 -0
- package/dist/platform/executable.js +28 -0
- package/dist/platform/executable.js.map +1 -0
- package/dist/platform/paths.js +1 -17
- package/dist/platform/paths.js.map +1 -1
- package/dist/platform/process-liveness.js +10 -0
- package/dist/platform/process-liveness.js.map +1 -0
- package/dist/platform/process-tree.js +44 -0
- package/dist/platform/process-tree.js.map +1 -0
- package/dist/platform/process.js +1 -1
- package/dist/platform/process.js.map +1 -1
- package/dist/platform/version-check.js +30 -9
- package/dist/platform/version-check.js.map +1 -1
- package/package.json +16 -7
- package/scripts/check-design-principles.mjs +107 -0
- package/scripts/check-managed-work-design.mjs +507 -0
- package/scripts/clean-dist.js +9 -0
- package/scripts/ensure-bin-modes.js +11 -0
- package/dist/cli/index.js +0 -193
- package/dist/cli/index.js.map +0 -1
- package/dist/commands/archive.js +0 -6
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/clarify.js +0 -6
- package/dist/commands/clarify.js.map +0 -1
- package/dist/commands/design.js +0 -28
- package/dist/commands/design.js.map +0 -1
- package/dist/commands/docs.js +0 -6
- package/dist/commands/docs.js.map +0 -1
- package/dist/commands/doctor.js +0 -494
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/implement.js +0 -6
- package/dist/commands/implement.js.map +0 -1
- package/dist/commands/init.js +0 -520
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/pipeline.js +0 -6
- package/dist/commands/pipeline.js.map +0 -1
- package/dist/commands/scan.js +0 -63
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/status.js +0 -173
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/uninstall.js +0 -214
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/update.js +0 -193
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/verify.js +0 -6
- package/dist/commands/verify.js.map +0 -1
- package/dist/core/assets.js +0 -27
- package/dist/core/assets.js.map +0 -1
- package/dist/core/cli-help.js +0 -98
- package/dist/core/cli-help.js.map +0 -1
- package/dist/core/context.js +0 -123
- package/dist/core/context.js.map +0 -1
- package/dist/core/dependencies.js +0 -146
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/detect.js +0 -64
- package/dist/core/detect.js.map +0 -1
- package/dist/core/i18n.js +0 -105
- package/dist/core/i18n.js.map +0 -1
- package/dist/core/integrity.js +0 -46
- package/dist/core/integrity.js.map +0 -1
- package/dist/core/manifest.js +0 -21
- package/dist/core/manifest.js.map +0 -1
- package/dist/core/prompts.js +0 -20
- package/dist/core/prompts.js.map +0 -1
- package/dist/core/registry.js +0 -134
- package/dist/core/registry.js.map +0 -1
- package/dist/core/rules.js +0 -17
- package/dist/core/rules.js.map +0 -1
- package/dist/core/scripts.js +0 -48
- package/dist/core/scripts.js.map +0 -1
- package/dist/core/skill-check.js +0 -32
- package/dist/core/skill-check.js.map +0 -1
- package/dist/core/skills.js +0 -62
- package/dist/core/skills.js.map +0 -1
- package/dist/core/state.js +0 -54
- package/dist/core/state.js.map +0 -1
- package/dist/utils/path.js +0 -11
- package/dist/utils/path.js.map +0 -1
- package/dist/utils/shell.js +0 -29
- package/dist/utils/shell.js.map +0 -1
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
| 12 | **Prompt 拆分合理性** | **如触发拆分条件,已按功能闭环拆分,每份 prompt 边界清晰** |
|
|
25
25
|
| 13 | **需求/原型字段对账** | 涉及页面、截图、原型或前端联调时,已建立"页面字段 -> API 字段 -> DTO/VO -> DB -> 测试"映射 |
|
|
26
26
|
| 14 | **功能点串行门禁** | 复杂 PRD、飞书文档、原型图或口头大需求必须具备 `source-ingestion.md`、`feature-gates.md`、`feature-inventory.md`、`ui-contract.md`、`gap-analysis.md`、`spec-freeze-review.md`,且当前功能点状态为 `已冻结` |
|
|
27
|
+
| 14.1 | **源码事实冻结卡** | full workflow 涉及现有行为、DB/表关系、跨仓或真实入口时必须具备 `source-code-audit.md`;覆盖所有写入方、真实入口、current/legacy/unmounted/data-model-only 分类、DB 核查或跳过原因、冲突审计和 owner 边界 |
|
|
27
28
|
|
|
28
29
|
### 按需检查项(涉及则必须检查)
|
|
29
30
|
|
|
@@ -65,6 +66,8 @@
|
|
|
65
66
|
| 47 | **金额精度边界** | **涉及金额、费用、优惠、抵扣、退款、分账、支付、发票、余额、电费、服务费、套餐结算、比例分摊、明细分配、对账或财务展示时强制** | Superpowers 技术详设包含 `Money Precision Boundary` 及金额恒等式、权威总额、独立计算项、差额反推项与公式、计算态来源、中间精度、舍入边界、scale/rounding mode、分配/对账规则、禁止提前舍入点和测试证据;存在加法恒等式且总额是真源时,最后一个组成项必须由权威总额减去其余组成项合计得到,禁止所有组成项分别计算和舍入后重建总额;测试必须覆盖半分、尾差或多明细分配场景 |
|
|
66
67
|
| 48 | **外部集成配置与部署合同** | **涉及第三方平台/工具、SDK、MQ/Kafka、回调、支付渠道、云服务或其他外部集成时强制** | api.md、sdd-quality-gate.md、Superpowers 技术详设和实现 prompt 包含 `外部集成配置与部署合同` / `External Integration Configuration And Deployment Contract`;列出 endpoint、应用/租户/项目 ID、Topic/Tag/Consumer Group、namespace、webhook、ACL/role、开关、超时和凭据引用在本地/测试/生产的来源与创建方式,以及注入方式、运行 owner、创建 owner/时点、就绪证据、回滚、密钥处理和阻塞项;环境相关值不得只硬编码在注解/常量/业务代码;测试自动创建、历史资源或本地启动成功不能证明生产就绪,缺少生产创建证据必须阻塞发布 |
|
|
67
68
|
| 49 | **并发与幂等归属** | **涉及并发、批量下发/开通/续费、重复提交/回调/消费或重复外部调用时强制** | sdd-quality-gate.md、Superpowers 技术详设和实现 prompt 包含 `Concurrency And Idempotency Ownership` / `并发与幂等归属`;明确业务幂等键、应用层原子占用 owner、短事务边界、PENDING/SUCCESS/FAILED 状态流转、重试复用原业务编码、外部调用边界和不确定结果对账;唯一索引不作为默认方案,只能在自然唯一、历史数据、NULL/软删除和冲突处理合同明确后作为可选兜底;测试覆盖并发、重复和重试 |
|
|
69
|
+
| 50 | **复杂度减法评审** | **完整 workflow 的 docs/design 阶段强制** | `design.md` 与 Superpowers 技术详设包含 `复杂度减法评审`,逐项记录现有能力/复用证据、必要性、最简实现、删除/拒绝项和证据/阻塞;统计新增表、字段、API、Service/组件、缓存、异步/MQ/事件、定时任务和兼容层;能扩展现有模块、由字段推导或用单事务同步闭环时不得另建平行实现;`sdd-quality-gate.md` 必须给出 PASS/BLOCKED 结论,只有 PASS/通过才能离开 docs/design,存在无证据抽象或未决更简方案时阻塞 |
|
|
70
|
+
| 51 | **冻结发布 SQL** | **涉及表/字段/索引/约束/初始化数据/历史迁移时强制** | docs 阶段已生成 `release-sql.md`;front matter 含 `database_change: true`、无占位符的精确 `target_sql_path`、`copy_policy: verbatim`、有效 `sql_sha256`;仅有一个完整可执行 SQL 代码块且包含合同要求的前置检查、DDL/DML、迁移和后置验证;design/tasks/quality gate 明确研发 Agent 只能原样复制,发现遗漏退回 docs,禁止 prompt 阶段临场设计 SQL |
|
|
68
71
|
|
|
69
72
|
### 文档完整性强制检查(新增,全部项目必做)
|
|
70
73
|
|
|
@@ -74,12 +77,12 @@
|
|
|
74
77
|
| 27 | **顶层文档同步更新** | 新增/修改 embedded change 后,`tasks.md`、`traceability-matrix.md`、`sdd-quality-gate.md`、`tests.md`、`test-report.md` 已同步更新 |
|
|
75
78
|
| 28 | **implementation prompt 文档引用** | prompt 中"必读文档"列表必须包含 `design.md`、`tests.md`、`review-checklist.md`、`sdd-quality-gate.md`,不能只引用 `api.md` 和 `spec.md` |
|
|
76
79
|
| 29 | **无"待后续生成"占位符** | 文档中不存在"待后续生成"、"待补充"、"TODO"等未完成的占位标记 |
|
|
77
|
-
| 30 |
|
|
80
|
+
| 30 | **需求级冻结发布 SQL** | 如涉及数据库变更,已创建 `release-sql.md` 并冻结目标版本路径和 SHA-256;tasks.md / tests.md / prompt 明确只能原样复制,不能让研发 Agent 追加或改写 |
|
|
78
81
|
| 31 | **tasks.md 标注 SQL 依赖** | 每个涉及数据库的任务已标注依赖的汇总 SQL 文件路径,不需要 SQL 的任务已写明"本任务不新增 SQL,但开始前仍需核查依赖表结构" |
|
|
79
82
|
| 32 | **tests.md 包含数据库结构核查用例** | 测试用例中包含 SHOW CREATE TABLE / SHOW COLUMNS 等数据库结构核查用例 |
|
|
80
83
|
| 33 | **汇总 SQL 格式规范** | SQL 脚本采用简单直接格式(ALTER TABLE / INSERT),不使用 INFORMATION_SCHEMA 判断、PREPARE/EXECUTE 等过度兼容脚本,按任务编号或功能块追加注释 |
|
|
81
84
|
| 34 | **数据库迁移类任务 prompt 强制顺序(阻塞级)** | 涉及表结构重构、旧数据迁移、状态字段变更、分页筛选依赖新表/新状态时:① prompt/pXX-xxx.md 中必须包含"强制执行顺序"章节;② 章节必须覆盖:核对数据库结构 → 执行表结构改造 → 执行旧数据迁移 → 回填 test-report 证据 → 才允许 Java 编码;③ 任一缺失视为文档交付不完整,阻塞进入开发阶段 |
|
|
82
|
-
| 35 | **版本总 SQL 收口对账(阻塞级)** | 每个涉及数据库的 P/CR 任务必须提供 `P编号 | 表 | 字段/索引/数据 | 源码引用 | 总SQL位置 | 开发库状态 | 测试库状态 | 处理结论`
|
|
85
|
+
| 35 | **版本总 SQL 收口对账(阻塞级)** | 每个涉及数据库的 P/CR 任务必须提供 `P编号 | 表 | 字段/索引/数据 | 源码引用 | 总SQL位置 | 开发库状态 | 测试库状态 | 处理结论` 对账表;开发库已有但冻结 SQL 缺失时必须退回 docs 更新 `release-sql.md`、哈希和 handoff,研发 Agent 不得补写;无对账表不得标记完成 |
|
|
83
86
|
| 41 | **跨仓实体字段对账(阻塞级)** | 多仓共享表、复制实体、MyBatis-Plus `@TableName`/`BaseMapper` 时:① 必须提供 `表 | 真源结构 | 消费仓 | 实体/Mapper/SQL 字段 | 实际库字段 | 处理结论 | 验证证据`;② 任一消费仓映射不存在列或查询旧字段时阻塞;③ 不得通过给测试库补废弃字段绕过 |
|
|
84
87
|
| 42 | **真实入口与测试端点分级(阻塞级)** | 涉及外部系统链路时:① test-report 必须分开记录 `Mock 验证`、`测试端点验证`、`真实入口验证`;② 测试 Controller/绕过鉴权端点只能标记局部通过;③ 无真实入口 payload/响应/trace/DB 时,不得写真实链路通过 |
|
|
85
88
|
| 44 | **Red-Green 证据占位(阻塞级)** | test-report.md 必须预置 `RED 失败证据`、`GREEN 通过证据`、`接口自动化证据`、`DB 核查证据`、`日志核查证据`、`未自动化/阻塞用例`;每项绑定 tests.md 用例 ID |
|
|
@@ -140,7 +143,7 @@
|
|
|
140
143
|
- 如果 D2(表结构改造 SQL)执行失败 → **阻塞**,修复 SQL 后重新执行,禁止先写 Java 代码
|
|
141
144
|
- 如果 D3(旧数据迁移 SQL)执行失败或数量核对不一致 → **阻塞**,必须解决迁移问题,禁止用业务代码绕过
|
|
142
145
|
- 如果 D4(迁移证据)缺失 → **阻塞**,明确"不允许进入编码阶段",必须补齐 test-report 证据
|
|
143
|
-
- 如果 D6(版本总 SQL 收口)缺失 →
|
|
146
|
+
- 如果 D6(版本总 SQL 收口)缺失 → **阻塞**,退回 docs 补齐冻结 SQL、哈希和对账表,不能只说开发库已存在
|
|
144
147
|
- D5 只有通过后才能开始 Phase 1(读取文档)之后的编码工作
|
|
145
148
|
|
|
146
149
|
### P0 基线特有加禁
|
|
@@ -270,7 +273,7 @@
|
|
|
270
273
|
- 批次报告中必须包含"数据库前置门禁"章节,写明检查了哪些表/字段/索引/初始化数据。
|
|
271
274
|
- 报告中必须包含汇总 SQL 文件路径、执行的具体脚本、执行结果、复查确认结果。
|
|
272
275
|
- 如果业务代码绕过字段缺失、空 SET、默认值缺失、初始化数据缺失等问题,应优先判断是否是 SQL 未执行导致。
|
|
273
|
-
- 如果根因是 SQL
|
|
276
|
+
- 如果根因是 SQL 未执行,执行冻结 SQL;如果冻结 SQL 有遗漏,退回 docs,不能由研发 Agent 补写或加业务兼容代码。
|
|
274
277
|
- 没有真实数据库结构核查和 SQL 执行证据时,结论必须写"未通过,缺少数据库前置门禁证据"。
|
|
275
278
|
- 检查本需求下是否只维护了一个汇总 SQL 文件,是否存在各任务各自新建的独立 SQL 文件。
|
|
276
279
|
- SQL 脚本是否采用简单直接格式,不存在过度兼容脚本(INFORMATION_SCHEMA 判断、PREPARE/EXECUTE 等)。
|
|
@@ -295,7 +298,7 @@
|
|
|
295
298
|
- {批次/任务}:{缺失的数据库核查/SQL 执行证据} → 处理方式:{fix}
|
|
296
299
|
- {批次/任务}:{发现代码绕过数据库缺失} → 根因判断:{SQL 未执行/设计变更} → 修复方向:{执行 SQL / 改设计}
|
|
297
300
|
- 版本总 SQL 收口缺口:X 项
|
|
298
|
-
- {批次/任务}:{
|
|
301
|
+
- {批次/任务}:{源码引用/开发库字段/测试库状态/冻结 SQL 缺口} → 处理方式:{退回 docs 更新 release-sql / 不采纳并说明}
|
|
299
302
|
- 跨仓数据合同缺口:X 项
|
|
300
303
|
- {表/消费仓}:{实体/Mapper/SQL 引用字段} → 实际库:{缺失/类型不一致/查询条件旧口径} → 处理方式:{修代码 / @TableField(exist=false) / 补最终合同 SQL / 阻塞}
|
|
301
304
|
- 真实入口验收缺口:X 项
|
|
@@ -133,6 +133,13 @@
|
|
|
133
133
|
| 54 | 真实入口日志闭环 | 检查服务日志 | 从入口日志到业务校验、DB 查询、外部调用或异常返回有同一 trace/业务单号串联 |
|
|
134
134
|
| 55 | 泛化失败归因 | 检查外部错误、业务日志和 DB 旁证 | 外部平台泛化失败时未直接写通过;已区分外部阻塞、合同漂移、代码异常 |
|
|
135
135
|
|
|
136
|
+
## 负向控制与资源清理检查
|
|
137
|
+
|
|
138
|
+
| # | 检查项 | 检查方法 | 通过标准 |
|
|
139
|
+
|---|---|---|---|
|
|
140
|
+
| 55.1 | 负向输入是否真实到达 | 对照 `tests.md` 的原始载荷、客户端命令与服务端日志/分支 | 畸形 JSON、错误 Content-Type、越权身份或非法字段以真实线协议注入,并证明命中目标解析/校验分支;不能只因状态码相同而通过 |
|
|
141
|
+
| 55.2 | 任务资源身份闭环 | 对照 owner 记录、资源记录、清理代码与失败用例 | 清理逐项比对 nonce、PID、端口、签名等冻结身份;任一不匹配拒绝清理且有证据。复用认证 helper 时只核对完整性、任务参数、一次失败清理和最终零残留 |
|
|
142
|
+
|
|
136
143
|
## 金额精度检查
|
|
137
144
|
|
|
138
145
|
| # | 检查项 | 检查方法 | 通过标准 |
|
|
@@ -35,6 +35,16 @@ canonical_sources:
|
|
|
35
35
|
| -------------------- | --------------- | ---------------- | ------------------------- | ------------- | ------ |
|
|
36
36
|
| <R1/S1> | `<file>:<line>` | <observed fact> | <implementation approach> | <files> | <risk> |
|
|
37
37
|
|
|
38
|
+
## 复杂度减法评审
|
|
39
|
+
|
|
40
|
+
| 设计项 | 现有能力/复用证据 | 是否必要 | 最简实现 | 删除/拒绝项 | 证据/阻塞 |
|
|
41
|
+
| ------ | ----------------- | -------- | -------- | ----------- | --------- |
|
|
42
|
+
| `<表/API/Service/组件/同步机制>` | `<现有源码/API/表/依赖>` | `保留/删除/阻塞` | `<最小闭环实现>` | `<不新增的平行抽象/缓存/异步/兼容层>` | `<锚点或阻塞>` |
|
|
43
|
+
|
|
44
|
+
新增项统计:表 0;字段 0;API 0;Service/组件 0;缓存 0;MQ/事件 0;定时任务 0;兼容层 0。按实际设计替换数量,不适用时保留 0。优先扩展
|
|
45
|
+
现有模块;可安全推导的状态不重复持久化;单事务同步可闭环时不引入异步、补偿或
|
|
46
|
+
缓存。每个保留项都要说明更简单方案为何不能满足合同,没有证据则删除。
|
|
47
|
+
|
|
38
48
|
## Architecture Boundary And Call Direction
|
|
39
49
|
|
|
40
50
|
Use this whenever the change crosses repositories, services, SDKs, MQ,
|
|
@@ -131,7 +131,7 @@ GUARD="$SCRIPT_DIR/superflow-guard.sh"
|
|
|
131
131
|
VALIDATE="$SCRIPT_DIR/superflow-yaml-validate.sh"
|
|
132
132
|
CHANGE_DIR="$(cd "$CHANGE_DIR" && pwd)"
|
|
133
133
|
CHANGE_NAME="$(basename "$CHANGE_DIR")"
|
|
134
|
-
PROJECT_ROOT="$(cd "$CHANGE_DIR
|
|
134
|
+
PROJECT_ROOT="$(cd "$CHANGE_DIR/../../.." && pwd)"
|
|
135
135
|
ARCHIVE_ROOT="$PROJECT_ROOT/openspec/changes/archive"
|
|
136
136
|
ARCHIVE_NAME="$CHANGE_NAME"
|
|
137
137
|
|
|
@@ -24,6 +24,7 @@ VALIDATE="$SCRIPT_DIR/superflow-yaml-validate.sh"
|
|
|
24
24
|
CHANGE_DIR="${1:-}"
|
|
25
25
|
PHASE="${2:-}"
|
|
26
26
|
MODE="${3:-}"
|
|
27
|
+
CHANGE_DIR_INPUT="${CHANGE_DIR%/}"
|
|
27
28
|
|
|
28
29
|
[[ -n "$CHANGE_DIR" && -n "$PHASE" ]] || {
|
|
29
30
|
usage
|
|
@@ -35,6 +36,25 @@ MODE="${3:-}"
|
|
|
35
36
|
CHANGE_DIR="$(cd "$CHANGE_DIR" && pwd)"
|
|
36
37
|
issues=()
|
|
37
38
|
|
|
39
|
+
require_canonical_change_layout() {
|
|
40
|
+
local suffix
|
|
41
|
+
|
|
42
|
+
if [[ -L "$CHANGE_DIR_INPUT" ]]; then
|
|
43
|
+
issues+=("symlinked OpenSpec change directory is forbidden; keep one physical openspec/changes/<change-name> directory")
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
[[ "$CHANGE_DIR" == */openspec/changes/* ]] || return 0
|
|
47
|
+
suffix="${CHANGE_DIR#*/openspec/changes/}"
|
|
48
|
+
case "$suffix" in
|
|
49
|
+
archive/*|*/embedded-changes/*) return 0 ;;
|
|
50
|
+
esac
|
|
51
|
+
if [[ "$suffix" == */* ]]; then
|
|
52
|
+
issues+=("non-canonical OpenSpec change directory: encode the version in <change-name> and use openspec/changes/<change-name>")
|
|
53
|
+
fi
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
require_canonical_change_layout
|
|
57
|
+
|
|
38
58
|
require_file() {
|
|
39
59
|
local path="$1"
|
|
40
60
|
[[ -f "$CHANGE_DIR/$path" ]] || issues+=("missing file: $path")
|
|
@@ -302,20 +322,106 @@ change_has_field_status_risk() {
|
|
|
302
322
|
"$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
|
|
303
323
|
}
|
|
304
324
|
|
|
305
|
-
|
|
325
|
+
change_has_database_change() {
|
|
326
|
+
if grep -Eiq '^[[:space:]]*database:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
327
|
+
return 1
|
|
328
|
+
fi
|
|
329
|
+
if grep -Eiq '^[[:space:]]*database:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
330
|
+
return 0
|
|
331
|
+
fi
|
|
306
332
|
grep -RIEiq \
|
|
307
|
-
'
|
|
333
|
+
'database_change[[:space:]]*:[[:space:]]*true|数据库变更.{0,8}(是|需要|包含)|ALTER[[:space:]]+TABLE|CREATE[[:space:]]+TABLE|ADD[[:space:]]+(COLUMN|INDEX|KEY|CONSTRAINT)|(^|[^不未无])新增.{0,12}(表|字段|索引|约束)|(^|[^不未无])(历史数据|初始化数据).{0,12}(迁移|回填)|schema[ -]migration|database[ -]migration|add.{0,12}(table|column|index|constraint)' \
|
|
308
334
|
"$CHANGE_DIR/proposal.md" \
|
|
309
335
|
"$CHANGE_DIR/api.md" \
|
|
310
336
|
"$CHANGE_DIR/design.md" \
|
|
311
|
-
"$CHANGE_DIR/
|
|
337
|
+
"$CHANGE_DIR/tasks.md" \
|
|
338
|
+
"$CHANGE_DIR/database-contract.md" \
|
|
312
339
|
"$CHANGE_DIR/spec.md" \
|
|
313
340
|
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
314
341
|
}
|
|
315
342
|
|
|
316
|
-
|
|
343
|
+
require_frozen_release_sql() {
|
|
344
|
+
local release_sql="$CHANGE_DIR/release-sql.md"
|
|
345
|
+
local output
|
|
346
|
+
|
|
347
|
+
require_file release-sql.md
|
|
348
|
+
[[ -f "$release_sql" ]] || return 0
|
|
349
|
+
|
|
350
|
+
output="$(mktemp)"
|
|
351
|
+
if ! python3 - "$release_sql" >"$output" 2>&1 <<'PY'
|
|
352
|
+
import hashlib
|
|
353
|
+
import re
|
|
354
|
+
import sys
|
|
355
|
+
from pathlib import Path
|
|
356
|
+
|
|
357
|
+
path = Path(sys.argv[1])
|
|
358
|
+
text = path.read_text(encoding="utf-8")
|
|
359
|
+
errors = []
|
|
360
|
+
|
|
361
|
+
front_match = re.match(r"\A---\n(.*?)\n---(?:\n|\Z)", text, re.S)
|
|
362
|
+
front = front_match.group(1) if front_match else ""
|
|
363
|
+
if not front_match:
|
|
364
|
+
errors.append("front matter is missing")
|
|
365
|
+
|
|
366
|
+
def field(name):
|
|
367
|
+
match = re.search(rf"(?m)^{re.escape(name)}:\s*(.*?)\s*$", front)
|
|
368
|
+
return match.group(1).strip().strip('"\'') if match else ""
|
|
369
|
+
|
|
370
|
+
if field("database_change").lower() != "true":
|
|
371
|
+
errors.append("database_change must be true")
|
|
372
|
+
|
|
373
|
+
target = field("target_sql_path")
|
|
374
|
+
if not target or not target.lower().endswith(".sql"):
|
|
375
|
+
errors.append("target_sql_path must be an exact .sql path")
|
|
376
|
+
if re.search(r"[<>{}]|testN|version|待定|pending", target, re.I):
|
|
377
|
+
errors.append("target_sql_path contains a placeholder")
|
|
378
|
+
|
|
379
|
+
if field("copy_policy").lower() != "verbatim":
|
|
380
|
+
errors.append("copy_policy must be verbatim")
|
|
381
|
+
|
|
382
|
+
declared_hash = field("sql_sha256").lower()
|
|
383
|
+
if not re.fullmatch(r"[0-9a-f]{64}", declared_hash):
|
|
384
|
+
errors.append("sql_sha256 must be a 64-character lowercase SHA-256")
|
|
385
|
+
|
|
386
|
+
blocks = re.findall(r"```sql[^\n]*\n(.*?)\n```", text, re.S | re.I)
|
|
387
|
+
if len(blocks) != 1:
|
|
388
|
+
errors.append("release-sql.md must contain exactly one sql code block")
|
|
389
|
+
else:
|
|
390
|
+
payload = blocks[0].replace("\r\n", "\n").replace("\r", "\n").rstrip("\n") + "\n"
|
|
391
|
+
actual_hash = hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
|
392
|
+
if declared_hash and actual_hash != declared_hash:
|
|
393
|
+
errors.append(
|
|
394
|
+
f"sql_sha256 mismatch: declared={declared_hash} actual={actual_hash}"
|
|
395
|
+
)
|
|
396
|
+
executable = re.sub(r"/\*.*?\*/|--[^\n]*", "", payload, flags=re.S)
|
|
397
|
+
if not re.search(
|
|
398
|
+
r"\b(CREATE|ALTER|DROP|INSERT|UPDATE|DELETE|MERGE|TRUNCATE|CALL)\b",
|
|
399
|
+
executable,
|
|
400
|
+
re.I,
|
|
401
|
+
):
|
|
402
|
+
errors.append("sql block has no executable schema/data change statement")
|
|
403
|
+
if not re.search(r"\b(SELECT|SHOW|CALL)\b", executable, re.I):
|
|
404
|
+
errors.append("sql block has no executable verification statement")
|
|
405
|
+
|
|
406
|
+
if errors:
|
|
407
|
+
print("; ".join(errors))
|
|
408
|
+
sys.exit(1)
|
|
409
|
+
PY
|
|
410
|
+
then
|
|
411
|
+
issues+=("frozen release SQL invalid: $(tr '\n' ' ' < "$output" | sed -E 's/[[:space:]]+/ /g')")
|
|
412
|
+
fi
|
|
413
|
+
rm -f "$output"
|
|
414
|
+
|
|
415
|
+
require_grep 'release-sql\.md' design.md "frozen release SQL design reference"
|
|
416
|
+
require_grep 'release-sql\.md' tasks.md "frozen release SQL task reference"
|
|
417
|
+
require_grep 'release-sql\.md' sdd-quality-gate.md "frozen release SQL quality-gate reference"
|
|
418
|
+
require_grep '原样复制|verbatim' tasks.md "verbatim SQL copy task"
|
|
419
|
+
require_grep '原样复制|verbatim' sdd-quality-gate.md "verbatim SQL copy quality gate"
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
change_has_external_enum_risk() {
|
|
317
423
|
grep -RIEiq \
|
|
318
|
-
'
|
|
424
|
+
'BEM|payOrigin|payMode|支付来源|支付方式|财务口径|第三方枚举|第三方字段|third[- ]party enum|source system|SDK.*枚举|枚举.*SDK' \
|
|
319
425
|
"$CHANGE_DIR/proposal.md" \
|
|
320
426
|
"$CHANGE_DIR/api.md" \
|
|
321
427
|
"$CHANGE_DIR/design.md" \
|
|
@@ -324,7 +430,45 @@ change_has_external_config_risk() {
|
|
|
324
430
|
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
325
431
|
}
|
|
326
432
|
|
|
433
|
+
change_contract_docs_without_complexity_budget() {
|
|
434
|
+
local path
|
|
435
|
+
for path in proposal.md api.md design.md tests.md spec.md; do
|
|
436
|
+
[[ -f "$CHANGE_DIR/$path" ]] || continue
|
|
437
|
+
sed -E '/新增项统计|复杂度预算|New-item counts|Complexity budget/d' \
|
|
438
|
+
"$CHANGE_DIR/$path"
|
|
439
|
+
done
|
|
440
|
+
if [[ -d "$CHANGE_DIR/specs" ]]; then
|
|
441
|
+
find "$CHANGE_DIR/specs" -path '*/spec.md' -type f \
|
|
442
|
+
-exec sed -E '/新增项统计|复杂度预算|New-item counts|Complexity budget/d' {} +
|
|
443
|
+
fi
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
change_all_docs_without_complexity_budget() {
|
|
447
|
+
find "$CHANGE_DIR" -maxdepth 2 -name '*.md' -type f \
|
|
448
|
+
-exec sed -E '/新增项统计|复杂度预算|New-item counts|Complexity budget/d' {} +
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
change_has_external_config_risk() {
|
|
452
|
+
if grep -Eiq '^[[:space:]]*external_config:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
453
|
+
return 1
|
|
454
|
+
fi
|
|
455
|
+
if grep -Eiq '^[[:space:]]*external_config:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
456
|
+
return 0
|
|
457
|
+
fi
|
|
458
|
+
local content
|
|
459
|
+
content="$(change_contract_docs_without_complexity_budget)"
|
|
460
|
+
grep -Eiq \
|
|
461
|
+
'第三方|外部平台|外部工具|外部集成|third[- ]party|external (platform|tool|integration|system)|SDK|MQ|Kafka|RocketMQ|TDMQ|callback|回调|webhook|支付渠道|payment gateway|cloud service|云服务' \
|
|
462
|
+
<<< "$content"
|
|
463
|
+
}
|
|
464
|
+
|
|
327
465
|
change_has_concurrency_idempotency_risk() {
|
|
466
|
+
if grep -Eiq '^[[:space:]]*concurrency:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
467
|
+
return 1
|
|
468
|
+
fi
|
|
469
|
+
if grep -Eiq '^[[:space:]]*concurrency:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
470
|
+
return 0
|
|
471
|
+
fi
|
|
328
472
|
grep -RIEiq \
|
|
329
473
|
'并发|批量下发|批量开通|批量续费|重复提交|重复回调|重复消费|重复下发|幂等|竞态|原子占用|concurren|idempoten|race condition|duplicate (request|callback|consumption|delivery)|atomic claim' \
|
|
330
474
|
"$CHANGE_DIR/proposal.md" \
|
|
@@ -336,6 +480,12 @@ change_has_concurrency_idempotency_risk() {
|
|
|
336
480
|
}
|
|
337
481
|
|
|
338
482
|
change_has_money_precision_risk() {
|
|
483
|
+
if grep -Eiq '^[[:space:]]*money:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
484
|
+
return 1
|
|
485
|
+
fi
|
|
486
|
+
if grep -Eiq '^[[:space:]]*money:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
487
|
+
return 0
|
|
488
|
+
fi
|
|
339
489
|
grep -RIEiq \
|
|
340
490
|
'金额|费用|价格|优惠|折扣|抵扣|退款|分账|支付|发票|余额|电费|服务费|套餐结算|比例分摊|明细分配|尾差|精度|舍入|(^|[^[:alnum:]_])(amount|fee|fees|price|discount|deduction|refund|payment|invoice|balance|proration|allocation|reconciliation|rounding)([^[:alnum:]_]|$)|revenue sharing|profit sharing|split payment|serviceFee|chargeFee|totalAmount|actualAmount|payAmount|refundAmount|discountAmount|invoiceAmount|balanceAmount' \
|
|
341
491
|
"$CHANGE_DIR/proposal.md" \
|
|
@@ -346,6 +496,53 @@ change_has_money_precision_risk() {
|
|
|
346
496
|
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
347
497
|
}
|
|
348
498
|
|
|
499
|
+
change_has_source_fact_risk() {
|
|
500
|
+
grep -RIEiq \
|
|
501
|
+
'现有|现行|遗留|数据库|数据表|表关系|Mapper|XML|跨仓|跨服务|真实入口|小程序|H5|existing|current behavior|legacy|database|table relationship|cross[- ](repo|service)|crosses services|real entry|mini[- ]program' \
|
|
502
|
+
"$CHANGE_DIR/proposal.md" \
|
|
503
|
+
"$CHANGE_DIR/api.md" \
|
|
504
|
+
"$CHANGE_DIR/design.md" \
|
|
505
|
+
"$CHANGE_DIR/tests.md" \
|
|
506
|
+
"$CHANGE_DIR/spec.md" \
|
|
507
|
+
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
change_has_cardinality_conflict_signal() {
|
|
511
|
+
grep -RIEiq \
|
|
512
|
+
'List[<((]|orderIds|batchInsert|批量插入|一对多|one[- ]to[- ]many|关系表' \
|
|
513
|
+
"$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
require_source_fact_audit() {
|
|
517
|
+
require_file source-code-audit.md
|
|
518
|
+
require_grep '源码事实冻结卡|Source Fact Freeze Card' source-code-audit.md "source fact freeze card"
|
|
519
|
+
require_grep '业务结论|Business conclusion' source-code-audit.md "source fact business conclusion"
|
|
520
|
+
require_grep 'understand.*定位|understand.*locator' source-code-audit.md "understand-anything locator evidence"
|
|
521
|
+
require_grep '数据模型|Data model' source-code-audit.md "source fact data model"
|
|
522
|
+
require_grep '所有写入方|All writers' source-code-audit.md "all writers inventory"
|
|
523
|
+
require_grep '真实用户入口|Real user entr' source-code-audit.md "real user entry"
|
|
524
|
+
require_grep '当前调用方|Current callers' source-code-audit.md "current callers"
|
|
525
|
+
require_grep '遗留冲突|Legacy conflict' source-code-audit.md "legacy conflict"
|
|
526
|
+
require_grep 'DB.*(必查|核查|跳过|未执行|reason)|数据库.*(必查|核查|跳过|未执行|原因)|DB (check|required|skip|reason)' source-code-audit.md "DB check or skip reason"
|
|
527
|
+
require_grep '结论等级|Conclusion level' source-code-audit.md "conclusion level"
|
|
528
|
+
require_grep 'owner.*(决策|decision)|决策.*owner' source-code-audit.md "owner decision boundary"
|
|
529
|
+
require_grep 'current|现行入口' source-code-audit.md "current evidence classification"
|
|
530
|
+
require_grep 'legacy|遗留入口' source-code-audit.md "legacy evidence classification"
|
|
531
|
+
require_grep 'unmounted|无前端调用' source-code-audit.md "unmounted evidence classification"
|
|
532
|
+
require_grep 'data-model-only|仅数据模型可表达' source-code-audit.md "data-model-only evidence classification"
|
|
533
|
+
require_grep 'owner-confirmed|owner 已确认' source-code-audit.md "owner-confirmed evidence classification"
|
|
534
|
+
require_grep 'blocked|阻塞' source-code-audit.md "blocked evidence classification"
|
|
535
|
+
require_grep '(证据分类|Evidence classifications).*(current|现行).*(legacy|遗留).*(unmounted|无前端调用).*(data-model-only|仅数据模型可表达).*(owner-confirmed|owner 已确认).*(blocked|阻塞)' source-code-audit.md "complete evidence classification set"
|
|
536
|
+
require_grep '提问资格门禁|Question Eligibility Gate' source-code-audit.md "question eligibility gate"
|
|
537
|
+
require_grep '源码检索|Source search' source-code-audit.md "source search evidence"
|
|
538
|
+
require_grep 'Mapper.*SQL|SQL.*Mapper' source-code-audit.md "Mapper and SQL search evidence"
|
|
539
|
+
require_grep '前端.*小程序.*H5|Frontend.*mini[- ]program.*H5' source-code-audit.md "frontend mini-program H5 caller search"
|
|
540
|
+
require_grep 'sibling.*repo|兄弟仓|关联仓' source-code-audit.md "sibling repository search"
|
|
541
|
+
if change_has_cardinality_conflict_signal; then
|
|
542
|
+
require_grep '冲突审计|Conflict Audit' source-code-audit.md "cardinality conflict audit"
|
|
543
|
+
fi
|
|
544
|
+
}
|
|
545
|
+
|
|
349
546
|
change_has_fx_precision_risk() {
|
|
350
547
|
grep -RIEiq \
|
|
351
548
|
'汇率|换汇|外汇|币种转换|跨币种|兑换率|(^|[^[:alnum:]_])(exchange rate|fx rate|currency conversion|cross.currency|base currency|quote currency)([^[:alnum:]_]|$)' \
|
|
@@ -358,13 +555,17 @@ change_has_fx_precision_risk() {
|
|
|
358
555
|
}
|
|
359
556
|
|
|
360
557
|
change_has_architecture_boundary_risk() {
|
|
361
|
-
|
|
558
|
+
local content
|
|
559
|
+
content="$(change_all_docs_without_complexity_budget)"
|
|
560
|
+
grep -Eiq \
|
|
362
561
|
'跨仓|跨服务|sibling|SDK|MQ|topic|consumer|scheduler|定时|device|设备|callback|回调|third[- ]party|第三方|mini[- ]program|小程序|gateway|网关|adapter|适配|protocol|协议|interconnect|互联互通|调用链|入口|出口' \
|
|
363
|
-
|
|
562
|
+
<<< "$content"
|
|
364
563
|
}
|
|
365
564
|
|
|
366
|
-
|
|
367
|
-
find "$CHANGE_DIR" -path '*/prompt/*.md' -type f
|
|
565
|
+
prompt_rels() {
|
|
566
|
+
find "$CHANGE_DIR" -path '*/prompt/*.md' -type f -print \
|
|
567
|
+
| LC_ALL=C sort \
|
|
568
|
+
| sed "s#^$CHANGE_DIR/##"
|
|
368
569
|
}
|
|
369
570
|
|
|
370
571
|
require_any_prompt() {
|
|
@@ -374,7 +575,7 @@ require_any_prompt() {
|
|
|
374
575
|
}
|
|
375
576
|
|
|
376
577
|
require_prompt_set() {
|
|
377
|
-
local task_count prompt_count non_index_prompt_count
|
|
578
|
+
local task_count prompt_count non_index_prompt_count prompt_rel document
|
|
378
579
|
require_file prompt/implementation.md
|
|
379
580
|
task_count="$(grep -E '^[[:space:]]*-[[:space:]]+\[[ xX]\]' "$CHANGE_DIR/tasks.md" 2>/dev/null | wc -l | tr -d ' ')"
|
|
380
581
|
prompt_count="$(find "$CHANGE_DIR/prompt" -maxdepth 1 -type f -name '*.md' 2>/dev/null | wc -l | tr -d ' ')"
|
|
@@ -385,9 +586,15 @@ require_prompt_set() {
|
|
|
385
586
|
if [[ "$prompt_count" -eq 0 ]]; then
|
|
386
587
|
issues+=("missing prompt/*.md files")
|
|
387
588
|
fi
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
589
|
+
for document in tasks.md traceability-matrix.md sdd-quality-gate.md test-report.md; do
|
|
590
|
+
[[ -f "$CHANGE_DIR/$document" ]] || continue
|
|
591
|
+
while IFS= read -r prompt_rel; do
|
|
592
|
+
if ! grep -Fq "]($prompt_rel)" "$CHANGE_DIR/$document" \
|
|
593
|
+
&& ! grep -Fq "](./$prompt_rel)" "$CHANGE_DIR/$document"; then
|
|
594
|
+
issues+=("$document does not link $prompt_rel")
|
|
595
|
+
fi
|
|
596
|
+
done < <(prompt_rels)
|
|
597
|
+
done
|
|
391
598
|
}
|
|
392
599
|
|
|
393
600
|
require_external_enum_contract() {
|
|
@@ -482,6 +689,29 @@ require_money_precision_evidence() {
|
|
|
482
689
|
fi
|
|
483
690
|
}
|
|
484
691
|
|
|
692
|
+
require_minimal_design_review() {
|
|
693
|
+
local path="$1"
|
|
694
|
+
local label="$2"
|
|
695
|
+
require_grep '复杂度减法评审|反过度设计评审|Minimal Design Review|Complexity Reduction Review' "$path" "$label"
|
|
696
|
+
require_grep '复用|reuse|existing capability|existing module' "$path" "$label reuse evidence"
|
|
697
|
+
require_grep '最简|最小实现|simplest|minimum design|minimal implementation' "$path" "$label simplest implementation"
|
|
698
|
+
require_grep '删除|拒绝|不新增|移出范围|removed|rejected|do not add|out of scope' "$path" "$label removed or rejected complexity"
|
|
699
|
+
require_grep '新增项统计|复杂度预算|New-item counts|Complexity budget' "$path" "$label complexity budget"
|
|
700
|
+
require_grep '表|table' "$path" "$label table count"
|
|
701
|
+
require_grep '字段|field' "$path" "$label field count"
|
|
702
|
+
require_grep 'API' "$path" "$label API count"
|
|
703
|
+
require_grep 'Service|服务|组件|service|component' "$path" "$label service/component count"
|
|
704
|
+
require_grep '缓存|cache' "$path" "$label cache count"
|
|
705
|
+
require_grep 'MQ|事件|异步|event|async' "$path" "$label async/event count"
|
|
706
|
+
require_grep '定时任务|scheduled job|scheduler' "$path" "$label scheduled-job count"
|
|
707
|
+
require_grep '兼容层|compatibility layer' "$path" "$label compatibility-layer count"
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
require_minimal_design_pass() {
|
|
711
|
+
local path="$1"
|
|
712
|
+
require_grep '(复杂度减法评审|反过度设计评审|Minimal Design Review|Complexity Reduction Review).*(PASS|通过)|(PASS|通过).*(复杂度减法评审|反过度设计评审|Minimal Design Review|Complexity Reduction Review)' "$path" "complexity reduction review PASS verdict"
|
|
713
|
+
}
|
|
714
|
+
|
|
485
715
|
transition_event=""
|
|
486
716
|
|
|
487
717
|
if [[ -x "$VALIDATE" && -f "$CHANGE_DIR/.sdd/state.yaml" ]]; then
|
|
@@ -511,6 +741,28 @@ case "$PHASE" in
|
|
|
511
741
|
require_grep 'RED|红绿|GREEN' tests.md "RED/GREEN test contract"
|
|
512
742
|
require_grep 'curl|Postman|Newman|pytest|RestAssured|自动化命令' tests.md "interface automation command"
|
|
513
743
|
require_grep 'handoff_hash|sdd-context|上下文包|防漂移' sdd-quality-gate.md "handoff/context-drift gate"
|
|
744
|
+
if change_has_database_change; then
|
|
745
|
+
require_frozen_release_sql
|
|
746
|
+
fi
|
|
747
|
+
workflow="$(state_get workflow)"
|
|
748
|
+
if [[ "$workflow" == "full" ]]; then
|
|
749
|
+
require_file requirement-review.md
|
|
750
|
+
require_grep '^review_verdict:[[:space:]]*PASS[[:space:]]*$' requirement-review.md "requirement reverse review PASS verdict"
|
|
751
|
+
require_grep '^implementation_readiness:[[:space:]]*READY[[:space:]]*$' requirement-review.md "requirement review implementation readiness"
|
|
752
|
+
require_grep '^open_blockers:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement reverse review has no open blockers"
|
|
753
|
+
require_grep '^open_external_contracts:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement review has no open external contracts"
|
|
754
|
+
require_grep '^open_source_investigations:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement review has no open source investigations"
|
|
755
|
+
require_grep '^open_owner_decisions:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement review has no open owner decisions"
|
|
756
|
+
require_grep '闭环矩阵|Closure Matrix' requirement-review.md "requirement review closure matrix"
|
|
757
|
+
require_grep '评审发现|Review Findings' requirement-review.md "requirement review findings"
|
|
758
|
+
require_grep '未关闭阻塞项|Open Blockers' requirement-review.md "requirement review open blocker ledger"
|
|
759
|
+
require_minimal_design_review design.md "complexity reduction review"
|
|
760
|
+
require_grep '复杂度减法评审|反过度设计评审|Minimal Design Review|Complexity Reduction Review' sdd-quality-gate.md "complexity reduction quality gate"
|
|
761
|
+
require_minimal_design_pass sdd-quality-gate.md
|
|
762
|
+
if change_has_source_fact_risk; then
|
|
763
|
+
require_source_fact_audit
|
|
764
|
+
fi
|
|
765
|
+
fi
|
|
514
766
|
if change_has_external_enum_risk; then
|
|
515
767
|
require_external_enum_contract api.md "external enum binding contract"
|
|
516
768
|
require_external_enum_contract sdd-quality-gate.md "external enum binding quality gate"
|
|
@@ -544,8 +796,14 @@ case "$PHASE" in
|
|
|
544
796
|
require_handoff_current
|
|
545
797
|
require_beta_handoff_structure
|
|
546
798
|
require_hash_recorded
|
|
799
|
+
if change_has_database_change; then
|
|
800
|
+
require_frozen_release_sql
|
|
801
|
+
fi
|
|
547
802
|
workflow="$(state_get workflow)"
|
|
548
803
|
if [[ "$workflow" == "full" ]]; then
|
|
804
|
+
require_minimal_design_review design.md "complexity reduction review"
|
|
805
|
+
require_grep '复杂度减法评审|反过度设计评审|Minimal Design Review|Complexity Reduction Review' sdd-quality-gate.md "complexity reduction quality gate"
|
|
806
|
+
require_minimal_design_pass sdd-quality-gate.md
|
|
549
807
|
require_optional_state_path technical_design "technical_design"
|
|
550
808
|
technical_design_rel="$(state_get technical_design)"
|
|
551
809
|
if [[ -n "${technical_design_rel:-}" && "$technical_design_rel" != "null" ]]; then
|
|
@@ -569,6 +827,7 @@ case "$PHASE" in
|
|
|
569
827
|
if change_has_money_precision_risk; then
|
|
570
828
|
require_money_precision_contract "$technical_design_rel" "money precision boundary"
|
|
571
829
|
fi
|
|
830
|
+
require_minimal_design_review "$technical_design_rel" "technical design minimal design review"
|
|
572
831
|
fi
|
|
573
832
|
fi
|
|
574
833
|
require_grep 'Superpowers Technical Design Handoff|Superpower 技术详设|technical_design|源码级 HOW' design.md "Superpowers technical design handoff"
|
|
@@ -582,11 +841,14 @@ case "$PHASE" in
|
|
|
582
841
|
require_handoff_current
|
|
583
842
|
require_beta_handoff_structure
|
|
584
843
|
require_hash_recorded
|
|
844
|
+
if change_has_database_change; then
|
|
845
|
+
require_frozen_release_sql
|
|
846
|
+
fi
|
|
585
847
|
require_any_prompt
|
|
586
848
|
require_prompt_set
|
|
587
849
|
require_grep 'OpenSpec/SDD|设计事实源|canonical|事实源' design.md "canonical source boundary"
|
|
588
|
-
prompt_rel
|
|
589
|
-
|
|
850
|
+
while IFS= read -r prompt_rel; do
|
|
851
|
+
[[ -n "${prompt_rel:-}" ]] || continue
|
|
590
852
|
require_grep 'Superpower 技术详设继承|Superpower 执行策略继承|technical_design|源码级 HOW' "$prompt_rel" "prompt Superpower strategy inheritance"
|
|
591
853
|
technical_design_rel="$(state_get technical_design)"
|
|
592
854
|
if [[ -n "${technical_design_rel:-}" && "$technical_design_rel" != "null" ]]; then
|
|
@@ -608,7 +870,11 @@ case "$PHASE" in
|
|
|
608
870
|
fi
|
|
609
871
|
fi
|
|
610
872
|
require_grep '上下文防漂移|handoff_hash|sdd-context' "$prompt_rel" "prompt context drift inheritance"
|
|
611
|
-
|
|
873
|
+
if change_has_database_change; then
|
|
874
|
+
require_grep 'release-sql\.md' "$prompt_rel" "prompt frozen release SQL reference"
|
|
875
|
+
require_grep '原样复制|verbatim|sql_sha256' "$prompt_rel" "prompt verbatim SQL copy contract"
|
|
876
|
+
fi
|
|
877
|
+
done < <(prompt_rels)
|
|
612
878
|
require_state_value build_mode "build_mode"
|
|
613
879
|
require_state_value isolation "isolation"
|
|
614
880
|
require_state_value tdd_mode "tdd_mode"
|
|
@@ -244,10 +244,13 @@ sync_state() {
|
|
|
244
244
|
"$state_sh" set "$CHANGE_DIR" context_compression "$context_compression"
|
|
245
245
|
"$state_sh" set "$CHANGE_DIR" handoff_context .sdd/handoff/sdd-context.json
|
|
246
246
|
"$state_sh" set "$CHANGE_DIR" handoff_hash "$context_hash"
|
|
247
|
-
technical_design_rel="
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
technical_design_rel=""
|
|
248
|
+
if [[ -d "$CHANGE_DIR/docs/superpowers/specs" ]]; then
|
|
249
|
+
technical_design_rel="$(
|
|
250
|
+
find "$CHANGE_DIR/docs/superpowers/specs" -maxdepth 1 -type f -name '*.md' \
|
|
251
|
+
| sort | head -n 1 | sed "s#^$CHANGE_DIR/##"
|
|
252
|
+
)"
|
|
253
|
+
fi
|
|
251
254
|
if [[ -n "$technical_design_rel" ]]; then
|
|
252
255
|
"$state_sh" set "$CHANGE_DIR" technical_design "$technical_design_rel"
|
|
253
256
|
fi
|