cowork-flow 0.0.41 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/package.json +1 -1
  2. package/src/commands/install-zcode-plugin.js +11 -0
  3. package/template/.claude/agents/cowork-check.md +13 -2
  4. package/template/.claude/agents/cowork-implement.md +14 -2
  5. package/template/.codex/agents/cowork-check.toml +12 -7
  6. package/template/.codex/agents/cowork-implement.toml +12 -5
  7. package/template/.cowork-flow/.version +1 -1
  8. package/template/.cowork-flow/scripts/application/task_context.py +18 -8
  9. package/template/.cowork-flow/scripts/common/core/quality_sources.py +140 -0
  10. package/template/.cowork-flow/scripts/common/gates/gates.py +54 -2
  11. package/template/.cowork-flow/scripts/common/gates/quality_review.py +332 -0
  12. package/template/.cowork-flow/scripts/common/gates/validate_coding_standards.py +13 -5
  13. package/template/.cowork-flow/spec/protocols/review.md +20 -1
  14. package/template/.opencode/agents/cowork-check.md +6 -0
  15. package/template/.opencode/agents/cowork-implement.md +14 -2
  16. package/template/.zcode/.zcode-plugin/plugin.json +1 -1
  17. package/template/.zcode/scaffold/.cowork-flow/spec/backend/database-guidelines.md +0 -23
  18. package/template/.zcode/scaffold/.cowork-flow/spec/backend/directory-structure.md +0 -27
  19. package/template/.zcode/scaffold/.cowork-flow/spec/backend/encoding-guidelines.md +0 -27
  20. package/template/.zcode/scaffold/.cowork-flow/spec/backend/error-handling.md +0 -20
  21. package/template/.zcode/scaffold/.cowork-flow/spec/backend/index.md +0 -40
  22. package/template/.zcode/scaffold/.cowork-flow/spec/backend/logging-guidelines.md +0 -20
  23. package/template/.zcode/scaffold/.cowork-flow/spec/backend/quality-guidelines.md +0 -25
  24. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/capabilities.md +0 -34
  25. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/decision-anchor.md +0 -74
  26. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/index.md +0 -11
  27. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/party-mode-v2-board.md +0 -68
  28. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/subagent-dispatch.md +0 -83
  29. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/workflow-state-templates.md +0 -72
  30. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/component-guidelines.md +0 -19
  31. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/directory-structure.md +0 -18
  32. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/hook-guidelines.md +0 -17
  33. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/index.md +0 -39
  34. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/quality-guidelines.md +0 -25
  35. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/state-management.md +0 -18
  36. package/template/.zcode/scaffold/.cowork-flow/spec/frontend/type-safety.md +0 -18
  37. package/template/.zcode/scaffold/.cowork-flow/spec/game/asset-pipeline.md +0 -53
  38. package/template/.zcode/scaffold/.cowork-flow/spec/game/engine-guidelines.md +0 -43
  39. package/template/.zcode/scaffold/.cowork-flow/spec/game/index.md +0 -23
  40. package/template/.zcode/scaffold/.cowork-flow/spec/game/multiplayer-guidelines.md +0 -44
  41. package/template/.zcode/scaffold/.cowork-flow/spec/game/performance-guidelines.md +0 -58
  42. package/template/.zcode/scaffold/.cowork-flow/spec/guides/code-reuse-thinking-guide.md +0 -26
  43. package/template/.zcode/scaffold/.cowork-flow/spec/guides/cross-layer-thinking-guide.md +0 -21
  44. package/template/.zcode/scaffold/.cowork-flow/spec/guides/index.md +0 -31
  45. package/template/.zcode/scaffold/.cowork-flow/spec/guides/pre-implementation-checklist.md +0 -15
  46. package/template/.zcode/scaffold/.cowork-flow/spec/index.md +0 -15
  47. package/template/.zcode/scaffold/.cowork-flow/spec/runtime/contract-registry.json +0 -68
  48. package/template/.zcode/scaffold/.cowork-flow/spec/runtime/index.md +0 -10
  49. package/template/.zcode/scaffold/.cowork-flow/spec/runtime/rules.json +0 -176
  50. package/template/.zcode/scaffold/.cowork-flow/spec/schemas/adapter.schema.json +0 -128
  51. package/template/.zcode/scaffold/.cowork-flow/spec/schemas/index.md +0 -10
  52. package/template/.zcode/scaffold/.cowork-flow/spec/schemas/party-mode-v2-actions.schema.json +0 -90
  53. package/template/.zcode/scaffold/.cowork-flow/spec/schemas/rules.schema.json +0 -89
