@tiic-tech/openworkflow 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/adapters/codex/src/doctorCodexAdapter.d.ts +6 -0
- package/dist/adapters/codex/src/doctorCodexAdapter.js +124 -0
- package/dist/adapters/codex/src/doctorCodexAdapter.js.map +1 -0
- package/dist/adapters/codex/src/generateAgents.d.ts +2 -0
- package/dist/adapters/codex/src/generateAgents.js +40 -0
- package/dist/adapters/codex/src/generateAgents.js.map +1 -0
- package/dist/adapters/codex/src/generateCodexAdapter.d.ts +9 -0
- package/dist/adapters/codex/src/generateCodexAdapter.js +59 -0
- package/dist/adapters/codex/src/generateCodexAdapter.js.map +1 -0
- package/dist/adapters/codex/src/generateCommands.d.ts +6 -0
- package/dist/adapters/codex/src/generateCommands.js +205 -0
- package/dist/adapters/codex/src/generateCommands.js.map +1 -0
- package/dist/adapters/codex/src/generateSkills.d.ts +7 -0
- package/dist/adapters/codex/src/generateSkills.js +60 -0
- package/dist/adapters/codex/src/generateSkills.js.map +1 -0
- package/dist/adapters/codex/src/generatedFiles.d.ts +4 -0
- package/dist/adapters/codex/src/generatedFiles.js +67 -0
- package/dist/adapters/codex/src/generatedFiles.js.map +1 -0
- package/dist/adapters/codex/src/manifest.d.ts +4 -0
- package/dist/adapters/codex/src/manifest.js +40 -0
- package/dist/adapters/codex/src/manifest.js.map +1 -0
- package/dist/adapters/codex/src/templates.d.ts +7 -0
- package/dist/adapters/codex/src/templates.js +6 -0
- package/dist/adapters/codex/src/templates.js.map +1 -0
- package/dist/cli/src/args.d.ts +8 -0
- package/dist/cli/src/args.js +34 -0
- package/dist/cli/src/args.js.map +1 -0
- package/dist/cli/src/commands/doctor.d.ts +1 -0
- package/dist/cli/src/commands/doctor.js +26 -0
- package/dist/cli/src/commands/doctor.js.map +1 -0
- package/dist/cli/src/commands/init.d.ts +1 -0
- package/dist/cli/src/commands/init.js +52 -0
- package/dist/cli/src/commands/init.js.map +1 -0
- package/dist/cli/src/commands/shared.d.ts +4 -0
- package/dist/cli/src/commands/shared.js +19 -0
- package/dist/cli/src/commands/shared.js.map +1 -0
- package/dist/cli/src/commands/sync.d.ts +1 -0
- package/dist/cli/src/commands/sync.js +27 -0
- package/dist/cli/src/commands/sync.js.map +1 -0
- package/dist/cli/src/commands/validate.d.ts +1 -0
- package/dist/cli/src/commands/validate.js +17 -0
- package/dist/cli/src/commands/validate.js.map +1 -0
- package/dist/cli/src/dev/validateRepositoryContractsCli.d.ts +2 -0
- package/dist/cli/src/dev/validateRepositoryContractsCli.js +37 -0
- package/dist/cli/src/dev/validateRepositoryContractsCli.js.map +1 -0
- package/dist/cli/src/dev/verifyRuntimeSurface.d.ts +2 -0
- package/dist/cli/src/dev/verifyRuntimeSurface.js +344 -0
- package/dist/cli/src/dev/verifyRuntimeSurface.js.map +1 -0
- package/dist/cli/src/dev/verifyWorkflowE2E.d.ts +2 -0
- package/dist/cli/src/dev/verifyWorkflowE2E.js +366 -0
- package/dist/cli/src/dev/verifyWorkflowE2E.js.map +1 -0
- package/dist/cli/src/index.d.ts +2 -0
- package/dist/cli/src/index.js +51 -0
- package/dist/cli/src/index.js.map +1 -0
- package/dist/core/src/artifacts/registry.d.ts +53 -0
- package/dist/core/src/artifacts/registry.js +483 -0
- package/dist/core/src/artifacts/registry.js.map +1 -0
- package/dist/core/src/commands/registry.d.ts +36 -0
- package/dist/core/src/commands/registry.js +539 -0
- package/dist/core/src/commands/registry.js.map +1 -0
- package/dist/core/src/contracts/index.d.ts +23 -0
- package/dist/core/src/contracts/index.js +16 -0
- package/dist/core/src/contracts/index.js.map +1 -0
- package/dist/core/src/contracts/yaml.d.ts +2 -0
- package/dist/core/src/contracts/yaml.js +12 -0
- package/dist/core/src/contracts/yaml.js.map +1 -0
- package/dist/core/src/contracts.d.ts +23 -0
- package/dist/core/src/contracts.js +15 -0
- package/dist/core/src/contracts.js.map +1 -0
- package/dist/core/src/fs/index.d.ts +4 -0
- package/dist/core/src/fs/index.js +28 -0
- package/dist/core/src/fs/index.js.map +1 -0
- package/dist/core/src/fs.d.ts +4 -0
- package/dist/core/src/fs.js +28 -0
- package/dist/core/src/fs.js.map +1 -0
- package/dist/core/src/initOpenWorkflow.d.ts +7 -0
- package/dist/core/src/initOpenWorkflow.js +220 -0
- package/dist/core/src/initOpenWorkflow.js.map +1 -0
- package/dist/core/src/validateOpenWorkflow.d.ts +5 -0
- package/dist/core/src/validateOpenWorkflow.js +145 -0
- package/dist/core/src/validateOpenWorkflow.js.map +1 -0
- package/dist/core/src/validators/validateOpenWorkflow.d.ts +5 -0
- package/dist/core/src/validators/validateOpenWorkflow.js +551 -0
- package/dist/core/src/validators/validateOpenWorkflow.js.map +1 -0
- package/dist/core/src/validators/validateRepositoryContracts.d.ts +2 -0
- package/dist/core/src/validators/validateRepositoryContracts.js +827 -0
- package/dist/core/src/validators/validateRepositoryContracts.js.map +1 -0
- package/dist/core/src/workflow/initOpenWorkflow.d.ts +7 -0
- package/dist/core/src/workflow/initOpenWorkflow.js +182 -0
- package/dist/core/src/workflow/initOpenWorkflow.js.map +1 -0
- package/dist/core/src/yaml.d.ts +2 -0
- package/dist/core/src/yaml.js +12 -0
- package/dist/core/src/yaml.js.map +1 -0
- package/package.json +55 -0
- package/references/artifact-authoring-templates.md +78 -0
- package/references/audit-first-discovery-loop.md +85 -0
- package/references/contract-graph.md +129 -0
- package/references/discovery-artifact-contracts.md +155 -0
- package/references/engineering-skill-reference-research.md +204 -0
- package/references/npm-cli-architecture.md +63 -0
- package/references/runtime-command-surface.md +169 -0
- package/schemas/artifact-contracts.schema.json +130 -0
- package/schemas/change.schema.json +71 -0
- package/schemas/contract-graph.schema.json +80 -0
- package/schemas/decision-record.schema.json +92 -0
- package/schemas/disclosure-levels.schema.json +66 -0
- package/schemas/openworkflow-contract.schema.json +88 -0
- package/schemas/product-design.schema.json +356 -0
- package/schemas/prototype-evidence.schema.json +325 -0
- package/schemas/prototype.schema.json +149 -0
- package/schemas/validation-target.schema.json +127 -0
- package/schemas/validation.schema.json +123 -0
- package/schemas/vision-session.schema.json +78 -0
- package/schemas/work-items.schema.json +87 -0
- package/schemas/workflow-index.schema.json +70 -0
- package/skills/build-prototype/SKILL.md +87 -0
- package/skills/build-prototype/agents/openai.yaml +4 -0
- package/skills/build-prototype/references/prototype-protocol.md +56 -0
- package/skills/build-prototype/scripts/init_prototype.py +260 -0
- package/skills/build-team/SKILL.md +292 -0
- package/skills/build-team/agents/openai.yaml +4 -0
- package/skills/build-team/references/runtime-schema.md +275 -0
- package/skills/build-team/references/team-protocol.md +244 -0
- package/skills/build-team/scripts/init_team_runtime.py +431 -0
- package/skills/build-validation/SKILL.md +81 -0
- package/skills/build-validation/agents/openai.yaml +4 -0
- package/skills/build-validation/references/validation-protocol.md +51 -0
- package/skills/build-validation/scripts/init_validation.py +194 -0
- package/skills/build-workflow/SKILL.md +65 -0
- package/skills/build-workflow/agents/openai.yaml +4 -0
- package/skills/build-workflow/references/workflow-layout.md +57 -0
- package/skills/build-workflow/scripts/init_workflow.py +423 -0
- package/skills/run-team/SKILL.md +93 -0
- package/skills/run-team/agents/openai.yaml +4 -0
- package/skills/run-team/references/delegation-and-agent-lifecycle.md +78 -0
- package/skills/run-team/references/run-loop.md +73 -0
- package/skills/run-team/references/runtime-audit.md +56 -0
- package/skills/run-team/references/scope-selection.md +64 -0
- package/skills/run-team/scripts/audit_team_runtime.py +173 -0
- package/skills/run-team/scripts/init_next_scope.py +304 -0
- package/templates/README.md +5 -0
- package/templates/codex/README.md +4 -0
- package/templates/openworkflow/README.md +4 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Initialize OpenWorkflow upstream contract infrastructure.
|
|
3
|
+
|
|
4
|
+
The script creates missing repo-local contract folders and seed files. It is
|
|
5
|
+
conservative by default: existing files are not overwritten unless --force is
|
|
6
|
+
provided.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
13
|
+
import re
|
|
14
|
+
import subprocess
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def q(value: str | None) -> str:
|
|
19
|
+
return "null" if value is None else json.dumps(value)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def slugify(value: str) -> str:
|
|
23
|
+
slug = re.sub(r"[^A-Za-z0-9]+", "-", value.strip().lower()).strip("-")
|
|
24
|
+
return slug or "project"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def git_ref(root: Path) -> str | None:
|
|
28
|
+
try:
|
|
29
|
+
result = subprocess.run(
|
|
30
|
+
["git", "rev-parse", "--short", "HEAD"],
|
|
31
|
+
cwd=root,
|
|
32
|
+
check=True,
|
|
33
|
+
text=True,
|
|
34
|
+
stdout=subprocess.PIPE,
|
|
35
|
+
stderr=subprocess.DEVNULL,
|
|
36
|
+
)
|
|
37
|
+
except (OSError, subprocess.CalledProcessError):
|
|
38
|
+
return None
|
|
39
|
+
return result.stdout.strip() or None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def detect_sources(root: Path) -> list[str]:
|
|
43
|
+
candidates = [
|
|
44
|
+
"AGENT.md",
|
|
45
|
+
"README.md",
|
|
46
|
+
"README",
|
|
47
|
+
"build_system_vision.md",
|
|
48
|
+
"ROADMAP.md",
|
|
49
|
+
"SPEC.md",
|
|
50
|
+
]
|
|
51
|
+
sources = [candidate for candidate in candidates if (root / candidate).exists()]
|
|
52
|
+
if (root / "docs").is_dir():
|
|
53
|
+
sources.append("docs/")
|
|
54
|
+
return sources or ["AGENT.md"]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def yaml_list(items: list[str], indent: int) -> str:
|
|
58
|
+
prefix = " " * indent
|
|
59
|
+
if not items:
|
|
60
|
+
return f"{prefix}[]\n"
|
|
61
|
+
return "".join(f"{prefix}- {q(item)}\n" for item in items)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def ensure_dir(path: Path, dry_run: bool) -> None:
|
|
65
|
+
if dry_run:
|
|
66
|
+
print(f"DIR {path}")
|
|
67
|
+
return
|
|
68
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def write_file(path: Path, content: str, force: bool, dry_run: bool) -> None:
|
|
72
|
+
if path.exists() and not force:
|
|
73
|
+
print(f"SKIP {path}")
|
|
74
|
+
return
|
|
75
|
+
if dry_run:
|
|
76
|
+
action = "OVERWRITE" if path.exists() else "WRITE"
|
|
77
|
+
print(f"{action} {path}")
|
|
78
|
+
return
|
|
79
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
80
|
+
path.write_text(content, encoding="utf-8")
|
|
81
|
+
print(f"WRITE {path}")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def touch_gitkeep(path: Path, dry_run: bool) -> None:
|
|
85
|
+
gitkeep = path / ".gitkeep"
|
|
86
|
+
if gitkeep.exists():
|
|
87
|
+
return
|
|
88
|
+
if dry_run:
|
|
89
|
+
print(f"WRITE {gitkeep}")
|
|
90
|
+
return
|
|
91
|
+
gitkeep.write_text("", encoding="utf-8")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def workflow_index(project_slug: str, project_title: str, sources: list[str], ref: str | None) -> str:
|
|
95
|
+
contract_id = f"workflow:{project_slug}"
|
|
96
|
+
return (
|
|
97
|
+
"schema_version: 0.1.0\n"
|
|
98
|
+
f"contract_id: {contract_id}\n"
|
|
99
|
+
"contract_type: workflow\n"
|
|
100
|
+
f"title: {q(project_title + ' workflow index')}\n"
|
|
101
|
+
"status: active\n"
|
|
102
|
+
"workflow_root: .codex\n"
|
|
103
|
+
"active_change: null\n"
|
|
104
|
+
"source_artifacts:\n"
|
|
105
|
+
f"{yaml_list(sources, 2)}"
|
|
106
|
+
f"base_git_ref: {q(ref)}\n"
|
|
107
|
+
"contracts:\n"
|
|
108
|
+
f" - contract_id: {contract_id}\n"
|
|
109
|
+
" contract_type: workflow\n"
|
|
110
|
+
" path: .codex/workflow/WORKFLOW_INDEX.yaml\n"
|
|
111
|
+
" status: active\n"
|
|
112
|
+
" - contract_id: workflow:contract-graph\n"
|
|
113
|
+
" contract_type: workflow\n"
|
|
114
|
+
" path: .codex/workflow/CONTRACT_GRAPH.yaml\n"
|
|
115
|
+
" status: active\n"
|
|
116
|
+
" - contract_id: context:default\n"
|
|
117
|
+
" contract_type: context\n"
|
|
118
|
+
" path: .codex/context/CONTEXT_MAP.yaml\n"
|
|
119
|
+
" status: draft\n"
|
|
120
|
+
" - contract_id: vision:default\n"
|
|
121
|
+
" contract_type: vision\n"
|
|
122
|
+
" path: .codex/vision/VISION_CONTRACT.yaml\n"
|
|
123
|
+
" status: draft\n"
|
|
124
|
+
" - contract_id: decision:index\n"
|
|
125
|
+
" contract_type: decision\n"
|
|
126
|
+
" path: .codex/decisions/DECISION_INDEX.yaml\n"
|
|
127
|
+
" status: active\n"
|
|
128
|
+
" - contract_id: spec:index\n"
|
|
129
|
+
" contract_type: spec\n"
|
|
130
|
+
" path: .codex/spec/SPEC_INDEX.yaml\n"
|
|
131
|
+
" status: active\n"
|
|
132
|
+
" - contract_id: validation:index\n"
|
|
133
|
+
" contract_type: validation\n"
|
|
134
|
+
" path: .codex/validation/VALIDATION_INDEX.yaml\n"
|
|
135
|
+
" status: active\n"
|
|
136
|
+
" - contract_id: prototype:index\n"
|
|
137
|
+
" contract_type: prototype\n"
|
|
138
|
+
" path: .codex/prototypes/PROTOTYPE_INDEX.yaml\n"
|
|
139
|
+
" status: active\n"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def contract_graph(project_slug: str) -> str:
|
|
144
|
+
workflow_id = f"workflow:{project_slug}"
|
|
145
|
+
return (
|
|
146
|
+
"schema_version: 0.1.0\n"
|
|
147
|
+
"contract_id: workflow:contract-graph\n"
|
|
148
|
+
"contract_type: workflow\n"
|
|
149
|
+
"title: OpenWorkflow contract graph\n"
|
|
150
|
+
"status: active\n"
|
|
151
|
+
"nodes:\n"
|
|
152
|
+
f" - contract_id: {workflow_id}\n"
|
|
153
|
+
" contract_type: workflow\n"
|
|
154
|
+
" path: .codex/workflow/WORKFLOW_INDEX.yaml\n"
|
|
155
|
+
" - contract_id: context:default\n"
|
|
156
|
+
" contract_type: context\n"
|
|
157
|
+
" path: .codex/context/CONTEXT_MAP.yaml\n"
|
|
158
|
+
" - contract_id: vision:default\n"
|
|
159
|
+
" contract_type: vision\n"
|
|
160
|
+
" path: .codex/vision/VISION_CONTRACT.yaml\n"
|
|
161
|
+
" - contract_id: decision:index\n"
|
|
162
|
+
" contract_type: decision\n"
|
|
163
|
+
" path: .codex/decisions/DECISION_INDEX.yaml\n"
|
|
164
|
+
" - contract_id: spec:index\n"
|
|
165
|
+
" contract_type: spec\n"
|
|
166
|
+
" path: .codex/spec/SPEC_INDEX.yaml\n"
|
|
167
|
+
" - contract_id: validation:index\n"
|
|
168
|
+
" contract_type: validation\n"
|
|
169
|
+
" path: .codex/validation/VALIDATION_INDEX.yaml\n"
|
|
170
|
+
" - contract_id: prototype:index\n"
|
|
171
|
+
" contract_type: prototype\n"
|
|
172
|
+
" path: .codex/prototypes/PROTOTYPE_INDEX.yaml\n"
|
|
173
|
+
"edges:\n"
|
|
174
|
+
f" - from: {workflow_id}\n"
|
|
175
|
+
" to: context:default\n"
|
|
176
|
+
" relation: initializes\n"
|
|
177
|
+
" - from: context:default\n"
|
|
178
|
+
" to: vision:default\n"
|
|
179
|
+
" relation: informs\n"
|
|
180
|
+
" - from: vision:default\n"
|
|
181
|
+
" to: decision:index\n"
|
|
182
|
+
" relation: constrains\n"
|
|
183
|
+
" - from: decision:index\n"
|
|
184
|
+
" to: spec:index\n"
|
|
185
|
+
" relation: constrains\n"
|
|
186
|
+
" - from: spec:index\n"
|
|
187
|
+
" to: validation:index\n"
|
|
188
|
+
" relation: scopes\n"
|
|
189
|
+
" - from: validation:index\n"
|
|
190
|
+
" to: prototype:index\n"
|
|
191
|
+
" relation: prototypes\n"
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def context_map(project_title: str, sources: list[str]) -> str:
|
|
196
|
+
return (
|
|
197
|
+
"schema_version: 0.1.0\n"
|
|
198
|
+
"contract_id: context:default\n"
|
|
199
|
+
"contract_type: context\n"
|
|
200
|
+
f"title: {q(project_title + ' shared context')}\n"
|
|
201
|
+
"status: draft\n"
|
|
202
|
+
"source_artifacts:\n"
|
|
203
|
+
f"{yaml_list(sources, 2)}"
|
|
204
|
+
"glossary: .codex/context/GLOSSARY.yaml\n"
|
|
205
|
+
"repo_map: []\n"
|
|
206
|
+
"source_references: []\n"
|
|
207
|
+
"depends_on:\n"
|
|
208
|
+
" - workflow:contract-graph\n"
|
|
209
|
+
"produces:\n"
|
|
210
|
+
" - vision:default\n"
|
|
211
|
+
"updated_at: null\n"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def glossary(project_title: str) -> str:
|
|
216
|
+
return (
|
|
217
|
+
"schema_version: 0.1.0\n"
|
|
218
|
+
"contract_id: context:glossary\n"
|
|
219
|
+
"contract_type: context\n"
|
|
220
|
+
f"title: {q(project_title + ' glossary')}\n"
|
|
221
|
+
"status: draft\n"
|
|
222
|
+
"terms: []\n"
|
|
223
|
+
"updated_at: null\n"
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def vision_contract(project_title: str) -> str:
|
|
228
|
+
return (
|
|
229
|
+
"schema_version: 0.1.0\n"
|
|
230
|
+
"contract_id: vision:default\n"
|
|
231
|
+
"contract_type: vision\n"
|
|
232
|
+
f"title: {q(project_title + ' vision')}\n"
|
|
233
|
+
"status: draft\n"
|
|
234
|
+
"depends_on:\n"
|
|
235
|
+
" - context:default\n"
|
|
236
|
+
"produces:\n"
|
|
237
|
+
" - decision:index\n"
|
|
238
|
+
"goals: []\n"
|
|
239
|
+
"non_goals: []\n"
|
|
240
|
+
"users: []\n"
|
|
241
|
+
"quality_bar: []\n"
|
|
242
|
+
"decision_priorities: []\n"
|
|
243
|
+
"updated_at: null\n"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def decision_index(project_title: str) -> str:
|
|
248
|
+
return (
|
|
249
|
+
"schema_version: 0.1.0\n"
|
|
250
|
+
"contract_id: decision:index\n"
|
|
251
|
+
"contract_type: decision\n"
|
|
252
|
+
f"title: {q(project_title + ' decision index')}\n"
|
|
253
|
+
"status: active\n"
|
|
254
|
+
"depends_on:\n"
|
|
255
|
+
" - vision:default\n"
|
|
256
|
+
"produces:\n"
|
|
257
|
+
" - spec:index\n"
|
|
258
|
+
"decisions: []\n"
|
|
259
|
+
"updated_at: null\n"
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def spec_index(project_title: str) -> str:
|
|
264
|
+
return (
|
|
265
|
+
"schema_version: 0.1.0\n"
|
|
266
|
+
"contract_id: spec:index\n"
|
|
267
|
+
"contract_type: spec\n"
|
|
268
|
+
f"title: {q(project_title + ' spec index')}\n"
|
|
269
|
+
"status: active\n"
|
|
270
|
+
"depends_on:\n"
|
|
271
|
+
" - decision:index\n"
|
|
272
|
+
"produces: []\n"
|
|
273
|
+
"specs: []\n"
|
|
274
|
+
"updated_at: null\n"
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def validation_index(project_title: str) -> str:
|
|
279
|
+
return (
|
|
280
|
+
"schema_version: 0.1.0\n"
|
|
281
|
+
"contract_id: validation:index\n"
|
|
282
|
+
"contract_type: validation\n"
|
|
283
|
+
f"title: {q(project_title + ' validation index')}\n"
|
|
284
|
+
"status: active\n"
|
|
285
|
+
"depends_on:\n"
|
|
286
|
+
" - spec:index\n"
|
|
287
|
+
"produces: []\n"
|
|
288
|
+
"validations: []\n"
|
|
289
|
+
"updated_at: null\n"
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def prototype_index(project_title: str) -> str:
|
|
294
|
+
return (
|
|
295
|
+
"schema_version: 0.1.0\n"
|
|
296
|
+
"contract_id: prototype:index\n"
|
|
297
|
+
"contract_type: prototype\n"
|
|
298
|
+
f"title: {q(project_title + ' prototype index')}\n"
|
|
299
|
+
"status: active\n"
|
|
300
|
+
"depends_on:\n"
|
|
301
|
+
" - validation:index\n"
|
|
302
|
+
"produces: []\n"
|
|
303
|
+
"prototypes: []\n"
|
|
304
|
+
"updated_at: null\n"
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def context_doc(project_title: str) -> str:
|
|
309
|
+
return (
|
|
310
|
+
f"# {project_title} Context\n\n"
|
|
311
|
+
"This file is the human-readable project context surface. Keep durable\n"
|
|
312
|
+
"indexes and machine-readable references in `CONTEXT_MAP.yaml` and\n"
|
|
313
|
+
"`GLOSSARY.yaml`.\n"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def vision_doc(project_title: str) -> str:
|
|
318
|
+
return (
|
|
319
|
+
f"# {project_title} Vision\n\n"
|
|
320
|
+
"This file is the human-readable project direction. Keep machine-readable\n"
|
|
321
|
+
"goals, non-goals, users, quality bars, and priorities in\n"
|
|
322
|
+
"`VISION_CONTRACT.yaml`.\n"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def init_workflow(args: argparse.Namespace) -> None:
|
|
327
|
+
root = Path(args.root).expanduser().resolve()
|
|
328
|
+
project_title = args.project_title or root.name
|
|
329
|
+
project_slug = slugify(args.project_slug or project_title)
|
|
330
|
+
sources = args.source_artifact or detect_sources(root)
|
|
331
|
+
ref = git_ref(root)
|
|
332
|
+
|
|
333
|
+
codex = root / ".codex"
|
|
334
|
+
dirs = [
|
|
335
|
+
codex / "workflow",
|
|
336
|
+
codex / "workflow" / "archive",
|
|
337
|
+
codex / "context",
|
|
338
|
+
codex / "context" / "archive",
|
|
339
|
+
codex / "vision",
|
|
340
|
+
codex / "vision" / "archive",
|
|
341
|
+
codex / "decisions",
|
|
342
|
+
codex / "decisions" / "archive",
|
|
343
|
+
codex / "spec",
|
|
344
|
+
codex / "spec" / "archive",
|
|
345
|
+
codex / "validation",
|
|
346
|
+
codex / "validation" / "archive",
|
|
347
|
+
codex / "prototypes",
|
|
348
|
+
codex / "prototypes" / "archive",
|
|
349
|
+
codex / "changes",
|
|
350
|
+
codex / "changes" / "archive",
|
|
351
|
+
]
|
|
352
|
+
for directory in dirs:
|
|
353
|
+
ensure_dir(directory, args.dry_run)
|
|
354
|
+
for directory in dirs:
|
|
355
|
+
if directory.name == "archive":
|
|
356
|
+
touch_gitkeep(directory, args.dry_run)
|
|
357
|
+
|
|
358
|
+
write_file(
|
|
359
|
+
codex / "workflow" / "WORKFLOW_INDEX.yaml",
|
|
360
|
+
workflow_index(project_slug, project_title, sources, ref),
|
|
361
|
+
args.force,
|
|
362
|
+
args.dry_run,
|
|
363
|
+
)
|
|
364
|
+
write_file(
|
|
365
|
+
codex / "workflow" / "CONTRACT_GRAPH.yaml",
|
|
366
|
+
contract_graph(project_slug),
|
|
367
|
+
args.force,
|
|
368
|
+
args.dry_run,
|
|
369
|
+
)
|
|
370
|
+
write_file(codex / "context" / "CONTEXT.md", context_doc(project_title), args.force, args.dry_run)
|
|
371
|
+
write_file(
|
|
372
|
+
codex / "context" / "CONTEXT_MAP.yaml",
|
|
373
|
+
context_map(project_title, sources),
|
|
374
|
+
args.force,
|
|
375
|
+
args.dry_run,
|
|
376
|
+
)
|
|
377
|
+
write_file(codex / "context" / "GLOSSARY.yaml", glossary(project_title), args.force, args.dry_run)
|
|
378
|
+
write_file(codex / "vision" / "VISION.md", vision_doc(project_title), args.force, args.dry_run)
|
|
379
|
+
write_file(
|
|
380
|
+
codex / "vision" / "VISION_CONTRACT.yaml",
|
|
381
|
+
vision_contract(project_title),
|
|
382
|
+
args.force,
|
|
383
|
+
args.dry_run,
|
|
384
|
+
)
|
|
385
|
+
write_file(
|
|
386
|
+
codex / "decisions" / "DECISION_INDEX.yaml",
|
|
387
|
+
decision_index(project_title),
|
|
388
|
+
args.force,
|
|
389
|
+
args.dry_run,
|
|
390
|
+
)
|
|
391
|
+
write_file(codex / "spec" / "SPEC_INDEX.yaml", spec_index(project_title), args.force, args.dry_run)
|
|
392
|
+
write_file(
|
|
393
|
+
codex / "validation" / "VALIDATION_INDEX.yaml",
|
|
394
|
+
validation_index(project_title),
|
|
395
|
+
args.force,
|
|
396
|
+
args.dry_run,
|
|
397
|
+
)
|
|
398
|
+
write_file(
|
|
399
|
+
codex / "prototypes" / "PROTOTYPE_INDEX.yaml",
|
|
400
|
+
prototype_index(project_title),
|
|
401
|
+
args.force,
|
|
402
|
+
args.dry_run,
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def parser() -> argparse.ArgumentParser:
|
|
407
|
+
p = argparse.ArgumentParser(description="Initialize OpenWorkflow contract infrastructure.")
|
|
408
|
+
p.add_argument("--root", default=".", help="Repository root. Defaults to current directory.")
|
|
409
|
+
p.add_argument("--project-title", default=None, help="Human-readable project title.")
|
|
410
|
+
p.add_argument("--project-slug", default=None, help="Stable contract slug. Defaults to project title.")
|
|
411
|
+
p.add_argument("--source-artifact", action="append", default=[], help="Source artifact path. Repeatable.")
|
|
412
|
+
p.add_argument("--force", action="store_true", help="Overwrite existing files.")
|
|
413
|
+
p.add_argument("--dry-run", action="store_true", help="Print writes without changing files.")
|
|
414
|
+
return p
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def main() -> int:
|
|
418
|
+
init_workflow(parser().parse_args())
|
|
419
|
+
return 0
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
if __name__ == "__main__":
|
|
423
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-team
|
|
3
|
+
description: Start and drive formal Agent Team development from the current repository state. Use when the user invokes /ow:team CONTENT or asks Codex to continue a governed multi-agent workflow, choose the next scope after MVP or another completed phase, inspect runtime/archive/git state, initialize or reconcile scope runtime, plan milestones and atom tasks, spawn or resume persistent agents, record agent_id values, and execute development through review, QA, issue-fix, and git checkpoint loops.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Run Team
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Use this skill as the execution entrypoint for an existing Agent Team. `/ow:team` is the user-facing entrypoint for both team creation and execution modes. This repo-local skill reads the current repo, runtime state, and user `CONTENT`, then drives the team through planning and actual development.
|
|
11
|
+
|
|
12
|
+
## Start Protocol
|
|
13
|
+
|
|
14
|
+
On `/ow:team CONTENT`, do not start coding immediately.
|
|
15
|
+
|
|
16
|
+
1. Audit the current state.
|
|
17
|
+
- Run `scripts/audit_team_runtime.py --root . --format markdown`.
|
|
18
|
+
- Inspect `git status --short`, current branch, and recent commits.
|
|
19
|
+
- Read `AGENT.md`, `.codex/agents/README.md`, `.codex/agents/orchestrator.md`.
|
|
20
|
+
- Read `.codex/runtime/STATE_MACHINE.md`, `RUNTIME_INDEX.yaml`, active scope `SCOPE.yaml`, `IMPLEMENT_INDEX.yaml`, `IMPLEMENT_ISSUE_INDEX.yaml`, and `AGENT_ROSTER.yaml`.
|
|
21
|
+
- Inspect active milestone task/issue files and any relevant `archive/` entries.
|
|
22
|
+
|
|
23
|
+
2. Load relevant context.
|
|
24
|
+
- Always load `references/run-loop.md` and `references/runtime-audit.md`.
|
|
25
|
+
- Load `references/scope-selection.md` when deciding whether to continue the current scope or create a new one.
|
|
26
|
+
- Load `references/delegation-and-agent-lifecycle.md` before spawning, resuming, or assigning agents.
|
|
27
|
+
- Load repo source-of-truth docs only when relevant to `CONTENT`.
|
|
28
|
+
|
|
29
|
+
3. Decide the run mode.
|
|
30
|
+
- `continue_scope`: continue active scope/milestone.
|
|
31
|
+
- `new_scope`: create a post-MVP, V1, migration, launch, hardening, or feature scope.
|
|
32
|
+
- `issue_fix`: convert unresolved issues into fix tasks.
|
|
33
|
+
- `release_or_checkpoint`: prepare QA/checkpoint/release work.
|
|
34
|
+
- `runtime_reconcile`: fix stale runtime before development.
|
|
35
|
+
|
|
36
|
+
4. Ask at most one question.
|
|
37
|
+
- Ask only if the delivery target or acceptance bar cannot be inferred from `CONTENT` and repo state.
|
|
38
|
+
- The question must combine target, done criteria, and constraints in one prompt.
|
|
39
|
+
- If the answer is incomplete, state assumptions and proceed.
|
|
40
|
+
|
|
41
|
+
5. Plan dependency order.
|
|
42
|
+
- Define or confirm scope id and goal.
|
|
43
|
+
- Draft milestones with target, dependencies, expected artifacts, QA gate, and acceptance criteria.
|
|
44
|
+
- Convert the first milestone into atom tasks.
|
|
45
|
+
- Write prompts before implementation tasks.
|
|
46
|
+
|
|
47
|
+
6. Initialize or reconcile runtime.
|
|
48
|
+
- For new scopes, run `scripts/init_next_scope.py`.
|
|
49
|
+
- For existing scopes, update only stale or missing runtime files.
|
|
50
|
+
- Preserve archive history; do not delete old runtime artifacts.
|
|
51
|
+
|
|
52
|
+
7. Execute through the Agent Team.
|
|
53
|
+
- Orchestrator must not directly implement product code, docs, QA, review, or prompt-writing work when an eligible subagent can own it.
|
|
54
|
+
- Spawn or resume the correct persistent/event-driven agent.
|
|
55
|
+
- Immediately record the returned `agent_id` in `AGENT_ROSTER.yaml` and the task entry.
|
|
56
|
+
- Keep persistent implementation agents mounted across related atom tasks and issue-fix loops.
|
|
57
|
+
- Use event-driven review, security, QA, and git-release agents asynchronously where ownership is disjoint.
|
|
58
|
+
|
|
59
|
+
8. Checkpoint.
|
|
60
|
+
- Update runtime state after every real state transition.
|
|
61
|
+
- Run required checks.
|
|
62
|
+
- Commit coherent runtime/implementation/QA slices, or record why a checkpoint is deferred.
|
|
63
|
+
|
|
64
|
+
## Runtime Rules
|
|
65
|
+
|
|
66
|
+
New delegated work must not leave `agent_id: null`.
|
|
67
|
+
|
|
68
|
+
Use `legacy_untracked` only for historical tasks that predate roster tracking. Do not invent ids.
|
|
69
|
+
|
|
70
|
+
Direct Orchestrator execution requires `orchestrator_exception`.
|
|
71
|
+
|
|
72
|
+
If unresolved issues exist in an earlier milestone, record them in that milestone's issue file, then route fix tasks back to the original persistent implementation agent when possible.
|
|
73
|
+
|
|
74
|
+
## Script Quick Start
|
|
75
|
+
|
|
76
|
+
Audit:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python3 .codex/skills/run-team/scripts/audit_team_runtime.py --root . --format markdown
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Create a new scope skeleton:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python3 .codex/skills/run-team/scripts/init_next_scope.py \
|
|
86
|
+
--root . \
|
|
87
|
+
--scope-id V1 \
|
|
88
|
+
--scope-title "V1 iteration" \
|
|
89
|
+
--source-artifact AGENT.md \
|
|
90
|
+
--milestone "M01:Post-MVP planning"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If this skill is installed globally, run the scripts from that global skill path instead.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Delegation And Agent Lifecycle
|
|
2
|
+
|
|
3
|
+
Use this reference before assigning work.
|
|
4
|
+
|
|
5
|
+
## Orchestrator Boundary
|
|
6
|
+
|
|
7
|
+
The Orchestrator owns:
|
|
8
|
+
|
|
9
|
+
- scope and milestone selection
|
|
10
|
+
- runtime state
|
|
11
|
+
- atom task decomposition
|
|
12
|
+
- prompt assignment
|
|
13
|
+
- agent lifecycle
|
|
14
|
+
- integration
|
|
15
|
+
- checkpoint decisions
|
|
16
|
+
|
|
17
|
+
The Orchestrator must not directly perform implementation, docs, QA, review, or prompt-writing work when an eligible subagent can own it.
|
|
18
|
+
|
|
19
|
+
Direct execution requires:
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
orchestrator_exception: "<reason>"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Persistent Agents
|
|
26
|
+
|
|
27
|
+
Use persistent agents for recurring work:
|
|
28
|
+
|
|
29
|
+
- `tech-prompt-agent`
|
|
30
|
+
- `frontend-agent`
|
|
31
|
+
- `backend-agent`
|
|
32
|
+
- `content-schema-agent`
|
|
33
|
+
- `data-agent`
|
|
34
|
+
- `infra-agent`
|
|
35
|
+
- `docs-agent`
|
|
36
|
+
|
|
37
|
+
Before spawning a persistent agent, check `AGENT_ROSTER.yaml` for an existing idle or active matching role. Resume it when possible.
|
|
38
|
+
|
|
39
|
+
After spawn or resume:
|
|
40
|
+
|
|
41
|
+
- record returned `agent_id` in `AGENT_ROSTER.yaml`
|
|
42
|
+
- record the same `agent_id` in `IMPLEMENT_TASKS.yaml`
|
|
43
|
+
- set lifecycle state to `active`
|
|
44
|
+
- set `current_task`
|
|
45
|
+
|
|
46
|
+
When the handoff is complete:
|
|
47
|
+
|
|
48
|
+
- set lifecycle state to `idle` unless blocked or closed
|
|
49
|
+
- set `last_completed_task`
|
|
50
|
+
- clear or update `current_task`
|
|
51
|
+
|
|
52
|
+
## Event-Driven Agents
|
|
53
|
+
|
|
54
|
+
Use event-driven agents for:
|
|
55
|
+
|
|
56
|
+
- `code-review-agent`
|
|
57
|
+
- `security-review-agent`
|
|
58
|
+
- `tdd-qa-agent` unless running a long test authoring stream
|
|
59
|
+
- `git-release-agent`
|
|
60
|
+
|
|
61
|
+
Event agents may run asynchronously when ownership is disjoint. Close after handoff unless there is a recorded reason to keep them idle.
|
|
62
|
+
|
|
63
|
+
## Issue Fix Return
|
|
64
|
+
|
|
65
|
+
When review finds issues:
|
|
66
|
+
|
|
67
|
+
1. Record issues in the reviewed milestone's `IMPLEMENT_ISSUES.yaml`.
|
|
68
|
+
2. Convert required issues into fix tasks.
|
|
69
|
+
3. Prefer the original persistent implementation `agent_id`.
|
|
70
|
+
4. Spawn a replacement only when the original agent is closed, unavailable, or no longer owns the paths.
|
|
71
|
+
|
|
72
|
+
## Forbidden States
|
|
73
|
+
|
|
74
|
+
- new assigned work with `agent_id: null`
|
|
75
|
+
- invented ids for historical work
|
|
76
|
+
- review agents editing implementation files
|
|
77
|
+
- implementation agents committing
|
|
78
|
+
- two agents writing the same path ownership without a merge plan
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Run Loop
|
|
2
|
+
|
|
3
|
+
Use this reference to drive `/ow:team CONTENT` from inspection into execution.
|
|
4
|
+
|
|
5
|
+
## Execution Flow
|
|
6
|
+
|
|
7
|
+
```txt
|
|
8
|
+
content_intake
|
|
9
|
+
-> repo_and_runtime_audit
|
|
10
|
+
-> source_truth_loading
|
|
11
|
+
-> run_mode_decision
|
|
12
|
+
-> scope_or_milestone_plan
|
|
13
|
+
-> runtime_init_or_reconcile
|
|
14
|
+
-> atom_task_plan
|
|
15
|
+
-> prompt_preparation
|
|
16
|
+
-> spawn_or_resume_agent
|
|
17
|
+
-> record_agent_id
|
|
18
|
+
-> delegated_work
|
|
19
|
+
-> handoff
|
|
20
|
+
-> review_or_qa
|
|
21
|
+
-> issue_fix_loop
|
|
22
|
+
-> checkpoint
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Operating Rules
|
|
26
|
+
|
|
27
|
+
- Treat `CONTENT` as the seed target, not as a complete plan.
|
|
28
|
+
- Infer from runtime first, then source-of-truth docs, then code state.
|
|
29
|
+
- Do not skip `git status --short`; dirty unrelated files affect checkpoint boundaries.
|
|
30
|
+
- Do not start implementation until the active scope, milestone, task, ownership, and agent session policy are known.
|
|
31
|
+
- Do not let the Orchestrator become the default implementer.
|
|
32
|
+
- Prefer persistent implementation agents for repeated work in the same domain.
|
|
33
|
+
- Use event-driven agents for review, security, QA, release notes, and narrow investigations.
|
|
34
|
+
- Keep `.codex/runtime/` synchronized with reality before moving to unrelated work.
|
|
35
|
+
|
|
36
|
+
## Run Modes
|
|
37
|
+
|
|
38
|
+
`continue_scope`:
|
|
39
|
+
|
|
40
|
+
- Active scope exists.
|
|
41
|
+
- Active milestone has planned, prompted, in-progress, blocked, or fix-required tasks.
|
|
42
|
+
- Continue by reconciling stale state, then assigning the next unblocked task.
|
|
43
|
+
|
|
44
|
+
`new_scope`:
|
|
45
|
+
|
|
46
|
+
- Existing scope is complete, frozen, deferred, or no longer matches `CONTENT`.
|
|
47
|
+
- Create a new scope such as `V1`, `POST_MVP`, `LAUNCH`, `CONTENT`, `MIGRATION`, or a short uppercase slug.
|
|
48
|
+
- Initialize runtime before atom tasks.
|
|
49
|
+
|
|
50
|
+
`issue_fix`:
|
|
51
|
+
|
|
52
|
+
- Unresolved issues exist and match `CONTENT`.
|
|
53
|
+
- Convert issues into fix tasks and route to the original persistent implementation agent when possible.
|
|
54
|
+
|
|
55
|
+
`release_or_checkpoint`:
|
|
56
|
+
|
|
57
|
+
- Work is complete enough for QA, commit, PR, deploy, or release notes.
|
|
58
|
+
- Assign QA/release agents as event-driven work.
|
|
59
|
+
|
|
60
|
+
`runtime_reconcile`:
|
|
61
|
+
|
|
62
|
+
- Runtime files are stale, missing, contradictory, or not parseable.
|
|
63
|
+
- Fix runtime before development.
|
|
64
|
+
|
|
65
|
+
## End State
|
|
66
|
+
|
|
67
|
+
A successful run should leave:
|
|
68
|
+
|
|
69
|
+
- updated runtime state
|
|
70
|
+
- agent ids recorded for new delegated work
|
|
71
|
+
- clear task/milestone status
|
|
72
|
+
- review or QA artifacts when relevant
|
|
73
|
+
- a commit decision for coherent slices
|