commit bb35e661b20b3048b724cebcecf275ebd42896a8 Author: octopus Date: Tue Sep 15 08:41:51 2026 +0800 Initial publish v0.1.0: standalone workflow core (corpus + examples + guards) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..30fec18 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Octopus Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..eac17c4 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# octopus-workflow + +Standalone workflow core extracted from the [octopus](https://eightarms.net/Octopus/octopus) +agent platform: a **provider-neutral corpus** of agent workflow skills, rules, +checklists, templates, and JSON schemas, plus the **drift guards** that keep +the corpus internally consistent and publish-ready. + +The corpus does not assume any specific forge (GitHub / Gitea / GitLab), +ticketing, or CI system. System-specific behavior lives behind an explicit +adapter contract (`core/adapters/`), so the same core can be adopted by any +octopus instance — or any other agent platform — with its own adapters. + +## Layout + +| Path | Contents | +|---|---| +| `core/skills/` | 17 workflow skills (analyze-dag, implement, review-code, verify, release, ...) | +| `core/rules/` | Behavioral rule corpus (claim discipline, compaction, routing, artifact addressing, ...) | +| `core/checklists/` | Per-stage checklists consumed by the skills | +| `core/templates/` | Artifact templates (DAG, iteration docs) | +| `core/schemas/` | JSON schemas under the public namespace `https://eightarms.net/octopus-workflow/schemas/` | +| `core/adapters/` | Adapter contract: terminology SSOT + Gitea reference implementation | +| `core/CORE-MANIFEST.json` | Registry of core↔instance mappings and sync semantics (verbatim / verbatimDir / rewritten / split / core-only) | +| `examples/` | Organization-agnostic narrative essays referencing the core | +| `guards/` | Standalone drift guards (bun + node stdlib only) | + +## Guards + +Runnable inside this repo with [bun](https://bun.sh), no install step needed: + +```bash +bun run check:core-cohesion # corpus structural invariants +bun run check:core-p1 # publish-readiness neutrality (no org-internal links) +bun run delink:core -- --check # no replaceable org-internal refs remain +``` + +The instance-side guards (`check-core-parity`, `check-schema-ids`, +`check-dangling-refs`, `core-sync.sh`) compare this corpus against a +consuming instance's `.octopus/` tree and live in the octopus platform +repo, not here. + +## Versioning & compatibility + +See [core/COMPATIBILITY.md](core/COMPATIBILITY.md) for the compatibility +matrix between core versions and consuming instances, and +[core/MIGRATION.md](core/MIGRATION.md) for adoption batches. + +## License + +[MIT](LICENSE) diff --git a/core/COMPATIBILITY.md b/core/COMPATIBILITY.md new file mode 100644 index 0000000..c50349b --- /dev/null +++ b/core/COMPATIBILITY.md @@ -0,0 +1,41 @@ +# 兼容矩阵(COMPATIBILITY) + +Core 与 octopus 实例(dogfood)之间的兼容性契约。随各 Increment 更新; +自首个 semver 发布起,本表挂接 changelog(发布仓 `CHANGELOG.md` 的 +条目以本表的行作为兼容性依据)。 + +## core 版本 × octopus 版本 + +| core 版本 | 对应 octopus 侧状态 | 兼容说明 | +| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0.x(Increment 1–4:骨架 + G0–G4 全量迁移) | octopus 实例 `.octopus/` 为消费镜像;core 与 dogfood 内容逐字/改写对齐 | core 是 SSOT 权威副本;dogfood 经 `script/core-sync.sh` 单向同步。schema 尚未迁入 core。 | +| 0.x(Increment 5:schema $id 迁移四件套) | dogfood `.octopus/schemas/*.json` 的 `$id` **保持旧命名空间不动**(活系统仍引用);core 侧 `$id` 已迁至 `https://eightarms.net/octopus-workflow/schemas/` | 双轨期:core schema 与 dogfood schema 是**不同 $id 的两份文件**(manifest 登记为 `rewritten`,不逐字同步)。活归档 run 的 index.json 携带旧 $id,读取侧经别名表解析。 | +| 1.0.0(首个 semver 发布,规划中) | 发布仓创建;live 迁移(dogfood 侧切新命名空间)完成 | `id-aliases.json` 置 `frozen: true`——$id 一经发布不可变(v3 §G)。别名保留 ≥2 个 major 版本。 | + +## builtin overlay 语料兼容 + +- 自 Increment 6b 起,builtin overlay(`builtin-data.gen.ts`)内嵌 + **中立版语料**(源权威 = `core/`);旧版内嵌本组织实例表述(含组织 + 工单号活链接与实例 token)。overlay 仅在实例磁盘无 `/` + 目录时生效——已初始化实例(含本组织 dogfood)运行时行为不变。 + +## $id 行(schema 命名空间兼容) + +- 旧命名空间 `$id`(历史形态 `https://eightarms.net/{legacy-owner}/octopus/.octopus/schemas/*.schema.json`) + 经 `core/schemas/id-aliases.json` 解析到新命名空间 + (`https://eightarms.net/octopus-workflow/schemas/*.schema.json`)。 +- **别名保留期 ≥2 个 major 版本**:自 frozen 起至少两个 major 版本内, + 旧 `$id` 仍被接受(`runs-index.schema.json` 的 `artifacts[].schema` + 字段声明该历史接受集)。 +- **twin token 归一记录**:scaffold-template 侧 schema `$id` 的 owner + token(旧命名空间 owner → Octopus)差异经 `normalizeSchemaOwnerToken` + (`script/check-scaffold-parity.ts`)归一化比较,双向等价;Increment 5 + 已将残留旧 owner token 的 6 份模板 schema 统一为 Octopus token(纯 + 一致性清理,归一化语义不变)。 + +## 后续 semver changelog 挂钩 + +- 首个 semver 发布(1.0.0)起,任何影响本表行的变更($id 变更、别名 + 增删、兼容语义调整)必须在发布仓 changelog 中登记,并同步更新本表。 +- 别名表 `frozen: true` 后新增别名视为 minor 变更;删除别名须满足 + 「≥2 个 major 版本保留期」并视为 major 变更。 diff --git a/core/CORE-MANIFEST.json b/core/CORE-MANIFEST.json new file mode 100644 index 0000000..a517ac0 --- /dev/null +++ b/core/CORE-MANIFEST.json @@ -0,0 +1,431 @@ +{ + "version": 1, + "mappings": [ + { + "core": "core/rules/claim-discipline.md", + "dogfood": ".octopus/rules/claim-discipline.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/rules/stash-discipline.md", + "dogfood": ".octopus/rules/stash-discipline.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/rules/code-graph.md", + "dogfood": ".octopus/rules/code-graph.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/rules/compact.md", + "dogfood": ".octopus/rules/compact.md", + "batch": "G1", + "sync": "rewritten" + }, + { + "core": "core/rules/workflow-routing.md", + "dogfood": ".octopus/rules/workflow-routing.md", + "batch": "G1", + "sync": "rewritten" + }, + { + "core": "core/rules/auto-approve.md", + "dogfood": ".octopus/rules/auto-approve.md", + "batch": "G1", + "sync": "rewritten" + }, + { + "core": "core/rules/two-tier-artifacts.md", + "dogfood": ".octopus/rules/two-tier-artifacts.md", + "batch": "G1", + "sync": "rewritten" + }, + { + "core": "core/rules/ticket-lifecycle.md", + "dogfood": ".octopus/rules/ticket-lifecycle.md", + "batch": "G1", + "sync": "rewritten" + }, + { + "core": "core/rules/testing.md", + "dogfood": ".octopus/rules/testing.md", + "batch": "G1", + "sync": "rewritten" + }, + { + "core": "core/rules/artifact-addressing.md", + "dogfood": null, + "batch": "G2", + "sync": "core-only" + }, + { + "core": "core/adapters/gitea/patterns.md", + "dogfood": ".octopus/skills/_shared/gitea-write-patterns.md", + "batch": "G2", + "sync": "split" + }, + { + "core": "core/adapters/gitea/reading.md", + "dogfood": ".octopus/skills/_shared/gitea-read-patterns.md", + "batch": "G2", + "sync": "split" + }, + { + "core": "core/rules/issue-checklist-sync.md", + "dogfood": ".octopus/rules/issue-checklist-sync.md", + "batch": "G3", + "sync": "rewritten" + }, + { + "core": "core/rules/issue-cross-linking.md", + "dogfood": ".octopus/rules/issue-cross-linking.md", + "batch": "G3", + "sync": "rewritten" + }, + { + "core": "core/rules/artifact-index-guards.md", + "dogfood": ".octopus/rules/artifact-index-guards.md", + "batch": "G3", + "sync": "rewritten" + }, + { + "core": "core/rules/type-checking.md", + "dogfood": ".octopus/rules/type-checking.md", + "batch": "G3", + "sync": "rewritten" + }, + { + "core": "core/rules/session-scope-guard.md", + "dogfood": ".octopus/rules/session-scope-guard.md", + "batch": "G3", + "sync": "rewritten" + }, + { + "core": "core/skills/analyze-dag/", + "dogfood": ".octopus/skills/analyze-dag/", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/browser-debug/", + "dogfood": ".octopus/skills/browser-debug/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/codegraph-setup/", + "dogfood": ".octopus/skills/codegraph-setup/", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/frontend/", + "dogfood": ".octopus/skills/frontend/", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/gitea-rest/", + "dogfood": ".octopus/skills/gitea-rest/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/headless-session-ops/", + "dogfood": ".octopus/skills/headless-session-ops/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/image-interpret/", + "dogfood": ".octopus/skills/image-interpret/", + "batch": "G4", + "sync": "verbatimDir" + }, + { + "core": "core/skills/implement/", + "dogfood": ".octopus/skills/implement/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/land-batch/", + "dogfood": ".octopus/skills/land-batch/", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/project-kickoff/", + "dogfood": ".octopus/skills/project-kickoff/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/prototype/", + "dogfood": ".octopus/skills/prototype/", + "batch": "G4", + "sync": "verbatimDir" + }, + { + "core": "core/skills/release/", + "dogfood": ".octopus/skills/release/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/retrospective/", + "dogfood": ".octopus/skills/retrospective/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/review-artifact/", + "dogfood": ".octopus/skills/review-artifact/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/review-code/", + "dogfood": ".octopus/skills/review-code/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/verify/", + "dogfood": ".octopus/skills/verify/", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/writing-skills/", + "dogfood": ".octopus/skills/writing-skills/", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/compaction-round-boundary.md", + "dogfood": ".octopus/skills/_shared/compaction-round-boundary.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/large-prompts.md", + "dogfood": ".octopus/skills/_shared/large-prompts.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/review-final-report-template.md", + "dogfood": ".octopus/skills/_shared/review-final-report-template.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/review-orchestrator-rules.md", + "dogfood": ".octopus/skills/_shared/review-orchestrator-rules.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/review-pipeline-phases.md", + "dogfood": ".octopus/skills/_shared/review-pipeline-phases.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/review-reviewer-prompt.md", + "dogfood": ".octopus/skills/_shared/review-reviewer-prompt.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/review-revision-prompt.md", + "dogfood": ".octopus/skills/_shared/review-revision-prompt.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/synthesis_task.md", + "dogfood": ".octopus/skills/_shared/synthesis_task.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/worker-report-persistence.md", + "dogfood": ".octopus/skills/_shared/worker-report-persistence.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/roles/coordinator.yaml", + "dogfood": ".octopus/skills/_shared/roles/coordinator.yaml", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/roles/producer.yaml", + "dogfood": ".octopus/skills/_shared/roles/producer.yaml", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/roles/reviewer.yaml", + "dogfood": ".octopus/skills/_shared/roles/reviewer.yaml", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/roles/tool.yaml", + "dogfood": ".octopus/skills/_shared/roles/tool.yaml", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/skills/_shared/roles/verifier.yaml", + "dogfood": ".octopus/skills/_shared/roles/verifier.yaml", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/checklists/audit-process.md", + "dogfood": ".octopus/checklists/audit-process.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/checklists/bugfix.md", + "dogfood": ".octopus/checklists/bugfix.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/checklists/code-review.md", + "dogfood": ".octopus/checklists/code-review.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/checklists/dag-single-gate.md", + "dogfood": ".octopus/checklists/dag-single-gate.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/checklists/frontend.md", + "dogfood": ".octopus/checklists/frontend.md", + "batch": "G4", + "sync": "verbatim" + }, + { + "core": "core/checklists/implementation.md", + "dogfood": ".octopus/checklists/implementation.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/checklists/pipeline-gate.md", + "dogfood": ".octopus/checklists/pipeline-gate.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/checklists/port.md", + "dogfood": ".octopus/checklists/port.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/checklists/prototype.md", + "dogfood": ".octopus/checklists/prototype.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/checklists/refactoring.md", + "dogfood": ".octopus/checklists/refactoring.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/checklists/release.md", + "dogfood": ".octopus/checklists/release.md", + "batch": "G4", + "sync": "verbatim" + }, + { + "core": "core/checklists/retrospective.md", + "dogfood": ".octopus/checklists/retrospective.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/checklists/verification.md", + "dogfood": ".octopus/checklists/verification.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/templates/dag.md", + "dogfood": ".octopus/templates/dag.md", + "batch": "G6b", + "sync": "rewritten" + }, + { + "core": "core/templates/runs-layout.md", + "dogfood": ".octopus/templates/runs-layout.md", + "batch": "G6", + "sync": "rewritten" + }, + { + "core": "core/schemas/port-analysis.schema.json", + "dogfood": ".octopus/schemas/port-analysis.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/review-status.schema.json", + "dogfood": ".octopus/schemas/review-status.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/reviewer-output.schema.json", + "dogfood": ".octopus/schemas/reviewer-output.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/runs-bundle.schema.json", + "dogfood": ".octopus/schemas/runs-bundle.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/runs-index.schema.json", + "dogfood": ".octopus/schemas/runs-index.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/runs-meta.schema.json", + "dogfood": ".octopus/schemas/runs-meta.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/synthesis.schema.json", + "dogfood": ".octopus/schemas/synthesis.schema.json", + "batch": "G5", + "sync": "rewritten" + }, + { + "core": "core/schemas/workflow-routing.schema.json", + "dogfood": ".octopus/schemas/workflow-routing.schema.json", + "batch": "G5", + "sync": "rewritten" + } + ] +} diff --git a/core/MIGRATION.md b/core/MIGRATION.md new file mode 100644 index 0000000..45ebda2 --- /dev/null +++ b/core/MIGRATION.md @@ -0,0 +1,136 @@ +# Core 迁移映射表 + +编号保真(不变量 C-2):迁移仅改位置,不改编号。映射登记的运行时事实源 +是 `core/CORE-MANIFEST.json`;本表是批次级视图。 + +| 源路径 | Core 路径 | 批次 | 状态 | +| --------------------------------------------------------- | ----------------------------------------------------- | ---- | ---------------------------------------------------------------------------------------- | +| `.octopus/rules/claim-discipline.md` | `core/rules/claim-discipline.md` | G0 | 已迁移(逐字复制) | +| `.octopus/rules/stash-discipline.md` | `core/rules/stash-discipline.md` | G0 | 已迁移(逐字复制) | +| `.octopus/rules/code-graph.md` | `core/rules/code-graph.md` | G0 | 已迁移(逐字复制) | +| `.octopus/rules/compact.md` | `core/rules/compact.md` | G1 | 已迁移(接口中立化改写) | +| `.octopus/rules/workflow-routing.md` | `core/rules/workflow-routing.md` | G1 | 已迁移(接口中立化改写) | +| `.octopus/rules/auto-approve.md` | `core/rules/auto-approve.md` | G1 | 已迁移(接口中立化改写) | +| `.octopus/rules/two-tier-artifacts.md` | `core/rules/two-tier-artifacts.md` | G1 | 已迁移(接口中立化改写) | +| `.octopus/rules/ticket-lifecycle.md` | `core/rules/ticket-lifecycle.md` | G1 | 已迁移(接口中立化改写) | +| `.octopus/rules/testing.md` | `core/rules/testing.md` | G1 | 已迁移(接口中立化改写) | +| (Core 原生,无 dogfood 源) | `core/rules/artifact-addressing.md` | G2 | 新增(Core 原生契约) | +| `.octopus/skills/_shared/gitea-write-patterns.md` | `core/adapters/gitea/patterns.md` | G2 | 已拆分(adapter 拆分上提) | +| `.octopus/skills/_shared/gitea-read-patterns.md` | `core/adapters/gitea/reading.md` | G2 | 已拆分(adapter 拆分上提) | +| `.octopus/rules/issue-checklist-sync.md` | `core/rules/issue-checklist-sync.md` | G3 | 已迁移(接口中立化改写) | +| `.octopus/rules/issue-cross-linking.md` | `core/rules/issue-cross-linking.md` | G3 | 已迁移(接口中立化改写) | +| `.octopus/rules/artifact-index-guards.md` | `core/rules/artifact-index-guards.md` | G3 | 已迁移(接口中立化改写) | +| `.octopus/rules/type-checking.md` | `core/rules/type-checking.md` | G3 | 已迁移(接口中立化改写) | +| `.octopus/rules/session-scope-guard.md` | `core/rules/session-scope-guard.md` | G3 | 已迁移(接口中立化改写) | +| `.octopus/skills/analyze-dag/` | `core/skills/analyze-dag/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/browser-debug/` | `core/skills/browser-debug/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/codegraph-setup/` | `core/skills/codegraph-setup/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/frontend/` | `core/skills/frontend/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/gitea-rest/` | `core/skills/gitea-rest/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/headless-session-ops/` | `core/skills/headless-session-ops/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/image-interpret/` | `core/skills/image-interpret/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/implement/` | `core/skills/implement/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/land-batch/` | `core/skills/land-batch/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/project-kickoff/` | `core/skills/project-kickoff/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/prototype/` | `core/skills/prototype/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/release/` | `core/skills/release/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/retrospective/` | `core/skills/retrospective/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/review-artifact/` | `core/skills/review-artifact/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/review-code/` | `core/skills/review-code/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/verify/` | `core/skills/verify/` | G4 | 已迁移(整目录逐字;6a 改写为 rewritten) | +| `.octopus/skills/writing-skills/` | `core/skills/writing-skills/` | G4 | 已迁移(整目录逐字) | +| `.octopus/skills/_shared/compaction-round-boundary.md` | `core/skills/_shared/compaction-round-boundary.md` | G4 | 已迁移(逐字,protected 纪律载体;6a 改写为 rewritten) | +| `.octopus/skills/_shared/large-prompts.md` | `core/skills/_shared/large-prompts.md` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/review-final-report-template.md` | `core/skills/_shared/review-final-report-template.md` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/review-orchestrator-rules.md` | `core/skills/_shared/review-orchestrator-rules.md` | G4 | 已迁移(逐字;6a 改写为 rewritten) | +| `.octopus/skills/_shared/review-pipeline-phases.md` | `core/skills/_shared/review-pipeline-phases.md` | G4 | 已迁移(逐字,protected 纪律载体;6a 改写为 rewritten) | +| `.octopus/skills/_shared/review-reviewer-prompt.md` | `core/skills/_shared/review-reviewer-prompt.md` | G4 | 已迁移(逐字,protected 纪律载体;6a 改写为 rewritten) | +| `.octopus/skills/_shared/review-revision-prompt.md` | `core/skills/_shared/review-revision-prompt.md` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/synthesis_task.md` | `core/skills/_shared/synthesis_task.md` | G4 | 已迁移(逐字,protected 纪律载体;6a 改写为 rewritten) | +| `.octopus/skills/_shared/worker-report-persistence.md` | `core/skills/_shared/worker-report-persistence.md` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/roles/coordinator.yaml` | `core/skills/_shared/roles/coordinator.yaml` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/roles/producer.yaml` | `core/skills/_shared/roles/producer.yaml` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/roles/reviewer.yaml` | `core/skills/_shared/roles/reviewer.yaml` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/roles/tool.yaml` | `core/skills/_shared/roles/tool.yaml` | G4 | 已迁移(逐字) | +| `.octopus/skills/_shared/roles/verifier.yaml` | `core/skills/_shared/roles/verifier.yaml` | G4 | 已迁移(逐字) | +| `.octopus/checklists/*.md`(13 份) | `core/checklists/` | G4 | 已迁移(逐字;audit-process/bugfix/pipeline-gate/port/prototype/verification;6a 改写为 rewritten) | +| `.octopus/templates/*.md`(2 份) | `core/templates/` | G4 | 已迁移(逐字) | +| `.octopus/schemas/port-analysis.schema.json` | `core/schemas/port-analysis.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| `.octopus/schemas/review-status.schema.json` | `core/schemas/review-status.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| `.octopus/schemas/reviewer-output.schema.json` | `core/schemas/reviewer-output.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| `.octopus/schemas/runs-bundle.schema.json` | `core/schemas/runs-bundle.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| `.octopus/schemas/runs-index.schema.json` | `core/schemas/runs-index.schema.json` | G5 | 已迁移($id 迁至公共命名空间;artifacts[].schema 声明历史接受集) | +| `.octopus/schemas/runs-meta.schema.json` | `core/schemas/runs-meta.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| `.octopus/schemas/synthesis.schema.json` | `core/schemas/synthesis.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| `.octopus/schemas/workflow-routing.schema.json` | `core/schemas/workflow-routing.schema.json` | G5 | 已迁移($id 迁至公共命名空间) | +| (待登记) | (待登记) | G5+ | 未开始 | + +## G5 twin 归一记录 + +scaffold-template 侧(`packages/octopus/src/cli/cmd/scaffold-template/schemas/`) +schema `$id` 的 owner token 归一(旧命名空间 owner token → Octopus,与既有 2 份多数对齐; +`normalizeSchemaOwnerToken` 归一化下双向等价,纯一致性清理): + +- `review-status.schema.json` +- `reviewer-output.schema.json` +- `runs-bundle.schema.json` +- `runs-index.schema.json` +- `synthesis.schema.json` +- `workflow-routing.schema.json` + +## 保护注记(protected 纪律载体) + +以下四个 `_shared` 文件是多轮评审管线的纪律载体(round-boundary 压缩、 +评审提示词、综合任务),G4 仅逐字迁移不改内容;其改写留给 Increment 6 +(deferHard 标记已在 manifest 登记): + +- `review-pipeline-phases.md` +- `review-reviewer-prompt.md` +- `synthesis_task.md` +- `compaction-round-boundary.md` + +## G6(Increment 6a:发布单元达标面) + +- **deferHard 27 件 → rewritten**:10 个 verbatimDir 技能目录 + 17 个 + verbatim 文件(_shared md/yaml + 清单/模板)全部按 G1 风格中立化改写 + (机制/结构/frontmatter 保留;实例术语以占位符表述并指向 + core/adapters/TERMINOLOGY.md;技能内 .ts 脚本未动)。gitea-rest SKILL.md + 标注为 gitea adapter reference implementation(frontmatter 原样)。 + manifest:sync → rewritten(目录行保持目录路径)、batch → G6、deferHard + 键全删。 +- **守卫小扩展**:parity/cohesion/dangling/core-sync 支持 rewritten 目录行 + (存在性 = 目录存在;C-1 扫描 = 递归目录内 .md/.yaml);cohesion 默认 + 扫描面纳入 .yaml;core-sync 对 rewritten 目录行报 managed-by 跳过。 +- **去链接化契约执行**:core/** 全树 #NNNN 活引用 → [org-internal #NNNN] + 注记(457 处、48 文件);delink:core 幂等;verbatim 镜像内 60 处递延 + 至 6b。 +- **examples/ 建立**:4 篇组织沉积教学案例(sprint-mode 吞吐事故、 + preflight 证据闭环、WIP cap 与 TD 登记、评审轮次预算),只引用 Core + 不被引用。 +- **P1 终验门**:check:core-p1(98 文本文件全树扫描;豁免 id-aliases.json + 与 runs-index 历史命名空间声明;verbatim 镜像 2 处命中列 6b 递延)。 +- 最终分类:71 mappings = 15 verbatim + 7 verbatimDir + 46 rewritten + + 2 split + 1 core-only。 + +## G6b(Increment 6b:字节锁解锁 + EMBED 重指) + +- **字节锁镜像翻转 rewritten**:v3 去链接化契约规定 dogfood 侧保留活链接 + → 不能三侧同批 delink。18 个携带 refs/P1 命中的 verbatim/verbatimDir + 镜像(13 个 verbatim 文件行 + 5 个 verbatimDir 目录行)翻转为 + sync = "rewritten"、batch = "G6b";core 侧运行 delink(60 处 + #NNNN → [org-internal #NNNN])+ 两处旧 owner legacy-token 手工中立化 + (checklists/code-review.md 5.8 行、checklists/refactoring.md 4.7 行, + 改为不指名组织的 token 漂移表述);dogfood 侧不动(parity 的 rewritten + 语义 = 双侧存在 + core 模式扫描,无字节比较)。翻转账本的 md 链接改写 + 为 core/ 与 / 引用形态(analyze-dag/frontend/ + writing-skills 共 21 处路径去实例化)。 +- **EMBED 重指 core/**:generate-builtin.ts 的 EMBED_SOURCES 源权威从 + `/` 改为 core/(audit §G 承诺)。CLOSURE_PATTERN / META_SKILL_ + PREFIXES / closure 路径解析同步重指;service 键名(rules/auto-approve.md + 等)保持不变,运行时读取不受影响。builtin overlay 仅在无 / + 磁盘目录时生效——本组织恒有 → dogfood 运行时不变;shipped 默认语料自此 + 为中立版(内嵌 [org-internal #NNNN] 注记、无组织实例 token)。 +- **终验归零**:delink-core --check 0 replaceable / 0 deferred; + check-core-p1 0 hits / 0 deferred(6a 递延清单全部清偿)。 +- 最终分类:71 mappings = 2 verbatim + 2 verbatimDir + 64 rewritten + + 2 split + 1 core-only。 diff --git a/core/README.md b/core/README.md new file mode 100644 index 0000000..229094c --- /dev/null +++ b/core/README.md @@ -0,0 +1,116 @@ +# octopus Core(工作流标准公共层) + +`core/` 是工作流体系标准化后的**公共 Core**:自包含的规则、技能、 +清单、模板、schema 与适配器层。`.octopus/` 下的对应文件是**消费副本** +(dogfood 实例),`examples/` 仅承载叙事性示例。 + +## 不变量 C-1:Core 不引用实例 + +- Core 内的工件**不得引用** `examples/` 或任何实例专有路径;`core/adapters/**` + 例外——adapter 目录承载后端绑定的 API 形态(工具名、端点),但仍 + **禁止实例机密与实例专有地址**(内网 IP、实例主机名、实例配置路径)。 +- 引用方向是**单向的**:`examples/` 与实例层可以引用 Core,Core 永远不 + 回头引用它们。 +- 机械化校验:`script/check-core-cohesion.ts` 的 C-1 扫描——HARD 模式 + (实例机密/专有地址)对全部 core 生效;SOFT 模式(实例路径/工具名) + 对 `core/adapters/**` 豁免、其余 core 文件生效(见「增量采用」)。 + +## 不变量 C-2:迁移保编号 + +- 清单迁移**仅改位置、不改编号**:任何规则 / 技能 / 清单迁入 Core 时, + 其标识符(issue 编号、TD 编号、检查项编号)原样保留。 +- 编号是跨实例的稳定契约;重编号会切断历史追溯链。 +- 映射登记:`core/CORE-MANIFEST.json`(core 路径 ↔ dogfood 路径 ↔ 批次), + 编号保真映射表骨架见 `core/MIGRATION.md`。 + +## SSOT 契约(单一事实源) + +- **Core = 全量权威副本**:规则、技能、\_shared、清单、模板已全部迁入, + 所有修改先落在 `core/`。**builtin overlay 源权威 = core/**(Increment 6b + 起,`packages/octopus/script/generate-builtin.ts` 的 EMBED_SOURCES 从 + core/ 读取——shipped 默认语料为中立版;仅当实例磁盘无 + `/` 目录时 overlay 才生效)。 +- **`.octopus/` = 消费镜像**:dogfood 实例通过 `script/core-sync.sh` 从 + Core 单向同步(verbatim / verbatimDir 自动逐文件同步;rewritten / + split 按术语表落地),永不反向。 +- **`examples/` 仅叙事**:只引用 Core,不承载事实源内容。 +- 机械化守护: + - `script/core-sync.sh` — 单向同步(`--check` 只检不写,CI 用); + - `script/check-core-parity.ts` — 逐对比较 manifest 登记的文件内容, + 不一致即报漂移; + - `script/check-core-cohesion.ts` — manifest 路径存在性 + C-1 扫描; + - `script/check-dangling-refs.ts` — 双侧路径存在性 + core 内部引用 + 完整性(intra-core 悬空检出;`--scope-report` 输出覆盖摘要); + - `script/check-scaffold-parity.ts` — scaffold-template twin 逐字节 + 校验(schema $id owner token 归一化比较); + - `script/delink-core.ts` — 去链接化契约执行(#NNNN 活引用 → [org-internal #NNNN] + 注记;幂等;--check 零剩余才过;Inc 6b 字节锁镜像翻转 rewritten 后无递延); + - `script/check-core-p1.ts` — P1 零残留终验(私网 IP / 实例主机名 / 个人 + 身份 / 旧 owner token 全树 grep;豁免 id-aliases.json 与历史命名空间 + URL 声明;Inc 6b 起无字节锁递延); + - `script/check-schema-ids.ts` — core schemas $id 命名空间/文件名匹配 + - id-aliases 一对一/存在性 + 历史接受集声明在位(完整 guards 表见 + 文末「机械化守护(guards)」)。 + +## 发布单元达标(Increment 6a + 6b) + +- **去链接化契约已执行**:core/** 全树 #NNNN 活引用已注记化 + ([org-internal #NNNN]),delink:core 幂等可重跑,--check 为零剩余门。 + Inc 6b 已解锁 6a 递延的 60 处字节锁镜像引用(翻转 rewritten 后 core 侧 + 全量注记化,0 递延)。 +- **P1 零残留终验门**:check:core-p1 扫 core/ 全部文本文件(md/yaml/ + json/ts),命中私网 IP、实例主机名、个人身份、旧 owner token 即 FAIL; + id-aliases.json(SCH-F401)与 runs-index 历史命名空间声明豁免。 + Inc 6b 已清偿 6a 递延的 2 处旧 owner token 命中(0 递延)。 +- **examples/ 方向性**:组织沉积教学案例(叙事),只引用 Core、不被 Core + 引用(C-1 单向);不入 manifest、不进 cohesion 扫描面。 + +## 目录语义 + +| 目录 | 语义 | +| ---------------------- | ------------------------------------------------------- | +| `core/rules/` | L1 强制规则的 Core 源(14 份已全部迁入,G0–G3) | +| `core/skills/` | 技能整目录的 Core 源(17 个已全部迁入,G4 verbatimDir) | +| `core/skills/_shared/` | 技能共享工件(角色 yaml、评审管线文件等,14 份,G4) | +| `core/checklists/` | 清单(13 份已全部迁入,G4) | +| `core/templates/` | 模板(dag.md、runs 布局,2 份已全部迁入,G4) | +| `core/schemas/` | JSON Schema(8 份已迁入,G5;$id 已迁至公共命名空间) | +| `core/adapters/` | 实例适配层(后端参考实现;SOFT 扫描豁免、HARD 仍生效) | + +## 增量采用 + +Core 的采用以 `core/CORE-MANIFEST.json` 登记为准——**登记了才算采用**。 +G0–G4 批次已完成全量迁移(14 规则、17 技能整目录、\_shared 14 份、 +13 清单、2 模板);后续批次按 `core/MIGRATION.md` 的映射表推进。 + +### C-1 扫描的增量形态(设计决策) + +模式分两级(Increment 3): + +- **HARD**(全 core 生效,含 adapters):实例主机名、内网 IP 段、实例 + 配置路径——实例机密与实例专有地址任何 core 文件不得出现。 +- **SOFT**(`core/adapters/**` 豁免):`.octopus/`、`packages/octopus`、 + MCP 工具名、工作树路径等实例绑定内容——adapter 目录是 Gitea 参考 + 实现,允许承载;其余 core 文件不得出现。 + +G0 三份规则是从实例规则**逐字复制**的,规则正文里出现实例路径字样属 +**叙述性引用**,且都在行内代码/围栏内(扫描先剥离,零命中)。 +脚本以 `--strict` 开关预留更严形态:`--strict` 时额外对 verbatim 文件 +按全模式集扫描(剥离语义同前)。默认扫描面 = core 下全部 `.md` 文件 +(含 adapters,adapters 只查 HARD)。扫描匹配前先剥离行内代码 span +(反引号内文字)与围栏代码块——反引号内的是定义性提及(如本文件对 +C-1 模式列表的描述),不是活引用。 + +### manifest 语义(sync 字段) + +| sync 值 | 语义 | parity 校验 | core-sync 行为 | +| ------------- | --------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------ | +| `verbatim` | 逐字复制 | 字节比较 | Core → dogfood 自动 `cp` | +| `verbatimDir` | 整目录逐字复制(目录级行,core 路径以 `/` 结尾) | 递归文件集一致(排除 `.gitkeep`)+ 逐文件字节比较 | Core → dogfood 逐文件同步 | +| `rewritten` | 接口中立化改写 | 双侧存在 + core 侧 HARD+SOFT 扫描 | `managed-by: rewrite (no auto-sync)` | +| `split` | adapter 拆分上提(页名/寻址语义已上提 Core 契约,API 形态留 adapter) | 双侧存在 + core 侧 HARD 扫描(SOFT 豁免) | `managed-by: split (no auto-sync)` | +| `core-only` | Core 原生契约,无 dogfood 对应(`dogfood: null`) | core 存在 + HARD+SOFT 扫描,无 dogfood 检查 | `managed-by: core-only` | + +`deferHard: true`(历史字段,**Increment 6a 已全数清零**):曾标记暂含实例 +表述的行;6a 已将全部 27 行中立化改写为 rewritten 并删除该键。现 +manifest 中不存在 deferHard 行,cohesion `--strict` 的 deferred 计数为 0。 diff --git a/core/adapters/.gitkeep b/core/adapters/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/core/adapters/TERMINOLOGY.md b/core/adapters/TERMINOLOGY.md new file mode 100644 index 0000000..710b588 --- /dev/null +++ b/core/adapters/TERMINOLOGY.md @@ -0,0 +1,36 @@ +# 术语映射表(Core ↔ dogfood 实例) + +> 本表是 Core 改写与 dogfood 实例对照的**唯一事实源**(v3 §E):Core 侧 +> 工件使用下表左列的中立术语,右列是本组织 dogfood 实例(Gitea 后端)的 +> 实际表述。任何 Core 工件需要落到本实例时,按本表做机械替换;反向 +> 改写(实例 → Core)同样以本表为准。新增映射必须先改本表,再改工件。 + +| Core 中立术语 | dogfood/Gitea 实例表述 | +| --- | --- | +| 工单后端(ticket backend) | Gitea | +| Tier-2 工件库 | Gitea wiki | +| 工单评论 API(ticket backend 评论接口) | `gitea_issue_comment__*` | +| wiki 读写 API(Tier-2 工件库读写接口) | `gitea_wiki__*` | +| 看板移动 API(工单看板列迁移接口) | `gitea_column__move_issue` | +| 项目看板 API(工单面板管理接口) | `gitea_project__*` | +| 路由解析工具(Step 0 路由门依赖) | `route_resolver` | +| 会话工作树路径(并发分支工作区根) | `` | +| 测试命令·变更集(本地前置检查) | `bun run test:changed` | +| 测试命令·全量分片(交付前置 / nightly) | `bun run test:parallel` | +| 类型检查命令 | `bun typecheck` | +| 产品代码路径(harness 实现所在包) | `packages/octopus/src/...` | +| 私化工单引用(组织内部工单号) | `#NNNN` 活链接(Core 侧用 `[org-internal #NNNN]` 注记) | +| 实例规则目录(dogfood 消费副本所在) | `.octopus/`(如 `.octopus/rules/`) | +| 运行工作区(Tier-1 本地工件) | `.octopus/runs/{slug}/` | +| 实例配置文件(会话/管线配置) | `octopus.jsonc` | + +## 备注 + +- **私化工单引用**:Core 侧不得产出指向具体实例的活链接 `#NNNN`(会被 + 实例渲染为真实工单);一律写 `[org-internal #NNNN]` 注记格式,落地 + 实例时按本表还原为 `#NNNN`。 +- **命令占位**:Core 规则正文中的 ``、 + `` 等占位符按本表「测试命令」两行绑定到实例命令。 +- **裸词 Gitea**:仅当作为 adapter 名称出现时允许(如「Gitea adapter」); +- 表内反引号包裹的实例表述仅供对照,不构成 Core 对实例的引用 + (C-1 扫描剥离行内代码后本表零命中)。 diff --git a/core/adapters/gitea/patterns.md b/core/adapters/gitea/patterns.md new file mode 100644 index 0000000..8052638 --- /dev/null +++ b/core/adapters/gitea/patterns.md @@ -0,0 +1,215 @@ +# Gitea Adapter — 写模式(Write Patterns) + +> Gitea adapter 参考实现(Increment 3,自 dogfood 源 +> `_shared/gitea-write-patterns.md` 拆分上提)。本目录承载后端绑定的 +> API 形态(MCP 工具名、REST 端点、curl 形态);页名规范与寻址语义 +> 是后端中立契约,见 `core/rules/artifact-addressing.md`(本文不重复)。 +> 实例基址由实例配置提供(下文 ``),见 +> `core/adapters/TERMINOLOGY.md`。 + +Owner/repo 固定为 `Octopus/octopus`。所有 wiki 页名遵循 Core 契约 +`{slug}/{type}-{seq:02d}-{title}`(例外页全枚举见 artifact-addressing.md)。 + +## Wiki URL 构造 — html_url 规则 + +**黄金规则:绝不手工拼接 wiki URL。** `gitea_wiki__create_page` / +`gitea_wiki__get_page` / `gitea_wiki__list_pages` 响应中的 `html_url` +字段是唯一权威链接,发布时捕获并原样复用。`page_name` → `html_url` +的变换不可推导(`/`→`%2F`、含斜杠页名带 `.-` 尾缀、CJK 百分号编码), +必须读 API。 + +**两种标识符勿混淆**: + +| 标识符 | 是什么 | 用途 | +| ----------- | ------------------------------------ | ---------------------------------------- | +| `page_name` | 原始页标识;字面 `/`、无主机、无编码 | wiki MCP 工具的 `page_name`/`title` 参数 | +| `html_url` | 后端生成的完整可点击 URL | markdown 链接、`target_url`、PR 正文 | + +**去向**: + +- **工件索引位置列** — 一个单元格同时存两者: + ``[`{page_name}`]({html_url})``。链接文本供读侧调 + `gitea_wiki__get_page`,href 供人点击(见 Pattern 10)。 +- **commit-status `target_url`** — 终报页的 `html_url`(见 Pattern 8)。 +- **页内交叉链接** — 用 `html_url`。 + +无 API 响应可用时(静态源串)用 ``,且仅此一处来源。 + +## Pattern 1: create-wiki-page + +``` +gitea_wiki__create_page(owner="Octopus", repo="octopus", + title="{slug}/{type}-{seq:02d}-{title}", + content="{内容}", + message="{可选 commit message}") +``` + +**发布→验证(强制)**:发布后立刻回读确认存在且内容一致: + +``` +gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name="{同 title}") +``` + +404 / 内容不一致 → 修复后重发。页名冲突(409)→ 该页已存在,改用 +Pattern 2 update,绝不另发新页。响应的 `html_url` 立即捕获复用。 + +## Pattern 2: update-wiki-page + +``` +gitea_wiki__update_page(owner="Octopus", repo="octopus", + page_name="{页名}", + content="{新内容}", + message="{commit message}") +``` + +更新后再回读验证;409 冲突 → 拉最新内容手工合并后重试。 + +## Pattern 3: create-issue + +``` +gitea_issue__create(owner="Octopus", repo="octopus", + title="{标题}", body="{正文}", labels=["{label}"]) +``` + +### 工单交叉链接(强制) + +父子工单组必须双向链接:父工单 task list 引用 `#`;子工单正文 +带 `## 父级 / Parent` 节引用父 `#`。 + +### 衍生工单创建 + +- 技术债(verify Phase 5.5):`TD-NNN` 经分配台账取号后升票,`## Parent` + 指回登记册源工单。 +- 基线失败(Phase 5.55):label `baseline-failure` + `BF-NNN`(族伞签, + 按失败签名去重)。 +- 不稳定测试(Phase 5.56):label `flaky-test` + `FT-NNN`(同上)。 + +## Pattern 4: update-issue + +``` +gitea_issue__update(owner="Octopus", repo="octopus", + index={issue_number}, body="{正文}", state="{open|closed}", ...) +``` + +原位更新正文(checklist 勾选、live 状态表维护);关闭工单即触发 +归档动作(见 artifact-addressing.md §4.3 + Pattern 10)。 + +## Pattern 5: add-issue-comment + +``` +gitea_issue_comment__create(owner="Octopus", repo="octopus", + index={issue_number}, body="{评论正文}") +``` + +首次评论后捕获返回的 `comment_id`——后续对同一逻辑评论的更新必须走 +Pattern 6 原位 edit,绝不再 create。用于:评审综合(Synthesis)、 +状态备注、TD 登记、claim 认领。 + +## Pattern 6: edit-issue-comment + +``` +gitea_issue_comment__edit(owner="Octopus", repo="octopus", + comment_id={comment_id}, body="{新正文}") +``` + +单评论聚合不变量(工件索引、当前状态表等)的执行手段。 + +## Pattern 7: move-issue-to-column + +``` +gitea_column__move_issue(owner="Octopus", repo="octopus", + project_id={project_id}, column_id={column_id}, index={issue_number}) +``` + +看板列迁移(Todo → In Progress → Review → Done)。 + +## Pattern 7.5: move-issue-to-pipeline-stage + +管线阶段板列(Pipeline Stages board column)承载阶段迁移——阶段转移 +落到板列,**不落** `## 当前状态` 行(该表只承载 PR / 评审 / CI 行与 +非阶段阻塞项)。列序列按管线阶段定义;移动用 Pattern 7 同款 +`gitea_column__move_issue`,column 由 `gitea_project__list` / +`gitea_column__list` 发现。 + +## Pattern 8: post-commit-status(REST 回退) + +MCP 工具缺席时用 REST 直发 commit status(评审综合的 Tier-2 落点): + +```bash +curl -X POST "/api/v1/repos/Octopus/octopus/statuses/{sha}" \ + -H "Authorization: token " \ + -H "Content-Type: application/json" \ + -d '{ + "context": "pipeline/review-{stage}", + "state": "{success|failure|pending|error}", + "target_url": "{html_url}", + "description": "{≤140 chars 摘要}" + }' +``` + +context 公式:`pipeline/review-{stage}`(`code` / `review-dag` / +`audit-process`)。token 从实例配置读取(此处 `` 占位)。 +merge 前读回验证:`GET /commits/{PR_SHA}/status`。 + +## Pattern 9: create-iteration-board + +``` +gitea_project__create(owner="Octopus", repo="octopus", + title="{slug} — Iteration {N}", description="…") +gitea_column__create(owner="Octopus", repo="octopus", + project_id={project_id}, title="Todo") +# … In Progress / Review / Done 同款 +``` + +DAG 聚合 agent 在单门 PASS 后建板;工单正文模板带 `## Node Reference` +(指向 `{epic-slug}/dag`)、`## Acceptance Criteria`、`## Parent`。 + +## Pattern 10: artifact-index(工单 ↔ 工件索引) + +技能发布工件后,在源工单维护 **`## 工件索引` 评论**——单一原位编辑的 +索引(反向链接 + compaction 恢复主路径;语义不变量见 +`core/rules/artifact-addressing.md` §4): + +``` +# 1. 找源工单(PR body / commit 的 Closes #N,或 DAG 父映射);无则跳过 +# 2. 评论已存在? +gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number}) +# → 扫 body 以 "## 工件索引" 开头的评论(遗留前缀 "## Pipeline 工件追踪表" +# 原位升级,不重复发) +# 3a. 不存在 → gitea_issue_comment__create 初始化 +# 3b. 存在 → gitea_issue_comment__edit 原位编辑(复用 comment_id) +``` + +**索引表模板**(每工件一行;技能只增改自己的行,绝不删他技的行): + + ## 工件索引 + + slug: `{slug}` — source issue #{N} + + | 工件 | 类型 | 版本 | 位置 | 重读 | + |------|------|------|------|------| + | DAG | 任务图 | v1 (frozen) | [`{epic-slug}/dag`]({html_url}) | CORE | + +**位置列填充规则**:单元格 = markdown 链接 ``[`{page_name}`]({html_url})``; +链接文本(page_name,字面 `/`)供读侧 `gitea_wiki__get_page`;href +(html_url)供人点击,必须取自 API 响应,严禁拼接。 + +**重读优先级**:`CORE` = compaction 后必读(重读集 = 全部 CORE 行); +`ON-Demand` → `ON-DEMAND` = 按需;`ARCHIVE` = 已归档不读。 + +**归档动作(archive-at-close)**:工单关闭时由关闭方 agent 原位 edit +本评论——表格上方加归档横幅(`> **状态**: ✅ 已归档 — issue #{N} 关闭于 +{date}`)+ 全部行 重读 置 `ARCHIVE`;不删行、不改位置列、不发第二条 +评论。主路径 verify Phase 5.6;跳过 verify 的路由由关闭 agent 补执行。 + +**各技能行映射**: + +| 技能 | 工件 ID | 位置 | +| ------------------------- | ---------------------------- | ------------------------------------------------------------ | +| `analyze-dag` | `DAG` | `{epic-slug}/dag` | +| `review-artifact` | `REVIEW-{stage}` | `{slug}/reviews/{stage}/final/report` | +| `review-code` | `REVIEW-code` | `{slug}/reviews/code/final/report` | +| `review-code`(DAG task) | `REVIEW-code-task-{node-id}` | `{epic-slug}/reviews/code/final/report-task-{node-id}` | +| `verify` | `VERIFY-{N}` | `{slug}/05-verify-iteration-{N}` | +| `verify`(milestone) | `VERIFY-M-{M-id}` | `{epic-slug}/05-verify-milestone-{M-id}`(重读 `ON-DEMAND`) | +| `verify`(DAG task) | `VERIFY-TASK-{node-id}` | `{epic-slug}/05-verify-task-{node-id}`(重读 `ON-DEMAND`) | diff --git a/core/adapters/gitea/reading.md b/core/adapters/gitea/reading.md new file mode 100644 index 0000000..9ddd055 --- /dev/null +++ b/core/adapters/gitea/reading.md @@ -0,0 +1,123 @@ +# Gitea Adapter — 读模式(Read Patterns) + +> Gitea adapter 参考实现(Increment 3,自 dogfood 源 +> `_shared/gitea-read-patterns.md` 拆分上提)。页名规范与寻址语义见 +> `core/rules/artifact-addressing.md`(后端中立契约,本文不重复)。 +> 实例基址 `` 由实例配置提供,见 TERMINOLOGY.md。 + +Owner/repo 固定 `Octopus/octopus`。compaction 恢复从 Pattern 6 +(读工件索引)开始——源工单上的工件索引是上下文恢复的规范入口, +硬编码页名路径仅作回退。 + +## Pattern 1: read-wiki-page + +``` +gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name="{slug}/{page_title}") +``` + +常用页名(全量文法 + 例外枚举见 `core/rules/artifact-addressing.md` §2): + +| 工件 | page_name | +| -------------------------- | ------------------------------------------------------------------------------------------------- | +| 验证报告 | `{slug}/05-verify-iteration-{N}` | +| DAG 工件(单门) | `{epic-slug}/dag`;AC 子页 `{epic-slug}/dag-nodes/{node-id}`;覆盖子页 `{epic-slug}/dag-coverage` | +| 评审终报(review-dag) | `{epic-slug}/reviews/review-dag/final/report` | +| 评审终报(code) | `{slug}/reviews/code/final/report` | +| 评审终报(code, DAG task) | `{epic-slug}/reviews/code/final/report-task-{node-id}` | +| 验证(DAG milestone) | `{epic-slug}/05-verify-milestone-{M-id}` | +| 验证(DAG task) | `{epic-slug}/05-verify-task-{node-id}` | +| DAG 共享契约 | `{epic-slug}/shared/{file}` | +| bugfix 附件 | `{slug}/repro-notes` · `{slug}/test-report` · `{slug}/bugfix-report` · `{slug}/ABORT` | +| 原型/实现笔记 | `{slug}/prototype-debt` · `{slug}/spike-report` · `{slug}/impl-notes` | +| 设计修订 | `{slug}/03-design-amendments` | +| 审计工件 | `audit/{date}/{page}`,如 `audit/{date}/final/report` | +| 移植工件 | `port-{name}/source-analysis/{file}` · `port-{name}/self-check` | +| 回顾报告 | `_retrospectives/{cycle-name}` | +| 回顾归档 | `_archive/{slug}/` | +| 技能评估 | `_evals/{skill-name}/{page}` | +| 浏览器调试证据 | `{slug}/verify/evidence/{name}`(临时截图留在工作区截图目录) | + +历史只读页名(旧管线产物仍可读):`{slug}/01-stakeholder-interview`、 +`{slug}/02-requirements-index`、`{slug}/02-req-{seq:02d}-{title}`、 +`{slug}/02-03-req-design`、`{slug}/03-design-index`、 +`{slug}/03-design-{seq:02d}-{title}`、`{slug}/03-adr-{NNNN}-{title}`、 +`{slug}/04-plan-index`、`{slug}/04-plan-{seq:02d}-{title}`、 +`{slug}/roadmap/{page}`、`{slug}/shared/{file}`、 +`{slug}/reviews/{roadmap|design-space|plan}/final/report`。 + +**本地回退(wiki MCP 工具不可用)**:读本地 wiki 克隆(实例路径见 +TERMINOLOGY.md)。wiki 文件名 URL 编码(`/`→`%2F`,`.md` 前可能带 +`.-`),用 glob 而非固定路径解析: + +``` +glob(pattern="*{slug}*{page-title}*.md", path="/{repo}-wiki/") +``` + +## Pattern 2: read-issue + +``` +gitea_issue__get(owner="Octopus", repo="octopus", index={issue_number}) +``` + +读工单详情、正文、元数据(label、assignee、milestone、state)。 + +## Pattern 3: read-issue-comments + +``` +gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number}) +``` + +读工单全部评论(评审结果、状态备注、讨论线程)。 + +## Pattern 4: read-project-column-issues + +``` +gitea_column__list_issues(owner="Octopus", repo="octopus", + project_id={project_id}, column_id={column_id}) +``` + +看板列工单队列。project/column 发现:`gitea_project__list` + +`gitea_column__list`。 + +## Pattern 5: read-review-status(CLI) + +``` +octopus review status [--stage ] [--sha ] [--json] +``` + +读评审收敛状态(commit status)。stage 值:`code`、`review-dag`、 +`audit-process`;省略 `--stage` 列出该提交全部状态。历史 stage 值 +(`design-space` 等)仅可查历史。 + +**stage-id → 评审目录映射**(Tier-1 本地 `reviews/{stage}/` 段): +`review-code` → `code`;`review-dag` → `review-dag`; +`audit-process` → `audit-process`。只有 code 评审用短名,不得发明其他。 + +收敛判定:context `pipeline/review-{stage}` 的 status 存在且 +state = `success`(= PASS 或 WARN,无未决 BLOCKER)。退出码 0 = 全部 +success,1 = 有 failure/error。 + +## Pattern 6: read-artifact-index(compaction 恢复主路径) + +压缩后或新会话从工单种子恢复时,读工件索引评论(写侧 Pattern 10) +而非猜测页名路径: + +``` +gitea_issue__get(owner="Octopus", repo="octopus", index={issue_number}) +gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number}) +# 找 body 以 "## 工件索引"(遗留 "## Pipeline 工件追踪表")开头的评论 +gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name=page_name) +``` + +**位置列提取规则**:单元格形如 ``[`{page_name}`]({html_url})`` —— +取**链接文本**(首个 `[` 与 `]` 之间、剥反引号)作为 page_name,不是 +href(含 `%2F`/`.-`,API 不认)。裸 page_name 单元格(无链接包裹)也 +接受:整格即 page_name。形如 `#comment-{id}` 的值改用 +`gitea_issue_comment__list` 读,不得喂给 `gitea_wiki__get_page`。 + +**重读规则**:重读集 = 全部 `CORE` 行;`ON-DEMAND` 行仅当前任务需要 +时读;绝不读 `ARCHIVE` 行。索引缺失(历史工单)→ 回退 issue body + +`## 当前状态` + 硬编码页名路径。 + +**已归档索引**:无 `CORE` 行,恢复时重读集为空,按需直读目标工件 +(位置列 URL 仍有效);归档只改重读优先级,不改可访问性。 diff --git a/core/checklists/.gitkeep b/core/checklists/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/core/checklists/audit-process.md b/core/checklists/audit-process.md new file mode 100644 index 0000000..7676a1f --- /dev/null +++ b/core/checklists/audit-process.md @@ -0,0 +1,211 @@ +> Core 中立版(Increment 6a 改写,原 deferHard verbatim)。编号与条目结构严格不变(C-2 不变量);实例术语按 `core/adapters/TERMINOLOGY.md` 绑定。 +# 流程审计检查清单(Process Audit Checklist) + +> 用于审计 `/` 流程基础设施本身的完整性、一致性与合规性。 +> 审计对象是这套 SDLC「工厂」本身(skills / checklists / templates / schemas), +> 而非某个具体项目对流程的遵循情况(后者归 `retrospective`)。 +> +> 依据:内部一致性规则、ISO 19011:2018(审核指南)、IEEE 1028-2008(软件评审与审计)、 +> 以及本仓库 `AGENTS.md` 工程约定。 + +> **维度命名空间(dimension namespace)**: 本清单中的维度代码(如 TRC)是**清单局部(checklist-local)**标识符,仅在本文档内唯一;其他清单可能对相同字母串绑定不同概念(如 code-review.md 的 TRC=Traceability vs 本清单的 TRC=Traceability 审计维度)。跨清单引用时必须带清单限定(如 audit-process.md TRC 10.3),不得使用裸代码。 + +--- + +## 使用说明 + +1. 审计对象是 `/` 目录下的 `skills/`、`checklists/`、`templates/`、`schemas/`; +2. 每个审计维度由一名独立审计员(Explorer,只读)负责,逐项判定 PASS / FAIL / NA(NA=逐项"不适用"判定标记,不属于 findings JSON 的维度 verdict 枚举 PASS/WARN/FAIL/UNRESOLVED——UNRESOLVED 专指审计员崩溃/超时状态,勿混用); +3. 对 FAIL 项必须给出:具体文件位置、引用证据、可执行的修复建议; +4. 审计员必须保持**独立性**(ISO 19011:2018):仅依据文件事实判定,不臆测意图; +5. 任一维度存在 FAIL 项须修订后重新审计,直至收敛。 + +**Known exceptions to INV 1.3** (inline self-check checklists — skills whose +checklist obligations are embedded in the SKILL.md body by design): +- `core/skills/writing-skills/SKILL.md` §"Authoring checklist" — methodology + skill, inline RED/GREEN/REFACTOR self-check is its normative form. +- `core/skills/codegraph-setup/SKILL.md` §"Verification checklist" — + setup/installation skill, inline verification checklist is its normative form. +- `core/skills/project-kickoff/SKILL.md` §"4. Workflow" step 4 (**Post-kickoff verification**) — + setup/lifecycle skill; its self-check is the `octopus kickoff --check-only` + tool's 5 readiness items, which is the tool-based equivalent of an inline + checklist (analogous to codegraph-setup's CLI verification), not a + `core/checklists/` artifact checklist. +- `core/skills/analyze-dag/SKILL.md` — pipeline Producer (DAG route entry + skill). Its producer-side self-check obligations are folded inline into the + SKILL.md body (Topology Constraints §, Page-Size Budget, Requirement + Registry, Exec-Resource Configuration) as the mechanically-checkable + destination of the folded plan-checklist rows; the **gate-side** coverage is + `core/checklists/dag-single-gate.md` (TOPO/REQMAP/RELEASE), not a + producer self-check checklist. A thin `analyze-dag.md` wrapper would add no + value over the in-skill rows + the single-gate checklist. +- `core/skills/land-batch/SKILL.md` — merge-pr stage skill (batch PR + landing). Its self-check obligations are inline by design: the fail-closed + `## Preconditions (all mandatory, fail-closed)` block and the + "Pre-validate locally (never enter CI red)" rung are the normative gates, + backstopped by CI merge-gate mechanical checks — same doctrine as + project-kickoff's tool-based self-check; a thin wrapper checklist would + add no value. +- Tool/utility & integration skills — `browser-debug`, + `gitea-rest`, `image-interpret`, `headless-session-ops` — are + non-artifact-producing (they drive tools / sessions / MCP servers, not SDLC + pipeline artifacts), so INV 1.3's "产物型 skill" clause does not apply to + them; their operational obligations are inline normative statements (e.g. + `browser-debug`'s session-cleanup / screenshot-naming iron rules) by the same + doctrine as the listed exemptions above. +These are exempted per `audit/2026-08-11/round1/revision-summary` (writing-skills, +codegraph-setup), `audit/2026-08-13/round1/revision-summary` (project-kickoff), +`audit/2026-08-17/round1/revision-summary` (analyze-dag), and +`audit/2026-09-01/round1/revision-summary` (land-batch); +creating thin wrapper checklist files would add no value. + +--- + +## 1. 清单完整性(INV — Inventory Completeness) + +> 流水线阶段齐全、无孤儿文件。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | --------------------------------------------------------------------- | ---- | ------ | ---- | +| 1.1 | SDLC 流水线各阶段均有对应 skill(analyze-dag→review-dag 单门→implement→review-code→verify→release→retrospective;legacy roadmap/requirements/design/plan 已归档 [org-internal #3072] phase 3,见 `/archive/`) | ☐ | ☐ | | +| 1.2 | 每个 `skills//` 目录恰好包含一个 `SKILL.md`(例外:`_shared/` 目录不含 `SKILL.md`,为共享引用文档目录) | ☐ | ☐ | | +| 1.3 | 每个产物型 skill 都有配套 `checklists/.md`(无清单的自检要求即为缺口) | ☐ | ☐ | | +| 1.4 | `checklists/` 中无孤儿清单(存在清单但无任何 skill 引用) | ☐ | ☐ | | +| 1.5 | `templates/` 中无孤儿模板(存在模板但无任何 skill 引用) | ☐ | ☐ | | +| 1.6 | `schemas/` 中无孤儿 schema(存在 schema 但无任何 skill 引用) | ☐ | ☐ | | +| 1.7 | 每个 review-* skill 的维度数量与其引用清单的章节数量一致,或存在文档化的合并说明(每节恰好被一个维度覆盖) | ☐ | ☐ | | + +--- + +## 2. 交叉引用完整性(XREF — Cross-Reference Integrity) + +> skill ↔ checklist ↔ template ↔ schema 的引用路径不得断裂。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------------- | ---- | ------ | ---- | +| 2.1 | skill 中引用的每个 `core/checklists/*.md` 路径真实存在 | ☐ | ☐ | | +| 2.2 | skill 中引用的每个 `core/templates/*.md` 路径真实存在 | ☐ | ☐ | | +| 2.3 | skill 中引用的每个 `core/schemas/*.json` 路径真实存在 | ☐ | ☐ | | +| 2.4 | skill 中引用的 wiki `{slug}/...` 路径结构与其它 skill 一致;引用模式见 `_shared/gitea-read-patterns.md` / `_shared/gitea-write-patterns.md` | ☐ | ☐ | | +| 2.5 | 清单中引用的标准编号(IEEE/ISO)在 skill References 中亦有呼应 | ☐ | ☐ | | +| 2.6 | skill 之间相互引用的前序/后继阶段名称真实存在(无断链) | ☐ | ☐ | | +| 2.7 | 引用的检查项编号(如 `ARCH 1.1–1.7`)在目标清单中确实存在 | ☐ | ☐ | | + +--- + +## 3. 元数据合规性(FM — Frontmatter Conformance) + +> 每个 SKILL.md 的 frontmatter 必须符合 octopus skill 规范。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ----------------------------------------------------------------- | ---- | ------ | ---- | +| 3.1 | `name` 存在、小写连字符、≤64 字符,且与所在目录名一致 | ☐ | ☐ | | +| 3.2 | `description` 存在且非空(缺失会被加载器过滤、永不触发) | ☐ | ☐ | | +| 3.3 | `description` 同时说明「做什么」与「何时触发」 | ☐ | ☐ | | +| 3.4 | `description` 使用第三人称("Use when...",而非 "I help...") | ☐ | ☐ | | +| 3.5 | 需要静默于相邻话题的 skill 使用了 "Use ONLY when..." 或 "Use ONLY after..." 限定 | ☐ | ☐ | | +| 3.6 | `triggers`(如有)为关键词/文件名,前置了用户可能说出的字面词 | ☐ | ☐ | | +| 3.7 | frontmatter 无未知顶层字段,YAML 可解析 | ☐ | ☐ | | + +--- + +## 4. 命名约定一致性(NAM — Naming Convention) + +> 跨流程基础设施的命名必须统一。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------------- | ---- | ------ | ---- | +| 4.1 | 清单文件名使用产物名词形式(如 `implementation.md`、`code-review.md`),skill 名使用动词形式或标准 SDLC 产物名(如 `implement`、`review-code`;`frontend`、`writing-skills` 等按产物/领域命名的 skill,以及按工具命名的集成类 skill(`gitea-rest`、`codegraph-setup`)除外),共享清单以产物名命名(如 `verification.md`、`port.md`;已归档的 legacy 清单见 `/archive/checklists/`) | ☐ | ☐ | | +| 4.2 | 维度代码(如 ARCH / SEC / TRC)在 skill 与清单间拼写一致 | ☐ | ☐ | | +| 4.3 | 角色名称与 core/skills/_shared/roles/*.yaml 的 name 字段一致(Producer/Reviewer/Verifier/Tool/Coordinator)。旧角色名(Developer/Analyst/Architect 等)由 role.ts 中的 ROLE_ALIASES 安全映射,不再需要独立 YAML。不得使用已废弃的角色名(如 'Organizer')。`escalation` 字段除可指向上述注册角色外,亦可指向有效的 subagent_type(如 'Builder',其作为运行时可加载的构建型子代理类型) | ☐ | ☐ | | +| 4.4 | 产物路径片段(wiki `{slug}/...`)命名跨 skill 统一;引用模式见 `_shared/gitea-read-patterns.md` / `_shared/gitea-write-patterns.md`。审计类产物使用日期 slug(如 wiki `audit/{date}/`)属允许例外 | ☐ | ☐ | | +| 4.5 | 严重度等级(BLOCKER/MAJOR/MINOR/INFO)跨 skill 与 schema 一致 | ☐ | ☐ | 允许例外:`port-analysis.schema.json` 使用三值契约(BLOCKER/MAJOR/MINOR,永不产出 INFO),已在 schema description 中自证为对四值集的文档化例外 | +| 4.6 | 裁决值(PASS/WARN/FAIL)跨 skill 与 schema 一致 | ☐ | ☐ | | + +--- + +## 5. 流水线衔接(FLOW — Pipeline Cohesion) + +> 阶段之间的前置条件与产物链必须闭合,无断裂。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ----------------------------------------------------------------- | ---- | ------ | ---- | +| 5.1 | 每个 skill 的 Preconditions 引用的前序产物,确由某个上游 skill 产出 | ☐ | ☐ | | +| 5.2 | 每个 skill 的产物,确被某个下游 skill 作为输入消费(终点除外:verify、release、retrospective,以及发布/副作用类 skill 如 `review-artifact` (target: process),其产出由人类或外部系统消费) | ☐ | ☐ | | +| 5.3 | review-* skill 的输入路径与其对应生产 skill 的输出路径精确匹配(代码评审输入为项目源码树中 git diff 标识的文件;其余评审输入为 wiki `{slug}/` 下的文档,读取模式见 `_shared/gitea-read-patterns.md`;process 审计目标为第三输入类——本地 `/` 语料,无上游生产 skill,自产自审) | ☐ | ☐ | | +| 5.4 | 收敛/审批关卡(如「Do NOT advance without approval」)在阶段切换处存在 | ☐ | ☐ | | +| 5.5 | 阶段顺序无环(不存在 A 依赖 B 同时 B 依赖 A) | ☐ | ☐ | | +| 5.6 | 每个 skill 声明的角色与模型分配在同类 skill 间一致 | ☐ | ☐ | | + +--- + +## 6. Schema 契约(SCH — Schema Contract) + +> schema 被正确引用,且 skill 描述的字段与 schema 定义对齐。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------------- | ---- | ------ | ---- | +| 6.1 | skill 中要求写入的 JSON 产物均指明了对应的 `core/schemas/*.json` | ☐ | ☐ | 允许例外:(a) `precondition-gate.jsonl`(review-code/verify)为自版本化、机器可再生的 JSONL 记录,有意无 backing schema;(b) browser-debug 证据包(`browser/{session-id}/manifest.json` 等)由冻结共享契约 `browser-evidence-4486/shared/pack-manifest-v1` 等校验(写入方 `/src/browser/evidence-pack.ts`),不在 `core/schemas/` 下 | +| 6.2 | skill 文中描述的字段名与 schema 的 `required`/`properties` 一致 | ☐ | ☐ | | +| 6.3 | skill 描述的枚举值(verdict/severity)与 schema `enum` 一致 | ☐ | ☐ | | +| 6.4 | 每个 schema 自身合法(`$schema`、`$id`、`type` 齐备) | ☐ | ☐ | | +| 6.5 | 多个 skill 共用同一 schema 时语义一致(无相互冲突的字段约定) | ☐ | ☐ | | + +--- + +## 7. 重复与漂移(DUP — Duplication & Drift) + +> 单一事实来源;术语不漂移。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------------- | ---- | ------ | ---- | +| 7.1 | 同一概念在不同 skill 中术语一致(无同义词漂移) | ☐ | ☐ | | +| 7.2 | 检查项/规则无跨文件的实质性重复(应集中于清单而非散落于 skill) | ☐ | ☐ | | +| 7.3 | 收敛准则(max_rounds、停止条件)在各 review-* skill 间一致或有理由不一致 | ☐ | ☐ | | +| 7.4 | 标准编号引用一致(同一标准不出现多种写法) | ☐ | ☐ | | + +--- + +## 8. 审计原则合规(STD — Audit Standards / ISO 19011:2018 · IEEE 1028-2008) + +> 体现独立性、客观证据、分级判定、可重复。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ----------------------------------------------------------------- | ---- | ------ | ---- | +| 8.1 | 审计员独立性:review-* skill 明确审计员只读、不得越权(ISO 19011:2018 §4) | ☐ | ☐ | | +| 8.2 | 客观证据:findings 要求 location + evidence(IEEE 1028-2008 证据留痕) | ☐ | ☐ | | +| 8.3 | 分级判定:严重度与裁决规则量化(pass_rate 阈值明确,非主观) | ☐ | ☐ | | +| 8.4 | 可重复:审计员 prompt 标准化、温度低(确定性输出) | ☐ | ☐ | | +| 8.5 | 防范范围收窄:明令禁止「只看重点/从简」类弱化措辞(IEEE 1028-2008 完整性) | ☐ | ☐ | | +| 8.6 | 留痕:审计产物落盘到结构化文件,而非仅存于对话 | ☐ | ☐ | | +| 8.7 | 闭环:存在重审循环与收敛/审批终止条件(ISO 19011:2018 跟踪与关闭) | ☐ | ☐ | | + +--- + +## 9. 工程约定符合度(AGT — AGENTS.md Conformance) + +> 流程基础设施所描述/示例的工程做法须符合本仓库 `AGENTS.md` 及其**委托的约定源**: +> `AGENTS.md` 将工程约定委托给 L1 `core/rules/*`(注入主会话)与 L2 wiki `rules/*` +> (按需读取),故本维各项的「基线」是 `AGENTS.md` 委托到的实际约定文档(下各条注明)。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ----------------------------------------------------------------- | ---- | ------ | ---- | +| 9.1 | skill 示例命令与测试约定一致(基线:`core/rules/testing.md` — `bun run test:parallel`、从 package 目录运行、勿从 repo 根运行) | ☐ | ☐ | | +| 9.2 | skill 示例的类型检查命令与 `core/rules/type-checking.md` 一致(package 目录 `bun typecheck`,非直接 `tsc`;repo 根整仓为 `bun turbo typecheck`) | ☐ | ☐ | | +| 9.3 | skill 引用的 DB/迁移流程与 L2 wiki `rules/database`(Drizzle、`bun run db generate`)一致 | ☐ | ☐ | | +| 9.4 | skill 描述的模块形态与 L2 wiki `rules/style-guide`(无 `export namespace`、自再导出)一致 | ☐ | ☐ | | +| 9.5 | skill 描述的 Effect 用法与 L2 wiki `rules/effect-rules` 一致(如适用) | ☐ | ☐ | | + +--- + +## 10. 可追溯性(TRC — Traceability) + +> 从需求到验证全链路可追溯;审计自身亦可追溯。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------------- | ---- | ------ | ---- | +| 10.1 | 存在贯穿全流水线的追溯机制(需求 ID → 设计 → 实现 → 验证) | ☐ | ☐ | | +| 10.2 | 每个 review-* skill 都包含 Traceability 维度或等价检查 | ☐ | ☐ | | +| 10.3 | 审计 finding 的 ID 规则唯一且可定位到具体检查项 | ☐ | ☐ | | +| 10.4 | 审计历史(轮次、裁决、blocker/major 数)被记录于 status 产物 | ☐ | ☐ | | +| 10.5 | 模型/角色分配变更可在 skill 中追溯(同类 skill 横向可比) | ☐ | ☐ | | diff --git a/core/checklists/bugfix.md b/core/checklists/bugfix.md new file mode 100644 index 0000000..29ed9bd --- /dev/null +++ b/core/checklists/bugfix.md @@ -0,0 +1,85 @@ +> Core 中立版(Increment 6a 改写,原 deferHard verbatim)。编号与条目结构严格不变(C-2 不变量);实例术语按 `core/adapters/TERMINOLOGY.md` 绑定。 +# Bugfix 检查清单 + +> 开发者在修复 Bug 时自检使用。确保修复的是根因而非症状,且不引入新问题。 + +> **维度命名空间(dimension namespace)**: 本清单中的维度代码(如 TST/BEH/GATE/REG)是**清单局部(checklist-local)**标识符,仅在本文档内唯一;其他清单可能对相同字母串绑定不同概念(如 code-review.md 的 TST=Test Quality、verification.md 的 TST=Test Suite Completeness、port.md 的 TST=Test Porting)。跨清单引用时必须带清单限定(如 code-review.md TST 5.8),不得使用裸代码。 + +--- + +## 使用说明 + +1. Phase 1-4 每阶段结束时检查对应项; +2. Phase 5 完成后检查全部项; +3. 所有项通过后方可提交。 + +--- + +## 1. 复现确认(REPRO — Reproduction) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | -------------------------------------------- | ---- | ------ | ---- | +| 1.1 | Bug 可以稳定复现(有明确的复现步骤) | ☐ | ☐ | | +| 1.2 | 实际行为与 Bug 报告一致 | ☐ | ☐ | | +| 1.3 | 如果无法复现,已向用户反馈原因并等待补充信息 | ☐ | ☐ | | +| 1.4 | 已捕获环境快照(`ps aux`、`lsof -p PID`、日志文件大小、进程树 — pipeline 模式强制,standalone 建议) | ☐ | ☐ | | +| 1.5 | 复现置信度评级 1–5(≥3 方可进入 pipeline 设计阶段;<3 → abort) | ☐ | ☐ | | +| 1.6 | 已检索 Gitea wiki `{slug}/repro-notes` / `{slug}/bugfix-report` 中是否存在同类症状的先前调查报告,复用已知根因而非重新推导(via `wiki 读写 API(见 TERMINOLOGY)`) | ☐ | ☐ | | + +--- + +## 2. 根因分析(ROOT — Root Cause) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------ | ---- | ------ | ---- | +| 2.1 | 根因已定位到具体代码行(非模块级别) | ☐ | ☐ | | +| 2.2 | 根因是底层逻辑缺陷,非表面症状 | ☐ | ☐ | | +| 2.3 | 如果根因来自数据/环境/配置,已注明具体差异 | ☐ | ☐ | | + +--- + +## 3. 回归测试(TEST — Regression Test) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | --------------------------------------------------- | ---- | ------ | ---- | +| 3.1 | 已编写针对性的回归测试 | ☐ | ☐ | | +| 3.2 | 回归测试在修复前 FAIL(确认覆盖了 Bug) | ☐ | ☐ | | +| 3.3 | 回归测试在修复后 PASS | ☐ | ☐ | | +| 3.4 | 如果无法编写自动化测试,已标注 `[flaky]` 并说明原因 | ☐ | ☐ | | + +--- + +## 4. 修复质量(FIX — Fix Quality) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | -------------------------------------------- | ---- | ------ | ---- | +| 4.1 | 修复是最小变更——只改了必须改的部分 | ☐ | ☐ | | +| 4.2 | 未混入重构、风格调整或不相关的"顺手改" | ☐ | ☐ | | +| 4.3 | 修复的是根因而非症状 | ☐ | ☐ | | +| 4.4 | 同一模块的已有测试全部通过(修复未引入退化) | ☐ | ☐ | | +| 4.5 | Commit 消息使用常规提交前缀(`fix:` / `refactor:` / `docs:`)并位于 `[{chunk-id}][{iteration}]` 之后 | ☐ | ☐ | | + +--- + +## 5. 全面回归(REG — Full Regression) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | --------------------------------------- | ---- | ------ | ---- | +| 5.1 | `bun run test:parallel` 全部通过(零失败) | ☐ | ☐ | | +| 5.2 | `bun typecheck` 无错误 | ☐ | ☐ | | +| 5.3 | `bun lint` 无错误 | ☐ | ☐ | | +| 5.4 | 如果有集成/端到端测试,已运行并全部通过 | ☐ | ☐ | | +| 5.5 | 移交评审前已按 `core/checklists/code-review.md` 的 A11Y(§8)与 PERF(§4)节自检本次变更,并对全部改动文件跑 `bunx prettier --check`(pre-commit 钩子只扫提交时的 staged 文件,CR-COMMIT 把提交推迟到评审收敛后,移交前的工作区漂移没有任何钩子拦截——出处:sticky-diff-error 复盘 action item 2) | ☐ | ☐ | | + +--- + +## 6. 闭环(CLOSURE — Fix Linked to Commit) + +> 防止"幽灵 artifact":bugfix 报告已写出但代码修复从未提交/合并,导致 bug +> 复发并重复调查。参见 `core/skills/retrospective/SKILL.md` 了解该规则的 +> 复盘出处。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | -------------------------------------------- | ---- | ------ | ---- | +| 6.1 | standalone bugfix 的 `{slug}/bugfix-report` 必须在同一周期内有**已合并提交**背书;若仅调查未应用修复,必须显式标注 "investigation only — no fix applied" | ☐ | ☐ | | +| 6.2 | 若本次修复取代了先前的同类 `{slug}/bugfix-report`,已在该先前报告顶部标注 SUPERSEDED 并指向新 PR | ☐ | ☐ | | diff --git a/core/checklists/code-review.md b/core/checklists/code-review.md new file mode 100644 index 0000000..679653e --- /dev/null +++ b/core/checklists/code-review.md @@ -0,0 +1,198 @@ +# 代码评审检查清单 + +> 用于评审代码的正确性、设计一致性、安全性和可维护性。 +> 依据 IEEE 1028-2008 和行业最佳实践。 + +> **维度命名空间(dimension namespace)**: 本清单中的维度代码(如 TST/BEH/GATE/REG)是**清单局部(checklist-local)**标识符,仅在本文档内唯一;其他清单可能对相同字母串绑定不同概念(如 code-review.md 的 TST=Test Quality、verification.md 的 TST=Test Suite Completeness、port.md 的 TST=Test Porting)。跨清单引用时必须带清单限定(如 code-review.md TST 5.8),不得使用裸代码。 + +--- + +## 使用说明 + +1. 阅读待评审的全部代码文件; +2. 同时阅读设计文档中的相关章节作为参考基线; +3. 逐项检查,判定为"通过"或"不通过"; +4. 对"不通过"项注明具体文件名、行号和问题描述; +5. 任一检查维度中若存在"不通过"项,须修订后重新评审; +6. 所有维度均通过后方可合并或发布。 +7. 第 2 轮及以后的评审中,任何仅属外观性的 MINOR 发现(命名、注释、死代码、导入顺序、风格等不影响正确性或可读性的问题)必须满足其一:已修复并关闭,或在 synthesis 中以 `WAIVED-{id}` 条目显式豁免并注明原因。`WAIVED-{id}` 约定的规范定义见 `.octopus/skills/_shared/review-revision-prompt.md`(本清单的豁免标记形如 `WAIVED-COR-R2-001`)。 +8. **CR-COMMIT 门禁**:代码评审收敛(所有维度 PASS)后,必须将所有评审修订提交到工作分支,再进入 verify 阶段。未提交的评审修订不得通过 verify 放行。验证阶段(verify)启动前必须确认 `git status` 无未提交修改。 +9. **standalone-bugfix 模式的预先存在模式豁免**:在 standalone-bugfix 模式下,修复的范围应以最小化外科手术为原则。若 COR/STY/DOC 维度的发现指向的是**修复前已存在的模式**(并非本次变更引入),且该模式与文件中已有代码保持一致,则 `WAIVED` 或 `ACCEPTED_RISK` 是有效的处理方式。具体适用场景: + - COR 1.9/1.10/1.13:错误处理策略在变更前已采用同等模式(如 `console.warn` 而非面向用户的错误提示、无超时策略等),本次变更未使其劣化 + - STY 6.8:文件/模块长度超过 200 行属于变更前已有的结构,拆分为独立重构任务(非本次 bugfix 范畴) + - DOC 9.5:注释中的默认值初始化(如 `lastTriggerScrollTop = -1`)为防御性编程,在观察者建立前即被覆盖,无行为影响 + 每次豁免必须在 synthesis 中以带编号的 `WAIVED-{id}` 或 `ACCEPTED_RISK` 条目记录原因。此豁免不影响其他维度的评审标准。 + +--- + +## 1. 正确性、错误处理与兼容性检查(COR — Correctness, Error Handling & Compatibility) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| ---- | ------------------------------------------------------------ | ---- | ------ | ---- | +| 1.1 | 逻辑分支完整,无遗漏的 if/else、switch case 或漏处理的枚举值 | ☐ | ☐ | | +| 1.2 | 边界条件正确处理(空值、空集合、零值、负值、最大值/最小值) | ☐ | ☐ | | +| 1.3 | null/undefined 在使用前已检查,无空引用风险 | ☐ | ☐ | | +| 1.4 | 异步操作正确使用 await 或 Promise 链,无竞态条件 | ☐ | ☐ | | +| 1.5 | 循环有正确的终止条件,无无限循环风险 | ☐ | ☐ | | +| 1.6 | 类型转换安全(如字符串转数字、JSON 解析),有失败处理 | ☐ | ☐ | | +| 1.7 | 无逻辑死区(unreachable code)或死代码(dead code) | ☐ | ☐ | | +| 1.8 | 所有可能失败的操作(I/O、网络、解析、数据库)有错误处理 | ☐ | ☐ | | +| 1.9 | 错误信息对用户友好(不暴露内部堆栈、路径或 SQL) | ☐ | ☐ | | +| 1.10 | 外部服务调用有超时、重试和熔断策略(与设计文档一致) | ☐ | ☐ | | +| 1.11 | 事务边界明确,异常时回滚,无部分提交 | ☐ | ☐ | | +| 1.12 | 错误码和 HTTP 状态码语义正确(不把 500 当 400 用) | ☐ | ☐ | | +| 1.13 | 异常被捕获且传播到合适的层级,无被吞掉的异常 | ☐ | ☐ | | +| 1.14 | 异步错误(Promise rejection、EventEmitter error)有处理器 | ☐ | ☐ | | +| 1.15 | 公共 API 的签名、参数和返回值未做不兼容变更(或已标注 breaking) | ☐ | ☐ | | +| 1.16 | 配置项的新增/删除/改名有迁移路径或向后兼容处理 | ☐ | ☐ | | +| 1.17 | 客户端(前端/移动端/SDK)与后端接口版本兼容 | ☐ | ☐ | | + +--- + +## 2. 设计一致性与依赖检查(DGN — Design Compliance & Dependencies) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| ---- | ------------------------------------------------------ | ---- | ------ | ---- | +| 2.1 | 代码实现了设计文档中该组件的全部指定接口和方法签名 | ☐ | ☐ | | +| 2.2 | 组件职责与设计文档中声明的职责一致,无越界逻辑 | ☐ | ☐ | | +| 2.3 | 组件依赖关系与设计文档的依赖图一致,无反向依赖 | ☐ | ☐ | | +| 2.4 | 数据模型(字段、类型、关系)与设计文档的数据设计一致 | ☐ | ☐ | | +| 2.5 | 接口输入输出的 Schema 与设计文档的接口设计一致 | ☐ | ☐ | | +| 2.6 | 代码未引入设计文档中未提及的新依赖或新服务 | ☐ | ☐ | | +| 2.7 | 架构模式(工厂、策略、仓储等)的使用方式与设计决策一致 | ☐ | ☐ | | +| 2.8 | 若代码偏离设计,有明确的 ADR 或注释说明理由 | ☐ | ☐ | | +| 2.9 | 已用 `graph usages`/`impact` 核验改动符号的所有调用方与传递影响均已处理,无遗漏的破坏性变更(评审时用代码图核对,而非 grep 逐文件追踪) | ☐ | ☐ | | +| 2.10 | 实现文件结构与迭代计划中的架构描述一致(文件数、模块划分、依赖方向)。若偏离(如单文件合并替代多文件架构),迭代计划已更新或偏离理由于设计文档中标明 | ☐ | ☐ | | +| 2.11 | 新增依赖有明确的技术理由(不在审查时追问"为什么需要它") | ☐ | ☐ | | +| 2.12 | 依赖版本已锁定(package-lock.json / bun.lock / 等同文件已更新) | ☐ | ☐ | | +| 2.13 | 无已知漏洞的依赖版本(依据 CVE 数据库或 `npm audit` 等同检查) | ☐ | ☐ | | +| 2.14 | 无引入未使用的依赖 | ☐ | ☐ | | +| 2.15 | 许可证兼容,无 GPL/AGPL 等强传染性许可证引入到非 GPL 项目 | ☐ | ☐ | | + +--- + +## 3. 安全性检查(SEC — Security) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| ---- | ----------------------------------------------------------------------------- | ---- | ------ | ---- | +| 3.1 | 用户输入在执行 SQL/命令/HTML 前已参数化或转义 | ☐ | ☐ | | +| 3.2 | 身份认证逻辑无绕过路径,会话令牌安全生成和验证 | ☐ | ☐ | | +| 3.3 | 授权检查在关键操作前执行,无 IDOR(越权访问)风险 | ☐ | ☐ | | +| 3.4 | 敏感数据(密码、令牌、密钥、PII)不在日志、错误消息或响应中泄露 | ☐ | ☐ | | +| 3.5 | 加密算法为业界推荐标准(无 MD5/SHA1/DES 用于安全目的),密钥管理合规 | ☐ | ☐ | | +| 3.6 | 输入校验在服务端执行(不依赖客户端校验) | ☐ | ☐ | | +| 3.7 | 无硬编码的凭据、密钥、内网地址或环境特定值 | ☐ | ☐ | | +| 3.7.1 | 暂存区/提交无符号链接,无机器本地绝对路径引用(`git diff --cached --diff-filter=T` 为空)| ☐ | ☐ | | +| 3.8 | 安全相关配置项(CORS、CSP、速率限制)符合设计文档安全章节 | ☐ | ☐ | | +| 3.9 | SAST 结论已核对:PR 存在时引用同 SHA 的 CI SAST 结果(`sast.yml`,无新增 HIGH/CRITICAL 发现);无 PR 或同 SHA 无扫描结果时标注 `UNVERIFIABLE-LOCAL`,留待 verify Phase 2.5 处理。评审员为只读权限,不自行运行扫描工具 | ☐ | ☐ | | +| 3.10 | 针对 CI SAST 报告的 HIGH 发现:True Positive 已修复或路由 Developer;False Positive 已标注排除理由(引用 `sast.yml` 产物,不重复推导) | ☐ | ☐ | | + +--- + +## 4. 性能检查(PERF — Performance) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| ---- | ------------------------------------------------------------- | ---- | ------ | ---- | +| 4.1 | 循环内无同步 I/O 或数据库查询(N+1 问题) | ☐ | ☐ | | +| 4.2 | 算法复杂度合理(无 O(n²) 或更高在主路径中,除非设计明确接受) | ☐ | ☐ | | +| 4.3 | 资源(连接、文件句柄、缓冲区)在使用后释放,无泄漏风险 | ☐ | ☐ | | +| 4.4 | 查询使用了索引,EXPLAIN 计划与设计文档索引设计一致 | ☐ | ☐ | | +| 4.5 | 适度使用缓存和批处理,无过早优化但也无非受控的重复计算 | ☐ | ☐ | | +| 4.6 | 异步操作非阻塞,长耗时操作用队列或后台任务处理 | ☐ | ☐ | | +| 4.7 | 前端:列表子项有稳定 key,事件处理器引用稳定,无不必要的重渲染 | ☐ | ☐ | | +| 4.8 | 前端:大列表使用虚拟滚动或分页,非首屏组件使用代码分割(lazy) | ☐ | ☐ | | +| 4.9 | 前端:图片有懒加载(`loading="lazy"`)和尺寸占位,无布局偏移 | ☐ | ☐ | | +| 4.10 | 前端:`useMemo`/`useCallback`/`computed`/`derived` 使用合理,无不必要的计算 | ☐ | ☐ | | + +--- + +## 5. 测试质量检查(TST — Test Quality) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------ | ---- | ------ | ---- | +| 5.1 | 新增代码有对应的测试(单元或集成),覆盖主要路径和分支 | ☐ | ☐ | | +| 5.2 | 测试覆盖了边界条件(空值、极值、异常路径) | ☐ | ☐ | | +| 5.3 | 测试断言验证了具体行为,非仅"不抛异常"或"返回非空" | ☐ | ☐ | | +| 5.4 | 测试相互独立,可任意顺序运行,无共享可变状态 | ☐ | ☐ | | +| 5.5 | Mock/Stub 的使用合理,模拟的外部行为与真实行为一致 | ☐ | ☐ | | +| 5.6 | 测试命名清晰表达了测试场景和预期结果 | ☐ | ☐ | | +| 5.7 | 本次变更涉及的测试已通过(`test:changed`,由 mechanical-green gate 机器判定,评审员引用 gate 结果即可)。全量套件(`test:parallel`)归 verify,不是代码评审门禁([org-internal #2598] 检查分层) | ☐ | ☐ | | +| 5.8 | 评审发现的"dummy fixture / harness 默认值漂移"类问题,不能仅凭 `WAIVED` 处置:若漂移值是 harness 对**生产 CLI/配置默认值**的镜像(如 harness 旧 owner 默认 vs CLI 新 owner 默认这类 token 漂移),WAIVED 会把真实漂移放行到 post-merge([org-internal #3169] TST-F002 → 后续 [org-internal #3172] 才修)。处置前确认该值是否被生产路径读取;被读取则必须 FIX 或显式登记 TD | ☐ | ☐ | | + +--- + +## 6. 风格与约定检查(STY — Style & Convention) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------ | ---- | ------ | ---- | +| 6.1 | 命名遵循项目约定(函数名、变量名、文件名、目录结构) | ☐ | ☐ | | +| 6.2 | 缩进、空格、引号、分号、行长度与项目格式化配置一致 | ☐ | ☐ | | +| 6.3 | 函数/方法长度合理(通常 ≤ 50 行),单一职责 | ☐ | ☐ | | +| 6.4 | 导入语句有序分组(第三方、内部、相对),无未使用的导入 | ☐ | ☐ | | +| 6.5 | 无注释掉的代码块(应删除或用版本控制追溯) | ☐ | ☐ | | +| 6.6 | 类型声明充分,无不必要的 `any` 或隐式类型 | ☐ | ☐ | | +| 6.7 | Lint 零错误已由机器判定(mechanical-green gate 与 CI 的 `bun oxlint --deny-warnings`);评审员引用 gate/CI 结果即可,只复核 lint 覆盖不到的约定项(6.1–6.6、6.8),不重复人工推导 | ☐ | ☐ | | +| 6.8 | 文件/模块长度 ≤ 200 行(超出需拆分)。模块过长降低可维护性和 review 效率 | ☐ | ☐ | | + +--- + +## 7. 数据库与数据检查(DBT — Database & Data) + +| # | 检查项 | 通过 | 不通过 | 备注 | +| --- | ------------------------------------------------------- | ---- | ------ | ---- | +| 7.1 | 数据库迁移可安全回滚(down migration 正确且与 up 对称) | ☐ | ☐ | | +| 7.2 | 查询使用参数化,无拼接 SQL 字符串 | ☐ | ☐ | | +| 7.3 | 索引使用与设计文档的索引设计对应,EXPLAIN 计划合理 | ☐ | ☐ | | +| 7.4 | 事务范围最小化(不在事务内执行外部调用或长计算) | ☐ | ☐ | | +| 7.5 | 数据库连接生命周期正确,连接池配置合理 | ☐ | ☐ | | +| 7.6 | 无大规模数据迁移导致锁表风险,大表变更方案已说明 | ☐ | ☐ | | +| 7.7 | 数据库 Schema 变更对已有数据向后兼容(新字段允许 NULL 或有默认值) | ☐ | ☐ | | + +--- + +## 8. 可访问性与浏览器兼容性检查(A11Y — Accessibility & Browser Compatibility) + +> 适用于所有面向用户的前端代码。确保 UI 可被各类用户(包括使用辅助技术者)正常使用。 + +| # | 检查项 | 通过 | 不通过 | 备注 | +| ---- | ----------------------------------------------------------------------- | ---- | ------ | ---- | +| 8.1 | 交互元素使用原生语义 HTML(`