@@ -0,0 +1,332 @@
1
+ #!/usr/bin/env python3
2
+ """Validate task-local quality review evidence."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import json
7
+ from json import JSONDecodeError
8
+ from pathlib import Path
9
+ from typing import Iterable
10
+
11
+ from common.gates.validate_coding_standards import collect_machine_checks
12
+
13
+
14
+ QUALITY_REVIEW_FILE = "quality-review.jsonl"
15
+ REQUIRED_FIELDS = frozenset(
16
+ {"id", "source", "type", "status", "files", "evidence", "verification"}
17
+ )
18
+ ALLOWED_TYPES = frozenset({"checklist", "machine_warning", "dod"})
19
+ ALLOWED_STATUSES = frozenset(
20
+ {"pass", "fail", "not_applicable", "acknowledged_warning"}
21
+ )
22
+ VAGUE_EVIDENCE = frozenset(
23
+ {
24
+ "checked",
25
+ "done",
26
+ "ok",
27
+ "pass",
28
+ "passed",
29
+ "n/a",
30
+ "na",
31
+ "已检查",
32
+ "已确认",
33
+ "通过",
34
+ "无问题",
35
+ }
36
+ )
37
+
38
+
39
+ def validate_quality_review(
40
+ repo_root: Path,
41
+ task_dir: Path | None,
42
+ ) -> list[dict]:
43
+ """Return blocking violations for missing or incomplete quality evidence."""
44
+ if task_dir is None:
45
+ return [
46
+ _violation(
47
+ "QUALITY-REVIEW-TASK-001",
48
+ "",
49
+ "Quality review gate requires a task directory",
50
+ "Run task complete with an explicit or active task directory.",
51
+ )
52
+ ]
53
+
54
+ evidence_path = Path(task_dir) / QUALITY_REVIEW_FILE
55
+ entries, violations = _read_entries(evidence_path)
56
+ if violations and not entries:
57
+ return violations
58
+
59
+ violations.extend(_validate_entries(entries, evidence_path))
60
+ if not violations:
61
+ violations.extend(_validate_machine_warning_coverage(repo_root, entries))
62
+ return violations
63
+
64
+
65
+ def _read_entries(evidence_path: Path) -> tuple[list[dict], list[dict]]:
66
+ if not evidence_path.is_file():
67
+ return [], [
68
+ _violation(
69
+ "QUALITY-REVIEW-MISSING-001",
70
+ str(evidence_path),
71
+ "quality-review.jsonl is required before task complete",
72
+ "Record quality checklist, machine warning, and DoD evidence in quality-review.jsonl.",
73
+ )
74
+ ]
75
+
76
+ entries: list[dict] = []
77
+ violations: list[dict] = []
78
+ try:
79
+ lines = evidence_path.read_text(encoding="utf-8").splitlines()
80
+ except UnicodeDecodeError:
81
+ return [], [
82
+ _violation(
83
+ "QUALITY-REVIEW-UTF8-001",
84
+ str(evidence_path),
85
+ "quality-review.jsonl must be valid UTF-8",
86
+ "Rewrite quality-review.jsonl as UTF-8.",
87
+ )
88
+ ]
89
+ except OSError as error:
90
+ return [], [
91
+ _violation(
92
+ "QUALITY-REVIEW-READ-001",
93
+ str(evidence_path),
94
+ f"quality-review.jsonl could not be read: {error}",
95
+ "Restore a readable quality-review.jsonl file.",
96
+ )
97
+ ]
98
+
99
+ for index, raw_line in enumerate(lines, start=1):
100
+ line = raw_line.strip()
101
+ if not line:
102
+ continue
103
+ try:
104
+ value = json.loads(line)
105
+ except JSONDecodeError as error:
106
+ violations.append(
107
+ _line_violation(
108
+ "QUALITY-REVIEW-JSONL-001",
109
+ evidence_path,
110
+ index,
111
+ f"quality-review.jsonl line is invalid JSON: {error.msg}",
112
+ "Write one JSON object per line.",
113
+ )
114
+ )
115
+ continue
116
+ if not isinstance(value, dict):
117
+ violations.append(
118
+ _line_violation(
119
+ "QUALITY-REVIEW-JSONL-001",
120
+ evidence_path,
121
+ index,
122
+ "quality-review.jsonl line must be a JSON object",
123
+ "Write one JSON object per evidence record.",
124
+ )
125
+ )
126
+ continue
127
+ entries.append(value)
128
+
129
+ if not entries and not violations:
130
+ violations.append(
131
+ _violation(
132
+ "QUALITY-REVIEW-EMPTY-001",
133
+ str(evidence_path),
134
+ "quality-review.jsonl must contain at least one evidence record",
135
+ "Add checklist and DoD evidence records before completing the task.",
136
+ )
137
+ )
138
+ return entries, violations
139
+
140
+
141
+ def _validate_entries(entries: list[dict], evidence_path: Path) -> list[dict]:
142
+ violations: list[dict] = []
143
+ has_dod = False
144
+ for index, entry in enumerate(entries, start=1):
145
+ missing = sorted(field for field in REQUIRED_FIELDS if field not in entry)
146
+ if missing:
147
+ violations.append(
148
+ _line_violation(
149
+ "QUALITY-REVIEW-SCHEMA-001",
150
+ evidence_path,
151
+ index,
152
+ f"quality-review record is missing fields: {', '.join(missing)}",
153
+ "Include id, source, type, status, files, evidence, and verification.",
154
+ )
155
+ )
156
+ continue
157
+
158
+ entry_type = str(entry.get("type") or "").strip()
159
+ status = str(entry.get("status") or "").strip()
160
+ if entry_type not in ALLOWED_TYPES:
161
+ violations.append(
162
+ _line_violation(
163
+ "QUALITY-REVIEW-TYPE-001",
164
+ evidence_path,
165
+ index,
166
+ f"unsupported quality-review type: {entry_type}",
167
+ "Use checklist, machine_warning, or dod.",
168
+ )
169
+ )
170
+ if status not in ALLOWED_STATUSES:
171
+ violations.append(
172
+ _line_violation(
173
+ "QUALITY-REVIEW-STATUS-002",
174
+ evidence_path,
175
+ index,
176
+ f"unsupported quality-review status: {status}",
177
+ "Use pass, fail, not_applicable, or acknowledged_warning.",
178
+ )
179
+ )
180
+ if status == "fail":
181
+ violations.append(
182
+ _line_violation(
183
+ "QUALITY-REVIEW-STATUS-001",
184
+ evidence_path,
185
+ index,
186
+ "quality-review record is still failing",
187
+ "Resolve the finding or keep the task out of complete.",
188
+ )
189
+ )
190
+ if entry_type == "dod" and status in {"pass", "not_applicable"}:
191
+ has_dod = True
192
+
193
+ violations.extend(_validate_files(entry, evidence_path, index))
194
+ violations.extend(_validate_evidence(entry, evidence_path, index))
195
+ violations.extend(_validate_verification(entry, evidence_path, index))
196
+
197
+ if not has_dod:
198
+ violations.append(
199
+ _violation(
200
+ "QUALITY-REVIEW-DOD-001",
201
+ str(evidence_path),
202
+ "quality-review.jsonl must include Definition of Done evidence",
203
+ "Add a dod record for .cowork-flow/spec/references/definition-of-done.md.",
204
+ )
205
+ )
206
+ return violations
207
+
208
+
209
+ def _validate_files(entry: dict, evidence_path: Path, index: int) -> list[dict]:
210
+ files = entry.get("files")
211
+ if _non_empty_string_list(files):
212
+ return []
213
+ return [
214
+ _line_violation(
215
+ "QUALITY-REVIEW-FILES-001",
216
+ evidence_path,
217
+ index,
218
+ "quality-review files must be a non-empty list of paths",
219
+ "List the reviewed changed files for this evidence record.",
220
+ )
221
+ ]
222
+
223
+
224
+ def _validate_evidence(entry: dict, evidence_path: Path, index: int) -> list[dict]:
225
+ evidence = str(entry.get("evidence") or "").strip()
226
+ normalized = evidence.casefold()
227
+ if len(evidence) >= 24 and normalized not in VAGUE_EVIDENCE:
228
+ return []
229
+ return [
230
+ _line_violation(
231
+ "QUALITY-REVIEW-EVIDENCE-001",
232
+ evidence_path,
233
+ index,
234
+ "quality-review evidence is too vague",
235
+ "Describe the concrete file, rule, finding, or verification result.",
236
+ )
237
+ ]
238
+
239
+
240
+ def _validate_verification(entry: dict, evidence_path: Path, index: int) -> list[dict]:
241
+ verification = entry.get("verification")
242
+ if _non_empty_string_list(verification):
243
+ return []
244
+ return [
245
+ _line_violation(
246
+ "QUALITY-REVIEW-VERIFICATION-001",
247
+ evidence_path,
248
+ index,
249
+ "quality-review verification must be a non-empty list of commands or reasons",
250
+ "Record executed commands, or an explicit reason a command was not applicable.",
251
+ )
252
+ ]
253
+
254
+
255
+ def _validate_machine_warning_coverage(
256
+ repo_root: Path,
257
+ entries: list[dict],
258
+ ) -> list[dict]:
259
+ warnings = collect_machine_checks(Path(repo_root))
260
+ if not warnings:
261
+ return []
262
+
263
+ acknowledgements = _machine_warning_acknowledgements(entries)
264
+ violations: list[dict] = []
265
+ for warning in warnings:
266
+ rule_id = str(warning.get("rule_id") or "")
267
+ file_path = str(warning.get("file") or "")
268
+ if (rule_id, file_path) in acknowledgements:
269
+ continue
270
+ violations.append(
271
+ _violation(
272
+ "QUALITY-REVIEW-MACHINE-WARNING-001",
273
+ file_path,
274
+ f"machine warning {rule_id} is not addressed in quality-review.jsonl",
275
+ "Fix the warning or add a machine_warning record with status acknowledged_warning.",
276
+ )
277
+ )
278
+ return violations
279
+
280
+
281
+ def _machine_warning_acknowledgements(entries: Iterable[dict]) -> set[tuple[str, str]]:
282
+ acknowledgements: set[tuple[str, str]] = set()
283
+ for entry in entries:
284
+ if entry.get("type") != "machine_warning":
285
+ continue
286
+ if entry.get("status") != "acknowledged_warning":
287
+ continue
288
+ source = str(entry.get("source") or entry.get("rule_id") or "").strip()
289
+ files = entry.get("files")
290
+ if not source or not isinstance(files, list):
291
+ continue
292
+ for file_path in files:
293
+ if isinstance(file_path, str) and file_path.strip():
294
+ acknowledgements.add((source, file_path.strip()))
295
+ return acknowledgements
296
+
297
+
298
+ def _non_empty_string_list(value: object) -> bool:
299
+ return (
300
+ isinstance(value, list)
301
+ and bool(value)
302
+ and all(isinstance(item, str) and bool(item.strip()) for item in value)
303
+ )
304
+
305
+
306
+ def _line_violation(
307
+ rule_id: str,
308
+ path: Path,
309
+ line: int,
310
+ message: str,
311
+ fix_hint: str,
312
+ ) -> dict:
313
+ violation = _violation(rule_id, str(path), message, fix_hint)
314
+ violation["line"] = line
315
+ return violation
316
+
317
+
318
+ def _violation(
319
+ rule_id: str,
320
+ file_path: str,
321
+ message: str,
322
+ fix_hint: str,
323
+ ) -> dict:
324
+ return {
325
+ "rule_id": rule_id,
326
+ "type": "quality_review",
327
+ "severity": "block",
328
+ "passed": False,
329
+ "message": message,
330
+ "file": file_path,
331
+ "fix_hint": fix_hint,
332
+ }
@@ -14,7 +14,7 @@ Only machine-decidable checks run here as hard blocks:
14
14
  A separate ``collect_machine_checks`` helper is exposed for callers that want
15
15
  additional regex-style warnings (hardcoded secrets, debug prints, silent
16
16
  excepts, trailing comments...) WITHOUT hard-blocking the workflow. These are
17
- emitted at severity=advisory so they can be rendered for the LLM without being a
17
+ emitted at severity=warn so they can be rendered for the LLM without being a
18
18
  wall the user must satisfy.
19
19
  """
