cowork-flow 0.0.37 → 0.0.39

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 (111) hide show
  1. package/README.md +27 -14
  2. package/package.json +1 -1
  3. package/src/commands/init.js +39 -28
  4. package/src/commands/sync.js +2 -2
  5. package/src/lib/asset-plan.js +127 -0
  6. package/src/lib/copy-template.js +101 -141
  7. package/src/lib/host-assets.js +231 -0
  8. package/src/lib/plan-applier.js +329 -0
  9. package/src/lib/platforms.js +15 -76
  10. package/src/lib/skill-registry.js +503 -0
  11. package/template/.claude/agents/cowork-check.md +10 -1
  12. package/template/.claude/agents/cowork-implement.md +11 -2
  13. package/template/.claude/hooks/inject-workflow-state.py +51 -254
  14. package/template/.codex/agents/cowork-check.toml +12 -3
  15. package/template/.codex/agents/cowork-implement.toml +11 -2
  16. package/template/.codex/agents/default.toml +3 -2
  17. package/template/.codex/agents/explorer.toml +3 -2
  18. package/template/.codex/agents/worker.toml +2 -1
  19. package/template/.codex/hooks/inject-workflow-state.py +46 -265
  20. package/template/.cowork-flow/.version +1 -1
  21. package/template/.cowork-flow/scripts/application/__init__.py +1 -0
  22. package/template/.cowork-flow/scripts/application/batch_execution.py +743 -0
  23. package/template/.cowork-flow/scripts/application/runtime_context_service.py +365 -0
  24. package/template/.cowork-flow/scripts/application/task_archive.py +220 -0
  25. package/template/.cowork-flow/scripts/application/task_context.py +765 -0
  26. package/template/.cowork-flow/scripts/application/task_creation.py +201 -0
  27. package/template/.cowork-flow/scripts/application/task_lifecycle.py +532 -0
  28. package/template/.cowork-flow/scripts/application/task_tree.py +179 -0
  29. package/template/.cowork-flow/scripts/commands/doctor.py +78 -57
  30. package/template/.cowork-flow/scripts/commands/party_mode_v2.py +671 -425
  31. package/template/.cowork-flow/scripts/commands/subagent.py +38 -26
  32. package/template/.cowork-flow/scripts/commands/task.py +535 -1953
  33. package/template/.cowork-flow/scripts/commands/task_archive_commands.py +195 -0
  34. package/template/.cowork-flow/scripts/commands/task_context_commands.py +240 -0
  35. package/template/.cowork-flow/scripts/commands/task_create_command.py +164 -0
  36. package/template/.cowork-flow/scripts/commands/task_navigation.py +407 -0
  37. package/template/.cowork-flow/scripts/commands/task_parser.py +364 -0
  38. package/template/.cowork-flow/scripts/commands/task_support.py +76 -0
  39. package/template/.cowork-flow/scripts/commands/task_tree_commands.py +160 -0
  40. package/template/.cowork-flow/scripts/common/core/execution_context.py +161 -85
  41. package/template/.cowork-flow/scripts/common/core/host_manifest.py +393 -0
  42. package/template/.cowork-flow/scripts/common/core/skill_registry.py +568 -0
  43. package/template/.cowork-flow/scripts/common/gates/coding_standards.py +58 -7
  44. package/template/.cowork-flow/scripts/common/gates/gates.py +323 -46
  45. package/template/.cowork-flow/scripts/common/gates/models.py +196 -0
  46. package/template/.cowork-flow/scripts/common/gates/registry.py +79 -0
  47. package/template/.cowork-flow/scripts/common/gates/tdd_evidence.py +13 -13
  48. package/template/.cowork-flow/scripts/common/gates/validate_coding_standards.py +104 -62
  49. package/template/.cowork-flow/scripts/common/gates/validate_implementation.py +39 -22
  50. package/template/.cowork-flow/scripts/common/gates/validate_rules.py +223 -40
  51. package/template/.cowork-flow/scripts/common/git/git_context.py +216 -182
  52. package/template/.cowork-flow/scripts/common/host/__init__.py +1 -0
  53. package/template/.cowork-flow/scripts/common/host/workflow_state_hook.py +303 -0
  54. package/template/.cowork-flow/scripts/common/storage/__init__.py +1 -0
  55. package/template/.cowork-flow/scripts/common/storage/operation_log.py +72 -0
  56. package/template/.cowork-flow/scripts/common/storage/state_store.py +279 -0
  57. package/template/.cowork-flow/scripts/common/storage/unit_of_work.py +214 -0
  58. package/template/.cowork-flow/scripts/common/task/active_task.py +93 -135
  59. package/template/.cowork-flow/scripts/common/task/batch_mode.py +33 -120
  60. package/template/.cowork-flow/scripts/common/task/decision_review.py +85 -0
  61. package/template/.cowork-flow/scripts/common/task/readiness.py +9 -15
  62. package/template/.cowork-flow/scripts/common/task/task_repository.py +156 -0
  63. package/template/.cowork-flow/scripts/run.py +24 -0
  64. package/template/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
  65. package/template/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
  66. package/template/.cowork-flow/spec/contracts/workflow-state-templates.md +1 -1
  67. package/template/.cowork-flow/spec/protocols/decision-review.md +28 -0
  68. package/template/.cowork-flow/spec/protocols/review.md +34 -0
  69. package/template/.cowork-flow/spec/protocols/spec-maintenance.md +16 -0
  70. package/template/.cowork-flow/spec/protocols/tdd.md +30 -0
  71. package/template/.cowork-flow/spec/references/definition-of-done.md +4 -4
  72. package/template/.cowork-flow/spec/references/orchestration-patterns.md +1 -1
  73. package/template/.cowork-flow/spec/runtime/contract-registry.json +25 -0
  74. package/template/.cowork-flow/spec/runtime/host-assets.json +214 -0
  75. package/template/.cowork-flow/spec/runtime/index.md +8 -0
  76. package/template/.cowork-flow/spec/runtime/rules.json +61 -10
  77. package/template/.cowork-flow/spec/runtime/skill-registry.json +397 -0
  78. package/template/.cowork-flow/spec/schemas/host-assets.schema.json +173 -0
  79. package/template/.cowork-flow/spec/schemas/rules.schema.json +10 -1
  80. package/template/.cowork-flow/spec/schemas/skill-registry.schema.json +202 -0
  81. package/template/.cowork-flow/workflow.md +18 -13
  82. package/template/.opencode/agents/cowork-check.md +11 -0
  83. package/template/.opencode/agents/cowork-implement.md +16 -1
  84. package/template/.zcode/.zcode-plugin/plugin.json +1 -1
  85. package/template/.zcode/hooks/inject-context.js +3 -85
  86. package/template/.zcode/hooks/inject-context.selfcheck.mjs +6 -6
  87. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
  88. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
  89. package/template/.zcode/scaffold/.cowork-flow/spec/runtime/rules.json +61 -10
  90. package/template/.zcode/scaffold/.cowork-flow/spec/schemas/rules.schema.json +10 -1
  91. package/template/.zcode/scaffold/.cowork-flow/workflow.md +18 -13
  92. package/template/.zcode/scaffold/AGENTS.md +18 -8
  93. package/template/AGENTS.md +1 -1
  94. package/template/skills/batch-mode/SKILL.md +140 -76
  95. package/template/skills/brainstorming/SKILL.md +2 -2
  96. package/template/skills/cowork-flow/SKILL.md +42 -0
  97. package/template/skills/party-mode/SHARED-BOUNDARIES.md +1 -1
  98. package/template/skills/party-mode/SKILL.md +48 -119
  99. package/template/.cowork-flow/scripts/common/gates/spec_validator.py +0 -53
  100. package/template/.cowork-flow/scripts/common/gates/validate_jsonl.py +0 -32
  101. package/template/skills/before-dev/SKILL.md +0 -41
  102. package/template/skills/check/SKILL.md +0 -53
  103. package/template/skills/check/simplification-guide.md +0 -47
  104. package/template/skills/continue/SKILL.md +0 -29
  105. package/template/skills/doubt-review/SKILL.md +0 -118
  106. package/template/skills/finish-work/SKILL.md +0 -32
  107. package/template/skills/party-mode-v2/SKILL.md +0 -75
  108. package/template/skills/start/SKILL.md +0 -78
  109. package/template/skills/tdd/SKILL.md +0 -74
  110. package/template/skills/update-spec/SKILL.md +0 -39
  111. package/template/skills/using-cowork-flow/SKILL.md +0 -80
@@ -3,34 +3,31 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- import hashlib
7
6
  import json
8
7
  import os
9
- import re
10
8
  import sys
11
9
  from pathlib import Path
12
10
  from typing import Any
13
11
 
14
- TAG_RE = re.compile(
15
- r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n(.*?)\n\s*\[/workflow-state:\1\]",
16
- re.DOTALL,
17
- )
18
- DEFAULT_CONTRACT_REGISTRY = {
19
- "contracts": [
20
- {
21
- "id": "RUNTIME_CONTEXT_DISPATCH_V2",
22
- "path": ".cowork-flow/spec/contracts/subagent-dispatch.md",
23
- "digest": [
24
- "Formal subagent work is keyed by cowork_runtime_context_id.",
25
- "Explicit shim bind records bound_context_key before formal output is accepted.",
26
- ],
27
- "readWhen": ["before formal subagent dispatch", "when checking subagent health"],
28
- },
29
- ]
30
- }
12
+
13
+ def _read_input() -> dict[str, Any]:
14
+ raw = sys.stdin.buffer.read()
15
+ if not raw.strip():
16
+ return {}
17
+ try:
18
+ data = json.loads(raw.decode("utf-8-sig"))
19
+ except (UnicodeDecodeError, json.JSONDecodeError, ValueError):
20
+ return {}
21
+ if not isinstance(data, dict):
22
+ return {}
23
+ if "claude_session_id" not in data:
24
+ session_id = data.get("session_id")
25
+ if isinstance(session_id, str) and session_id.strip():
26
+ data["claude_session_id"] = session_id
27
+ return data
31
28
 