20
20
 
@@ -163,7 +163,7 @@ def validate_coding_standards(
163
163
  Approach A keeps only the UTF-8 / IO-encoding check here. All natural
164
164
  language rules authored in the spec tree are surfaced to the LLM via the
165
165
  checklist in ``get_coding_standards_summary``; they do not block the
166
- workflow from this function. Optional advisory warnings live in
166
+ workflow from this function. Optional machine warnings live in
167
167
  ``collect_machine_checks``.
168
168
  """
169
169
  return list(validate_changed_files(repo_root, collect_changed_files(repo_root)))
@@ -173,7 +173,7 @@ def collect_machine_checks(
173
173
  repo_root: Path,
174
174
  task_dir: Path | None = None,
175
175
  ) -> list[dict]:
176
- """Emit regex-style advisory signals (severity=advisory).
176
+ """Emit regex-style machine warning signals (severity=warn).
177
177
 
178
178
  The LLM decides how to act on them; the workflow never blocks on a hit.
179
179
  Kept separate from ``validate_coding_standards`` so callers can choose
@@ -185,6 +185,14 @@ def collect_machine_checks(
185
185
  return violations
186
186
 
187
187
 
188
+ def validate_machine_checks(
189
+ repo_root: Path,
190
+ task_dir: Path | None = None,
191
+ ) -> list[dict]:
192
+ """Gate binding for optional quality machine-check warnings."""
193
+ return collect_machine_checks(repo_root, task_dir)
194
+
195
+
188
196
  def _changed_machine_check_files(repo_root: Path) -> Sequence[object]:
189
197
  try:
190
198
  return collect_changed_files(repo_root)
@@ -289,7 +297,7 @@ def _adv(
289
297
  return {
290
298
  "rule_id": rule_id,
291
299
  "type": "machine_check",
292
- "severity": "advisory",
300
+ "severity": "warn",
293
301
  "passed": False,
294
302
  "message": message,
295
303
  "file": file_path,
@@ -357,7 +365,7 @@ def main() -> None:
357
365
  parser.add_argument("--list", action="store_true", help="List parsed spec rules")
358
366
  parser.add_argument("--validate", action="store_true")
359
367
  parser.add_argument("--machine-checks", action="store_true",
360
- help="Also emit advisory machine-check warnings")
368
+ help="Also emit machine-check warnings")
361
369
 
362
370
  args = parser.parse_args()
363
371
  repo_root = Path(args.repo_root).resolve()
@@ -7,7 +7,8 @@
7
7
  1. Read the task decision anchor, plan, `check.jsonl`, registered context, and current diff.
8
8
  2. Review behavior, caller/callee contracts, persisted state, templates, specs, and scope.
9
9
  3. Review test intent, reject shallow tests, run focused tests that fail for meaningful behavior breaks, then broader validation for shared runtime changes.
10
- 4. Reject shallow tests and unresolved blockers; fix only in-scope issues.
10
+ 4. Verify `quality-review.jsonl` covers quality checklist, machine warning, and Definition of Done evidence.
11
+ 5. Reject shallow tests and unresolved blockers; fix only in-scope issues.
11
12
 
12
13
  ## Output
13
14
 
@@ -18,10 +19,28 @@ Report the same core fields on every Host:
18
19
  - `findings`
19
20
  - `test_intent_review`
20
21
  - `verification`
22
+ - `quality_review`
21
23
  - `resolution`
22
24
 
23
25
  Do not claim completion from intent or unexecuted commands.
24
26
 
27
+ ## Quality Evidence
28
+
29
+ `quality-review.jsonl` is the task-local audit trail for quality review. Each
30
+ record must include `id`, `source`, `type`, `status`, `files`, `evidence`, and
31
+ `verification`.
32
+
33
+ - `source`: a spec/checklist path or machine warning rule ID.
34
+ - `type`: `checklist`, `machine_warning`, or `dod`.
35
+ - `status`: `pass`, `fail`, `not_applicable`, or `acknowledged_warning`.
36
+ - `evidence`: concrete file/rule reasoning, not generic "checked" claims.
37
+ - `verification`: exact commands run or an explicit reason a command was not applicable.
38
+
39
+ Backend/frontend natural-language markdown supplies review checklist context,
40
+ not dynamic hard validators. Deterministic hard gates cover machine-decidable
41
+ checks; machine warning output must be fixed or acknowledged in
42
+ `quality-review.jsonl` before completion.
43
+
25
44
  ## Simplification Review
26
45
 
27
46
  When a change exceeds 50 lines or readability is a finding:
@@ -49,6 +49,12 @@ Rules:
49
49
  - Read the task directory from the bound runtime context.
50
50
  - Read `<task>/decision-anchor.md`, the plan file linked from this task (check `<task>/task.json` `relatedFiles` for a plan path, or search `.cowork-flow/plans/`), `<task>/check.jsonl`, each JSONL `file` entry, and
51
51
  current `git diff`.
52
+ - Read `<task>/quality-review.jsonl` if present and verify checklist, machine
53
+ warning, and Definition of Done evidence.
54
+ - Treat backend/frontend natural-language specs as review checklist context,
55
+ not dynamic hard validators.
56
+ - Fix machine warning findings or require acknowledged warning evidence in
57
+ `<task>/quality-review.jsonl`.
52
58
  - Check behavior, tests, spec sync, and scope.
53
59
  - Fix only in-scope issues.
54
60
  - Report changed files and exact verification commands.
@@ -62,6 +62,11 @@ Then read the relevant spec directory:
62
62
  - Backend work: `.cowork-flow/spec/backend/index.md` (and all linked docs)
63
63
  - Frontend work: `.cowork-flow/spec/frontend/index.md` (and all linked docs)
64
64
 
65
+ Backend/frontend natural-language specs are review checklist context, not
66
+ dynamic hard validators. Deterministic gates handle machine-decidable checks;
67
+ machine warning findings must be fixed or acknowledged in
68
+ `quality-review.jsonl`.
69
+
65
70
  ---
66
71
 
67
72
  ## Coding Gates (Hard Constraints)
@@ -163,6 +168,7 @@ Before marking any change complete, you MUST verify:
163
168
  3. Error paths, permission paths, data boundaries are verified
164
169
  4. New conventions, contracts, or migration impacts are documented in spec or task records
165
170
  5. Failed verification is NOT worked around by shrinking assertions, deleting tests, or skipping critical paths
171
+ 6. `quality-review.jsonl` records checklist, machine warning, and Definition of Done evidence
166
172
 
167
173
  ---
168
174
 
@@ -197,8 +203,9 @@ You MUST NOT do any of the following:
197
203
  7. Apply coding gates — verify each gate before proceeding
198
204
  8. Implement changes within assigned scope
199
205
  9. Run verification commands (compile, lint, test, build, type-check)
200
- 10. Report changed files and exact verification commands
201
- 11. Do NOT run task start, task finish, task archive, unscoped resume, commit, or push
206
+ 10. Write `<task>/quality-review.jsonl` with checklist, machine warning, and Definition of Done evidence
207
+ 11. Report changed files and exact verification commands
208
+ 12. Do NOT run task start, task finish, task archive, unscoped resume, commit, or push
202
209
 
203
210
  ---
204
211
 
@@ -208,6 +215,11 @@ Rules:
208
215
  - Read `<task>/decision-anchor.md`, `<task>/implement.jsonl`,
209
216
  and each JSONL `file` entry.
210
217
  - Read the plan file linked from this task. Follow the plan steps in order.
218
+ - Read quality source entries from context; natural-language specs are not dynamic hard validators.
219
+ - Fix machine warning findings or record acknowledged warning evidence in
220
+ `<task>/quality-review.jsonl`.
221
+ - Record Definition of Done and quality checklist evidence in
222
+ `<task>/quality-review.jsonl`.
211
223
  - Keep edits inside the assigned scope.
212
224
  - Report changed files and exact verification commands.
213
225
  - Do not use the `task` tool or invoke subagents.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cowork-flow",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "AI 协作工作流引擎:任务生命周期、子代理调度、门禁与状态注入。将 cowork-flow 的完整工作流带入 ZCode。",
5
5
  "author": {
6
6
  "name": "fisklikewater"
@@ -1,23 +0,0 @@
1
- # 后端数据库规范
2
-
3
- ## 目标
4
-
5
- - 数据模型、迁移、查询方式保持一致。
6
- - 数据变更可审计、可回滚、可复现。
7
- - 事务边界与业务动作一致,不用扩大事务掩盖建模问题。
8
-
9
- ## 默认规则
10
-
11
- - 表结构变更必须通过迁移文件、版本化脚本或仓库既有机制管理。
12
- - 查询优先使用仓库统一的数据访问方式;没有统一封装时,保持查询入口集中且可测试。
13
- - 写操作应明确幂等性、并发影响、失败补偿和重试边界。
14
- - 审计字段、逻辑删除、版本号、租户隔离等约定必须在同一数据域内一致。
15
- - 原始 SQL、批量更新、跨表聚合和长事务都需要说明索引、锁、性能和回滚影响。
16
-
17
- ## 检查项
18
-
19
- - 新表或新集合是否补齐主键、唯一约束、索引和必要审计信息。
20
- - 复杂查询是否避免 N+1、隐式全表扫描和不受控分页。
21
- - 事务中是否包含外部调用、慢查询或不必要的长时间锁持有。
22
- - 数据迁移是否考虑历史数据、重复执行、失败恢复和线上回滚。
23
- - 错误处理是否区分数据不存在、数据冲突、约束失败和系统异常。
@@ -1,27 +0,0 @@
1
- # 后端目录结构规范
2
-
3
- ## 目标
4
-
5
- - 模块职责清晰
6
- - 包结构稳定
7
- - 新人和 AI 能快速定位代码
8
-
9
- ## 推荐做法
10
-
11
- - 按业务能力或边界拆模块,不按“工具类型”滥拆
12
- - Controller / API 只做参数接收、鉴权入口和响应编排
13
- - Service / UseCase 承接业务规则
14
- - Repository / DAO 承接持久化访问
15
- - Domain Model / Entity / Aggregate 保持边界清晰
16
-
17
- ## 命名建议
18
-
19
- - 模块名体现业务边界,不体现实现细节
20
- - 包名与目录名统一小写
21
- - 同一层命名保持后缀一致,例如 `Controller`、`Service`、`Repository`
22
-
23
- ## 不建议
24
-
25
- - 一个模块同时承担多个无关业务
26
- - 在 Controller 中堆业务逻辑
27
- - 在公共模块中混入业务特化逻辑
@@ -1,27 +0,0 @@
1
- ## 字符集编码要求
2
-
3
- ### Windows 平台编码规范
4
-
5
- - **环境初始化**:在执行任何 `PowerShell` 脚本或命令前,优先执行
6
- `$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8`,强制统一当前会话的输入输出编码。
7
- - **绝对强制使用 UTF-8**:包含但不限于修改源代码、读写配置、生成文本、日志记录等所有涉及字符流输入输出的操作,都必须显式指定
8
- `UTF-8` 编码,严禁依赖系统默认编码(如 `GBK/CP936`)。
9
- - **PowerShell 读写规范**:
10
- - 使用 `Get-Content` 和 `Set-Content` 时,必须显式添加 `-Encoding UTF8` 参数。
11
- - 使用 `Out-File` 时,必须显式添加 `-Encoding UTF8` 参数。
12
- - 尽量避免使用重定向符号 `>` 进行文本输出,推荐使用 `Set-Content -Encoding UTF8` 替代。
13
- - **无 BOM 格式约束**:除非目标系统(如旧版 Windows 记事本或特定遗留软件)明确要求,否则生成的 `UTF-8` 文本文件**必须不带
14
- `BOM`
15
- **。在 PowerShell 中,建议使用
16
- `[System.IO.File]::WriteAllText($path, $content, (New-Object System.Text.UTF8Encoding $false))` 来确保无 `BOM` 写入。
17
- - **Python 读写规范**:所有 `open()` 函数调用必须显式包含 `encoding="utf-8"` 参数(例如
18
- `open("file.txt", "r", encoding="utf-8")`)。
19
- - **Node.js 读写规范**:在 `fs.readFile` 或 `fs.writeFile` 中,必须显式指定 `{ encoding: "utf8" }` 选项。
20
- - **Java 读写规范**:
21
- - 严禁使用 `FileReader` 或 `FileWriter`(它们会隐式使用系统默认编码)。必须使用 `FileInputStream` / `FileOutputStream` 配合
22
- `InputStreamReader` / `OutputStreamWriter`,并显式传入 `StandardCharsets.UTF_8`。
23
- - 在使用 `Files.readAllLines` 或 `Files.write` 时,必须显式传入 `StandardCharsets.UTF_8` 参数。
24
- - 涉及 `Scanner` 读取文件时,必须指定 `new Scanner(file, "UTF-8")`。
25
- - **Go 语言读写规范**:使用 `os.Create` 或 `os.OpenFile` 后,建议使用 `bufio` 或 `ioutil` 时确保写入的是 `UTF-8` 字节流;若涉及
26
- Windows 特定 API,需注意转换。
27
- - **文件头检查**:在修改现有文件前,应检查文件当前的编码格式,避免将非 `UTF-8` 文件错误地以 `UTF-8` 解析导致乱码损坏。
@@ -1,20 +0,0 @@
1
- # 后端异常处理规范
2
-
3
- ## 目标
4
-
5
- - 调用方能稳定感知错误
6
- - 内部错误与外部错误边界清晰
7
-
8
- ## 推荐做法
9
-
10
- - 统一定义错误码或错误类型
11
- - 参数校验错误、业务错误、系统错误分层处理
12
- - 对外返回稳定结构,对内保留足够上下文
13
- - 不把底层异常原样泄露给调用方
14
-
15
- ## 典型检查项
16
-
17
- - 是否区分“可预期业务失败”和“系统异常”
18
- - 是否保留 traceId / requestId / correlationId
19
- - 是否有统一异常兜底
20
- - 是否记录了必要但不过量的日志
@@ -1,40 +0,0 @@
1
- # 后端开发规范
2
-
3
- ## 默认基线
4
-
5
- - 后端代码以清晰的业务边界、稳定的接口契约和可验证的行为为核心。
6
- - 规范来源优先级:仓库已落地代码、配置、测试、迁移脚本、接口文档,然后才是本目录通用规则。
7
- - 新增实现应贴合现有架构,不静默引入第二套分层、命名、错误模型或数据访问方式。
8
- - 无法从现有代码判断约定时,采用本目录的保守默认规则,并在任务记录中说明假设。
9
-
10
- ---
11
-
12
- ## 阅读顺序
13
-
14
- | 文档 | 用途 |
15
- |------|------|
16
- | [目录结构](./directory-structure.md) | 模块划分、包结构、命名方式 |
17
- | [数据库规范](./database-guidelines.md) | 实体、迁移、查询、事务 |
18
- | [异常处理](./error-handling.md) | 错误码、异常边界、统一返回 |
19
- | [日志规范](./logging-guidelines.md) | 结构化日志、敏感信息、链路标识 |
20
- | [质量规范](./quality-guidelines.md) | 测试、lint、门禁、禁止模式 |
21
- | [字符集编码规范](./encoding-guidelines.md) | 编码、换行、BOM 和跨平台读写约定 |
22
-
23
- ---
24
-
25
- ## 使用原则
26
-
27
- - 优先遵循仓库现有模式,不新增与现有风格冲突的写法。
28
- - 先查已有公共模块、公共库或基础设施封装,再决定是否新增代码。
29
- - Controller / API 层保持薄入口,业务规则放在服务、用例或领域层。
30
- - 变更接口、数据结构、权限、异步链路或持久化模型时,同步更新调用方、测试和相关文档。
31
- - 涉及跨模块、异步链路、权限边界时,同时阅读 `guides/` 下的思考指引。
32
-
33
- ---
34
-
35
- ## 默认完成标准
36
-
37
- - 关键路径有自动化验证或明确的手工验证记录。
38
- - 错误路径、空值、权限不足、重复提交等边界被显式考虑。
39
- - 运行时配置、数据迁移、兼容性和回滚影响已说明。
40
- - 不把“未运行测试”描述成“测试通过”。
@@ -1,20 +0,0 @@
1
- # 后端日志规范
2
-
3
- ## 目标
4
-
5
- - 便于排查
6
- - 便于追踪链路
7
- - 不泄露敏感信息
8
-
9
- ## 推荐做法
10
-
11
- - 使用结构化日志
12
- - 统一记录请求标识、用户标识、任务标识或链路标识
13
- - 错误日志记录上下文,不重复打印同一异常
14
- - 对账号、令牌、密钥、身份证号、手机号等敏感字段脱敏
15
-
16
- ## 不建议
17
-
18
- - 直接输出完整请求体或完整响应体
19
- - 使用临时 `print` / `console` 式调试输出长期留在主干
20
- - 同一错误在多层重复打印