32
29
 
33
- def _find_repo_root(start: Path) -> Path | None:
30
+ def _find_root(start: Path) -> Path | None:
34
31
  current = start.resolve()
35
32
  while True:
36
33
  if (current / ".cowork-flow").is_dir():
@@ -40,250 +37,50 @@ def _find_repo_root(start: Path) -> Path | None:
40
37
  current = current.parent
41
38
 
42
39
 
43
- def _read_hook_input() -> dict[str, Any]:
44
- try:
45
- raw = sys.stdin.buffer.read()
46
- except AttributeError:
47
- text = sys.stdin.read()
48
- else:
49
- if not raw.strip():
50
- return {}
51
- try:
52
- text = raw.decode("utf-8-sig")
53
- except UnicodeDecodeError:
54
- encoding = getattr(sys.stdin, "encoding", None) or "utf-8"
55
- text = raw.decode(encoding, errors="replace")
56
- if not text.strip():
57
- return {}
58
- try:
59
- data = json.loads(text)
60
- except (json.JSONDecodeError, ValueError):
61
- return {}
62
- return data if isinstance(data, dict) else {}
63
-
64
-
65
- def _hook_event_name(hook_input: dict[str, Any]) -> str:
66
- value = hook_input.get("hook_event_name") or hook_input.get("hookEventName")
67
- if isinstance(value, str) and value.strip():
68
- return value.strip()
69
- return "UserPromptSubmit"
70
-
71
-
72
- def _normalize_hook_input(hook_input: dict[str, Any]) -> dict[str, Any]:
73
- normalized = dict(hook_input)
74
- if "claude_session_id" not in normalized:
75
- session_id = normalized.get("session_id")
76
- if isinstance(session_id, str) and session_id.strip():
77
- normalized["claude_session_id"] = session_id
78
- return normalized
79
-
80
-
81
- def _load_breadcrumbs(root: Path) -> dict[str, str]:
82
- workflow = root / ".cowork-flow" / "spec" / "contracts" / "workflow-state-templates.md"
83
- try:
84
- text = workflow.read_text(encoding="utf-8")
85
- except OSError:
86
- return {}
87
- return {match.group(1): match.group(2).strip() for match in TAG_RE.finditer(text)}
88
-
89
-
90
- def _as_string_list(value: Any) -> list[str]:
91
- if not isinstance(value, list):
92
- return []
93
- return [item for item in value if isinstance(item, str) and item.strip()]
94
-
95
-
96
- def _load_contract_registry(root: Path) -> tuple[list[dict[str, Any]], str | None]:
97
- registry_file = root / ".cowork-flow" / "spec" / "runtime" / "contract-registry.json"
98
- try:
99
- data = json.loads(registry_file.read_text(encoding="utf-8"))
100
- except OSError:
101
- data = DEFAULT_CONTRACT_REGISTRY
102
- warning = f"contract registry unavailable at {registry_file}; using fallback digest"
103
- except json.JSONDecodeError:
104
- data = DEFAULT_CONTRACT_REGISTRY
105
- warning = f"contract registry invalid at {registry_file}; using fallback digest"
106
- else:
107
- warning = None
108
- contracts = data.get("contracts") if isinstance(data, dict) else None
109
- if not isinstance(contracts, list):
110
- contracts = DEFAULT_CONTRACT_REGISTRY["contracts"]
111
- warning = warning or f"contract registry has no contracts array at {registry_file}; using fallback digest"
112
- return [contract for contract in contracts if isinstance(contract, dict)], warning
113
-
114
-
115
- def _contract_fingerprint(root: Path, contracts: list[dict[str, Any]]) -> str:
116
- digest = hashlib.sha256()
117
- digest.update(json.dumps(contracts, ensure_ascii=False, sort_keys=True).encode("utf-8"))
118
- for contract in contracts:
119
- path = contract.get("path")
120
- if not isinstance(path, str) or not path.strip():
121
- continue
122
- try:
123
- digest.update((root / path).read_bytes())
124
- except OSError:
125
- digest.update(f"missing:{path}".encode("utf-8"))
126
- return digest.hexdigest()[:16]
127
-
128
-
129
- def _build_contract_digest(root: Path) -> str:
130
- contracts, warning = _load_contract_registry(root)
131
- fingerprint = _contract_fingerprint(root, contracts)
132
- lines = [
133
- '<cowork-runtime host="claude-code" adapter="claude-code.hooks">',
134
- f'<contract-digest fingerprint="{fingerprint}">',
135
- "policy: repeat this short digest every hook; read full spec files only before listed actions.",
136
- ]
137
- if warning:
138
- lines.append(f"warning: {warning}")
139
- for contract in contracts:
140
- contract_id = contract.get("id")
141
- path = contract.get("path")
142
- if not isinstance(contract_id, str) or not contract_id.strip():
143
- continue
144
- path_text = path if isinstance(path, str) and path.strip() else "<missing-path>"
145
- lines.append(f"- {contract_id}: {path_text}")
146
- for item in _as_string_list(contract.get("digest"))[:2]:
147
- lines.append(f" digest: {item}")
148
- read_when = _as_string_list(contract.get("readWhen"))
149
- if read_when:
150
- lines.append(f" read_before: {'; '.join(read_when)}")
151
- lines.extend(["</contract-digest>", "</cowork-runtime>"])
152
- return "\n".join(lines)
153
-
154
-
155
- def _load_common(root: Path) -> None:
156
- scripts_dir = root / ".cowork-flow" / "scripts"
157
- if str(scripts_dir) not in sys.path:
158
- sys.path.insert(0, str(scripts_dir))
159
-
160
-
161
- def _get_active_task(root: Path, hook_input: dict[str, Any]) -> tuple[str | None, str, str]:
162
- _load_common(root)
163
- try:
164
- from common.task.active_task import get_active_task # type: ignore[import-not-found]
165
- except Exception:
166
- return None, "no_task", "unavailable"
167
-
168
- active = get_active_task(root, hook_input)
169
- if not active.task_path:
170
- return None, "no_task", active.source
171
-
172
- task_dir = root / active.task_path
173
- task_json = task_dir / "task.json"
174
- try:
175
- data = json.loads(task_json.read_text(encoding="utf-8"))
176
- except (OSError, json.JSONDecodeError):
177
- return active.task_path, "stale", active.source
178
-
179
- status = data.get("status")
180
- if not isinstance(status, str) or not status.strip():
181
- status = "unknown"
182
- return active.task_path, status.strip(), active.source
183
-
184
-
185
- def _resolve_runtime_context(root: Path, hook_input: dict[str, Any]) -> tuple[dict[str, Any] | None, str | None]:
186
- _load_common(root)
187
- try:
188
- from common.task.active_task import ( # type: ignore[import-not-found]
189
- bind_runtime_context,
190
- read_runtime_context,
191
- resolve_runtime_context_id,
192
- )
193
- except Exception:
194
- return None, None
195
-
196
- runtime_context_id = resolve_runtime_context_id(hook_input)
197
- if not runtime_context_id:
198
- return None, None
199
-
200
- context = read_runtime_context(root, runtime_context_id)
201
- if not context or context.get("scope") != "subagent" or context.get("status") == "closed":
202
- return None, runtime_context_id
203
-
204
- bound = bind_runtime_context(root, runtime_context_id, values=hook_input)
205
- return bound or context, runtime_context_id
206
-
207
-
208
- def _subagent_runtime_lines(context: dict[str, Any]) -> list[str]:
209
- assignment = context.get("assignment") if isinstance(context.get("assignment"), dict) else {}
210
- lines = [
211
- f"Runtime context: {context.get('runtime_context_id')}",
212
- f"Agent: {context.get('agent_type') or 'unknown'}",
213
- "Scope: subagent",
214
- "Do not run start/resume/task start/archive/commit/spawn.",
215
- ]
216
- goal = assignment.get("goal") if isinstance(assignment, dict) else None
217
- if isinstance(goal, str) and goal.strip():
218
- lines.append(f"Goal: {goal.strip()}")
219
- return lines
220
-
221
-
222
- def _build_context(
223
- root: Path,
224
- task_path: str | None,
225
- status: str,
226
- source: str,
227
- breadcrumbs: dict[str, str],
228
- extra_lines: list[str] | None = None,
229
- ) -> str:
230
- body = breadcrumbs.get(status) or "Refer to .cowork-flow/workflow.md for the current step."
231
- if extra_lines:
232
- body = "\n".join([body, *extra_lines])
233
- if task_path is None:
234
- header = f"Status: {status}\nSource: {source}"
235
- else:
236
- header = f"Task: {task_path}\nStatus: {status}\nSource: {source}"
237
-
238
- return "\n\n".join(
239
- [
240
- "<claude-code-runtime>\nhooks: UserPromptSubmit, SessionStart\n</claude-code-runtime>",
241
- _build_contract_digest(root),
242
- f"<workflow-state>\n{header}\n{body}\n</workflow-state>",
243
- ]
244
- )
245
-
246
-
247
40
  def main() -> int:
248
- if os.environ.get("COWORK_FLOW_HOOKS") == "0" or os.environ.get("COWORK_FLOW_DISABLE_HOOKS") == "1":
41
+ if (
42
+ os.environ.get("COWORK_FLOW_HOOKS") == "0"
43
+ or os.environ.get("COWORK_FLOW_DISABLE_HOOKS") == "1"
44
+ ):
249
45
  return 0
250
-
251
- hook_input = _normalize_hook_input(_read_hook_input())
46
+ hook_input = _read_input()
252
47
  cwd_value = hook_input.get("cwd")
253
- cwd = Path(cwd_value) if isinstance(cwd_value, str) and cwd_value.strip() else Path.cwd()
254
- root = _find_repo_root(cwd)
48
+ cwd = (
49
+ Path(cwd_value)
50
+ if isinstance(cwd_value, str) and cwd_value.strip()
51
+ else Path.cwd()
52
+ )
53
+ root = _find_root(cwd)
255
54
  if root is None:
256
55
  return 0
257
-
258
- event_name = _hook_event_name(hook_input)
259
- breadcrumbs = _load_breadcrumbs(root)
260
- runtime_context, runtime_context_id = _resolve_runtime_context(root, hook_input)
261
- extra_lines: list[str] | None = None
262
- if runtime_context is not None:
263
- task_dir = runtime_context.get("task_dir")
264
- task_path = task_dir.strip() if isinstance(task_dir, str) and task_dir.strip() else None
265
- status = "delegated_subtask"
266
- source = f"runtime-context:{runtime_context.get('runtime_context_id')}"
267
- extra_lines = _subagent_runtime_lines(runtime_context)
268
- elif runtime_context_id:
269
- task_path = None
270
- status = "delegated_subtask"
271
- source = f"runtime-context-invalid:{runtime_context_id}"
272
- extra_lines = [
273
- f"Runtime context: {runtime_context_id}",
274
- "Scope: subagent",
275
- "Runtime context is missing, closed, or invalid. Do not run start/resume/task start/archive/commit/spawn.",
276
- ]
277
- else:
278
- task_path, status, source = _get_active_task(root, hook_input)
279
- additional_context = _build_context(root, task_path, status, source, breadcrumbs, extra_lines)
280
-
56
+ scripts_dir = root / ".cowork-flow" / "scripts"
57
+ sys.path.insert(0, str(scripts_dir))
58
+ from common.host.workflow_state_hook import build_hook_context
59
+
60
+ context = build_hook_context(
61
+ root,
62
+ hook_input,
63
+ host="claude-code",
64
+ adapter="claude-code.hooks",
65
+ preamble=(
66
+ (
67
+ "<claude-code-runtime>\n"
68
+ "hooks: UserPromptSubmit, SessionStart\n"
69
+ "</claude-code-runtime>"
70
+ ),
71
+ ),
72
+ )
73
+ event_name = (
74
+ hook_input.get("hook_event_name")
75
+ or hook_input.get("hookEventName")
76
+ or "UserPromptSubmit"
77
+ )
281
78
  print(
282
79
  json.dumps(
283
80
  {
284
81
  "hookSpecificOutput": {
285
82
  "hookEventName": event_name,
286
- "additionalContext": additional_context,
83
+ "additionalContext": context,
287
84
  }
288
85
  },
289
86
  ensure_ascii=False,
@@ -32,15 +32,24 @@ Load context before checking:
32
32
  5. Read `git diff`.
33
33
  6. Include `test_intent_review` in the review output for meaningful behavior breaks coverage and shallow tests rejection.
34
34
 
35
+ Authoritative internal protocols:
36
+ - `.cowork-flow/spec/protocols/review.md`
37
+ - `.cowork-flow/spec/protocols/decision-review.md`
38
+ - `.cowork-flow/spec/protocols/spec-maintenance.md`
39
+
40
+ Apply their output contracts exactly. Review output must preserve
41
+ `acceptanceId`, `findings`, `test_intent_review`, `resolution`, and
42
+ `specUpdates`.
43
+
35
44
  Rules:
36
45
  - Fix issues directly when they are clearly in scope.
37
46
  - MUST NOT spawn, wait for, list, or close other agents.
38
47
  - MUST NOT commit, archive, or mutate cowork-flow task state.
39
48
  - Report findings, changed files, and exact verification commands.
40
- - Include test intent findings that map tests back to PRD acceptance or regression behavior.
41
- - BEFORE declaring PRD acceptance passed, run the spec-driven coding gate and
49
+ - Include test intent findings that map tests back to decision-anchor acceptance criteria or regression behavior.
50
+ - BEFORE declaring decision-anchor acceptance passed, run the spec-driven coding gate and
42
51
  treat a nonzero exit as a hard blocker:
43
- ./.cowork-flow/run python .cowork-flow/scripts/common/gates/validate_coding_standaries.py --validate --repo-root .
52
+ ./.cowork-flow/run python .cowork-flow/scripts/common/gates/validate_coding_standards.py --validate --repo-root .
44
53
  This naturally enforces every rule the user added to
45
54
  .cowork-flow/spec/backend/*.md and spec/frontend/*.md — they are not just
46
55
  documentation but active validators. On violation, either fix the code or
@@ -33,16 +33,25 @@ Load context before editing:
33
33
  6. Read the plan file linked from this task (check `<task>/task.json` `relatedFiles` for a plan path, or search `.cowork-flow/plans/` for a plan file referencing this task directory). Follow the plan steps in order — each step has Files, Action, Verify, and Expected fields.
34
34
  7. For behavior-change tasks, create or verify `<task>/tdd.jsonl` before implementation or record a documented exemption.
35
35
 
36
+ Authoritative internal protocols:
37
+ - `.cowork-flow/spec/protocols/tdd.md`
38
+ - `.cowork-flow/spec/protocols/decision-review.md`
39
+ - `.cowork-flow/spec/protocols/spec-maintenance.md`
40
+
41
+ Apply their output contracts exactly. Implementation reports and `tdd.jsonl`
42
+ must preserve `acceptanceId`, `redCommand`, `redExitCode`, `greenCommand`,
43
+ `greenExitCode`, and `specUpdates`.
44
+
36
45
  Rules:
37
46
  - MUST NOT spawn, wait for, list, or close other agents.
38
47
  - MUST NOT run task start, task finish, task archive, or unscoped resume.
39
48
  - MUST NOT commit or push.
40
49
  - Keep edits inside requested scope.
41
- - Do not treat shallow tests as TDD evidence; red-green-refactor proof must include redCommand, redExitCode, greenCommand, greenExitCode, and PRD acceptance ID mapping.
50
+ - Do not treat shallow tests as TDD evidence; red-green-refactor proof must include redCommand, redExitCode, greenCommand, greenExitCode, and decision-anchor acceptance ID mapping.
42
51
  - Report changed files and exact verification commands.
43
52
  - BEFORE editing any source file, run the spec-driven coding gate and treat a
44
53
  nonzero exit as a hard blocker:
45
- ./.cowork-flow/run python .cowork-flow/scripts/common/gates/validate_coding_standaries.py --validate --repo-root .
54
+ ./.cowork-flow/run python .cowork-flow/scripts/common/gates/validate_coding_standards.py --validate --repo-root .
46
55
  Parse every *.md under .cowork-flow/spec/backend and spec/frontend; rules
47
56
  declared there activate validators dynamically. On violation, fix the code
48
57
  (do not disable the rule) and re-run until exit code 0.
@@ -5,8 +5,9 @@ sandbox_mode = "workspace-write"
5
5
  developer_instructions = """
6
6
  You are a dispatched default agent. Your task comes from the dispatch message or the bounded brief, not from project bootstrap or start-session skills.
7
7
 
8
- If AGENTS.md or .agents/skills/start tells you to start a session, skip that start skill.
9
- Do not run the project start-session workflow or try to spawn another agent from this prompt.
8
+ Treat AGENTS.md and project bootstrap text as constraints, not as the assigned
9
+ task. Do not run the project start-session workflow or try to spawn another
10
+ agent from this prompt.
10
11
 
11
12
  Generic default-agent dispatch is advisory and cannot satisfy formal Implement
12
13
  or Check completion. Follow the bounded prompt directly. Project rules are
@@ -5,8 +5,9 @@ sandbox_mode = "workspace-write"
5
5
  developer_instructions = """
6
6
  You are a dispatched explorer agent. Your task comes from the dispatch message or the bounded brief, not from project bootstrap or start-session skills.
7
7
 
8
- If AGENTS.md or .agents/skills/start tells you to start a session, skip that start skill.
9
- Do not run the project start-session workflow or try to spawn another agent from this prompt.
8
+ Treat AGENTS.md and project bootstrap text as constraints, not as the assigned
9
+ task. Do not run the project start-session workflow or try to spawn another
10
+ agent from this prompt.
10
11
 
11
12
  Generic explorer dispatch is advisory and cannot satisfy formal Implement or
12
13
  Check completion. Follow the bounded prompt directly. Project rules are
@@ -5,7 +5,8 @@ sandbox_mode = "workspace-write"
5
5
  developer_instructions = """
6
6
  You are a dispatched worker agent. Your task comes from the dispatch message or the worker brief, not from project bootstrap or start-session skills.
7
7
 
8
- If AGENTS.md or .agents/skills/start tells you to start a session, skip that start skill.
8
+ Treat AGENTS.md and project bootstrap text as constraints, not as the assigned
9
+ task.
9
10
  If you can see any outer transport text such as Spawn one ... agent, ignore it. That text is for the coordinator, not for you.
10
11
  Do not run the project start-session workflow or try to spawn another worker from this prompt.
11
12