okstra 0.168.0 → 0.169.1

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 (101) hide show
  1. package/README.md +5 -4
  2. package/docs/architecture/storage-model.md +57 -1
  3. package/docs/architecture.md +70 -2
  4. package/docs/cli.md +8 -4
  5. package/docs/for-ai/skills/okstra-code-review.md +3 -2
  6. package/docs/for-ai/skills/okstra-schedule-gen.md +3 -1
  7. package/docs/project-structure-overview.md +14 -11
  8. package/package.json +1 -1
  9. package/runtime/BUILD.json +2 -2
  10. package/runtime/agents/workers/claude-worker.md +6 -5
  11. package/runtime/agents/workers/report-writer-worker.md +9 -4
  12. package/runtime/agents/workers/translator-worker.md +6 -4
  13. package/runtime/bin/okstra-error-log.py +38 -282
  14. package/runtime/prompts/duties/acceptance-critic.md +24 -0
  15. package/runtime/prompts/duties/acceptance-verifier.md +24 -0
  16. package/runtime/prompts/duties/analysis-worker.md +24 -0
  17. package/runtime/prompts/duties/code-reviewer.md +24 -0
  18. package/runtime/prompts/duties/common.md +35 -0
  19. package/runtime/prompts/duties/implementation-executor.md +24 -0
  20. package/runtime/prompts/duties/implementation-verifier.md +24 -0
  21. package/runtime/prompts/duties/lead.md +24 -0
  22. package/runtime/prompts/duties/report-writer.md +24 -0
  23. package/runtime/prompts/duties/reverification-worker.md +24 -0
  24. package/runtime/prompts/duties/schedule-verifier.md +24 -0
  25. package/runtime/prompts/duties/scope-critic.md +24 -0
  26. package/runtime/prompts/duties/translator.md +24 -0
  27. package/runtime/prompts/lead/convergence.md +104 -14
  28. package/runtime/prompts/lead/okstra-lead-contract.md +11 -21
  29. package/runtime/prompts/lead/plan-body-verification.md +16 -1
  30. package/runtime/prompts/lead/report-writer.md +20 -5
  31. package/runtime/prompts/lead/team-contract.md +13 -13
  32. package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
  33. package/runtime/prompts/profiles/_implementation-diff-review.md +1 -1
  34. package/runtime/prompts/profiles/_implementation-executor.md +1 -1
  35. package/runtime/prompts/profiles/implementation.md +4 -2
  36. package/runtime/python/okstra_ctl/adapters/hosts/antigravity/adapter.py +6 -0
  37. package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +3 -2
  38. package/runtime/python/okstra_ctl/adapters/hosts/capability_adapter.py +8 -0
  39. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +33 -0
  40. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +13 -12
  41. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +6 -0
  42. package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +3 -2
  43. package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +2 -0
  44. package/runtime/python/okstra_ctl/adapters/hosts/external/relay.md +3 -3
  45. package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +6 -0
  46. package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +2 -1
  47. package/runtime/python/okstra_ctl/adapters/hosts/kimi/adapter.py +6 -0
  48. package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +2 -1
  49. package/runtime/python/okstra_ctl/agent_invocation.py +1582 -0
  50. package/runtime/python/okstra_ctl/agent_prompt_cli.py +796 -0
  51. package/runtime/python/okstra_ctl/codex_dispatch.py +2 -107
  52. package/runtime/python/okstra_ctl/context_cost.py +46 -5
  53. package/runtime/python/okstra_ctl/dispatch_core.py +538 -43
  54. package/runtime/python/okstra_ctl/dispatch_state.py +461 -36
  55. package/runtime/python/okstra_ctl/doctor.py +90 -16
  56. package/runtime/python/okstra_ctl/entrypoints/hosts.py +87 -9
  57. package/runtime/python/okstra_ctl/error_log_write.py +308 -0
  58. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +214 -23
  59. package/runtime/python/okstra_ctl/path_hints.py +26 -0
  60. package/runtime/python/okstra_ctl/paths.py +20 -0
  61. package/runtime/python/okstra_ctl/ports/__init__.py +8 -0
  62. package/runtime/python/okstra_ctl/ports/host.py +3 -0
  63. package/runtime/python/okstra_ctl/ports/host_model.py +60 -0
  64. package/runtime/python/okstra_ctl/registry/host_registry.py +5 -0
  65. package/runtime/python/okstra_ctl/render.py +217 -12
  66. package/runtime/python/okstra_ctl/report_finalize.py +44 -0
  67. package/runtime/python/okstra_ctl/run.py +368 -51
  68. package/runtime/python/okstra_ctl/session.py +16 -12
  69. package/runtime/python/okstra_ctl/team.py +11 -11
  70. package/runtime/python/okstra_ctl/worker_audit_check.py +26 -4
  71. package/runtime/python/okstra_ctl/worker_audit_ledger.py +59 -9
  72. package/runtime/python/okstra_ctl/worker_dispatch.py +104 -0
  73. package/runtime/python/okstra_ctl/worker_prompt_body.py +5 -38
  74. package/runtime/python/okstra_ctl/worker_prompt_contract.py +56 -3
  75. package/runtime/python/okstra_ctl/worker_prompt_headers.py +2 -2
  76. package/runtime/python/okstra_ctl/worker_prompt_policy.py +38 -1
  77. package/runtime/skills/okstra-code-review/SKILL.md +22 -3
  78. package/runtime/skills/okstra-run/SKILL.md +16 -1
  79. package/runtime/skills/okstra-schedule-gen/SKILL.md +15 -1
  80. package/runtime/templates/implementation-worker-preamble.md +0 -10
  81. package/runtime/templates/report-writer-prompt-preamble.md +0 -9
  82. package/runtime/templates/reports/settings.template.json +0 -11
  83. package/runtime/templates/worker-prompt-preamble.md +0 -10
  84. package/runtime/validators/lib/fixtures.sh +93 -0
  85. package/runtime/validators/lib/validate-assets.sh +0 -8
  86. package/runtime/validators/validate-run.py +182 -0
  87. package/src/cli-registry.mjs +14 -0
  88. package/src/commands/execute/agent-prompt.mjs +25 -0
  89. package/src/commands/execute/codex-dispatch.mjs +6 -63
  90. package/src/commands/execute/worker-dispatch.mjs +76 -0
  91. package/src/commands/lifecycle/doctor.mjs +18 -3
  92. package/src/commands/lifecycle/install.mjs +33 -15
  93. package/src/commands/lifecycle/uninstall.mjs +4 -3
  94. package/src/lib/install-assets.mjs +9 -0
  95. package/runtime/agents/workers/antigravity-worker.md +0 -259
  96. package/runtime/agents/workers/codex-worker.md +0 -259
  97. package/runtime/agents/workers/grok-worker.md +0 -259
  98. package/runtime/agents/workers/kimi-worker.md +0 -259
  99. package/runtime/prompts/coding-preflight/scripts/preedit-check.sh +0 -79
  100. package/runtime/templates/operating-standard.md +0 -22
  101. package/src/lib/worker-agent-render.mjs +0 -50
@@ -1,296 +1,52 @@
1
1
  #!/usr/bin/env python3
2
- """OKSTRA error log helper.
2
+ """OKSTRA error log helper — CLI adapter.
3
3
 
4
- Single writer for runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl.
4
+ The writer itself lives in `okstra_ctl.error_log_write`, which the deterministic
5
+ dispatcher also calls in-process. This file is the argparse surface over it and
6
+ re-exports the writer's names so the contract tests keep reading one module.
5
7
  """
6
8
  from __future__ import annotations
7
9
 
8
10
  import argparse
9
- import datetime as dt
10
11
  import json
11
- import os
12
12
  from pathlib import Path
13
13
 
14
- STDERR_EXCERPT_MAX_BYTES = 2048
15
- TRUNCATION_SUFFIX = "...[truncated]"
16
- PIPE_BUF_BYTES = 4096
17
-
18
- ALLOWED_ERROR_TYPES = {"tool-failure", "cli-failure", "contract-violation"}
19
- ALLOWED_AGENTS = {
20
- "claude-lead", "claude-worker", "codex-worker",
21
- "antigravity-worker", "report-writer",
22
- }
23
- ALLOWED_AGENT_ROLES = {"lead", "worker", "report-writer"}
24
- SUPPORTED_SIDECAR_SCHEMA_VERSIONS = {1}
25
-
26
- ALLOWED_CAUSES = {
27
- "sandbox-denied", "service-unavailable", "auth-failed", "unknown",
28
- }
29
- # A `sandbox-denied` claim is only admissible with both probes attached.
30
- CAUSE_EVIDENCE_FIELDS = ("targetProbe", "controlProbe")
31
- # Both probes share a record's PIPE_BUF_BYTES budget with stderrExcerpt, so
32
- # they cannot reuse the 2048 cap that assumes stderrExcerpt owns it alone.
33
- CAUSE_PROBE_MAX_BYTES = 256
34
- # Backstop vocabulary: scanned in `message` only — never in stderrExcerpt,
35
- # where a kernel's real "Operation not permitted" is legitimate content.
36
- # Deliberately excludes bare "blocked"/"blocks": everyday English that would
37
- # reject honest records like "test blocked on upstream dependency".
38
- _BLOCKING_CLAIM_TERMS = (
39
- "sandbox", "not permitted", "permission denied", "eperm",
14
+ from okstra_ctl.error_log_write import (
15
+ ALLOWED_AGENT_ROLES,
16
+ ALLOWED_AGENTS,
17
+ ALLOWED_CAUSES,
18
+ ALLOWED_ERROR_TYPES,
19
+ CAUSE_EVIDENCE_FIELDS,
20
+ CAUSE_PROBE_MAX_BYTES,
21
+ PIPE_BUF_BYTES,
22
+ STDERR_EXCERPT_MAX_BYTES,
23
+ SUPPORTED_SIDECAR_SCHEMA_VERSIONS,
24
+ TRUNCATION_SUFFIX,
25
+ append_jsonl_line,
26
+ append_observed,
27
+ dump_from_worker_sidecar,
28
+ normalize_cause_context,
29
+ truncate_stderr,
40
30
  )
41
- # The backstop targets *unclassified* blocking claims. A worker that declared
42
- # a specific cause has already done the honest work — `auth-failed` legitimately
43
- # reads "permission denied" (MySQL 1045).
44
- _UNCLASSIFIED_CAUSES = (None, "unknown")
45
-
46
-
47
- def _now_utc():
48
- return dt.datetime.now(dt.timezone.utc)
49
-
50
-
51
- def _iso(t):
52
- return t.isoformat()
53
-
54
-
55
- def _truncate_utf8(s, limit):
56
- """Truncate to `limit` bytes without splitting a multibyte character."""
57
- if s is None:
58
- return None
59
- encoded = s.encode("utf-8")
60
- if len(encoded) <= limit:
61
- return s
62
- cut = encoded[:limit]
63
- while cut:
64
- try:
65
- return cut.decode("utf-8") + TRUNCATION_SUFFIX
66
- except UnicodeDecodeError:
67
- cut = cut[:-1]
68
- return TRUNCATION_SUFFIX
69
-
70
-
71
- def truncate_stderr(s):
72
- """Truncate stderr text to STDERR_EXCERPT_MAX_BYTES, multibyte-safe."""
73
- return _truncate_utf8(s, STDERR_EXCERPT_MAX_BYTES)
74
-
75
-
76
- def normalize_cause_context(context, *, message):
77
- """Validate a record's cause claim and return the normalized context.
78
-
79
- Raises ValueError on three conditions:
80
- - `cause` is set to a value outside ALLOWED_CAUSES;
81
- - `cause` is 'sandbox-denied' but the two probes are missing or blank —
82
- those probes are what distinguish a real denial from an unreachable
83
- or auth-gated target, the misdiagnosis this gate exists to stop;
84
- - `message` asserts a block in prose while the record left its cause
85
- unclassified, which would smuggle the same claim past the gate.
86
- """
87
- cause = context.get("cause") if isinstance(context, dict) else None
88
-
89
- if cause is not None and cause not in ALLOWED_CAUSES:
90
- raise ValueError(
91
- f"invalid cause: {cause!r} (allowed: {sorted(ALLOWED_CAUSES)})"
92
- )
93
-
94
- if cause == "sandbox-denied":
95
- evidence = context.get("causeEvidence")
96
- if not isinstance(evidence, dict):
97
- raise ValueError(
98
- "cause 'sandbox-denied' requires context.causeEvidence with "
99
- f"{list(CAUSE_EVIDENCE_FIELDS)}"
100
- )
101
- normalized_evidence = {}
102
- for field in CAUSE_EVIDENCE_FIELDS:
103
- value = evidence.get(field)
104
- if not isinstance(value, str) or not value.strip():
105
- raise ValueError(
106
- f"cause 'sandbox-denied' requires a non-empty "
107
- f"context.causeEvidence.{field}: record the command and "
108
- f"its raw output that proves the claim"
109
- )
110
- normalized_evidence[field] = _truncate_utf8(
111
- value, CAUSE_PROBE_MAX_BYTES
112
- )
113
- return {**context, "causeEvidence": normalized_evidence}
114
31
 
115
- if message and cause in _UNCLASSIFIED_CAUSES:
116
- lowered = message.lower()
117
- hit = next((t for t in _BLOCKING_CLAIM_TERMS if t in lowered), None)
118
- if hit:
119
- raise ValueError(
120
- f"message asserts a blocking claim ({hit!r}) without "
121
- "context.cause='sandbox-denied' + context.causeEvidence. "
122
- "Either attach the two probes, or state the cause you "
123
- "actually verified."
124
- )
125
-
126
- return context
127
-
128
-
129
- def append_jsonl_line(path, record):
130
- """Append a single JSON record as one line to ``path``.
131
-
132
- Atomicity guarantee (POSIX only):
133
- With ``O_APPEND`` and a single ``write()`` syscall, the kernel
134
- appends the entire payload as one indivisible operation as long as
135
- the payload size is at most ``PIPE_BUF`` (4096 bytes on Linux and
136
- macOS). Larger payloads may be split across syscalls and interleave
137
- with concurrent writers, so this helper rejects them with
138
- ``ValueError`` rather than silently losing atomicity.
139
-
140
- The atomicity contract holds only on POSIX filesystems with O_APPEND
141
- semantics. Concurrent writers using ``O_TRUNC``, ``unlink``, or
142
- non-append modes against the same path break the contract and are
143
- out of scope for this helper.
144
-
145
- Caller responsibilities:
146
- - Keep records small (this module's stderr excerpt cap of
147
- ``STDERR_EXCERPT_MAX_BYTES`` exists to keep records well under
148
- ``PIPE_BUF_BYTES``).
149
- - Handle ``TypeError`` from ``json.dumps`` for non-serializable values.
150
-
151
- Creates parent directories as needed.
152
- """
153
- p = Path(path)
154
- p.parent.mkdir(parents=True, exist_ok=True)
155
- # ensure_ascii=False keeps UTF-8 compact (no \uXXXX escapes).
156
- # json.dumps escapes literal newlines inside string values, so the
157
- # only unescaped newline is the record separator we append below.
158
- line = json.dumps(record, ensure_ascii=False, separators=(",", ":")) + "\n"
159
- data = line.encode("utf-8")
160
- if len(data) > PIPE_BUF_BYTES:
161
- raise ValueError(
162
- f"record too large for atomic append: {len(data)} bytes > "
163
- f"PIPE_BUF ({PIPE_BUF_BYTES})"
164
- )
165
- # mode 0o644: owner read/write, group/world read-only.
166
- fd = os.open(str(p), os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o644)
167
- try:
168
- os.write(fd, data)
169
- finally:
170
- os.close(fd)
171
-
172
-
173
- def append_observed(
174
- *,
175
- out_path,
176
- task_key,
177
- phase,
178
- agent,
179
- agent_role,
180
- model,
181
- error_type,
182
- command,
183
- command_kind,
184
- exit_code,
185
- duration_ms,
186
- message,
187
- stderr_excerpt,
188
- context,
189
- now=None,
190
- ):
191
- """Append a lead-observed error event to errors.jsonl."""
192
- if error_type not in ALLOWED_ERROR_TYPES:
193
- raise ValueError(f"invalid errorType: {error_type!r}")
194
- if agent not in ALLOWED_AGENTS:
195
- raise ValueError(f"invalid agent: {agent!r}")
196
- if agent_role not in ALLOWED_AGENT_ROLES:
197
- raise ValueError(f"invalid agentRole: {agent_role!r}")
198
- # Runs before append_jsonl_line so a rejected claim leaves no trace in the
199
- # log: a written-then-flagged record is still a record someone can cite.
200
- context = normalize_cause_context(context, message=message)
201
- ts = _iso(now or _now_utc())
202
- rec = {
203
- "ts": ts,
204
- "recordedAt": ts,
205
- "taskKey": task_key,
206
- "phase": str(phase),
207
- "agent": agent,
208
- "agentRole": agent_role,
209
- "model": model,
210
- "source": "lead-observed",
211
- "errorType": error_type,
212
- "command": command,
213
- "commandKind": command_kind,
214
- "exitCode": exit_code,
215
- "durationMs": duration_ms,
216
- "message": message,
217
- "stderrExcerpt": truncate_stderr(stderr_excerpt),
218
- "context": context,
219
- }
220
- append_jsonl_line(out_path, rec)
221
- return rec
222
-
223
-
224
- def dump_from_worker_sidecar(
225
- *,
226
- sidecar_path,
227
- out_path,
228
- task_key,
229
- agent,
230
- agent_role,
231
- model,
232
- now=None,
233
- ):
234
- """Read worker sidecar errors[] and append each to errors.jsonl with
235
- Lead-side metadata filled in. Returns number of records appended.
236
-
237
- Raises ValueError if:
238
- - ``agent`` or ``agent_role`` is not in the allow-lists
239
- - sidecar ``schemaVersion`` is not in ``SUPPORTED_SIDECAR_SCHEMA_VERSIONS``
240
- - any entry's ``errorType`` is not in ``ALLOWED_ERROR_TYPES``
241
- - any entry asserts a blocking cause without its required evidence
242
-
243
- Returns 0 (no-op) if the sidecar file does not exist or its
244
- ``errors`` list is empty.
245
-
246
- Partial-failure semantics: entries are validated and appended in
247
- order. If entry N fails validation, entries 0..N-1 have already
248
- been written to ``out_path`` and are NOT rolled back. Callers that
249
- require atomicity must validate the sidecar payload before invoking
250
- this function.
251
- """
252
- if agent not in ALLOWED_AGENTS:
253
- raise ValueError(f"invalid agent: {agent!r}")
254
- if agent_role not in ALLOWED_AGENT_ROLES:
255
- raise ValueError(f"invalid agentRole: {agent_role!r}")
256
- p = Path(sidecar_path)
257
- if not p.exists():
258
- return 0
259
- payload = json.loads(p.read_text())
260
- schema = payload.get("schemaVersion")
261
- if schema not in SUPPORTED_SIDECAR_SCHEMA_VERSIONS:
262
- raise ValueError(f"unsupported sidecar schemaVersion: {schema!r}")
263
- entries = payload.get("errors") or []
264
- recorded_at = _iso(now or _now_utc())
265
- count = 0
266
- for e in entries:
267
- et = e.get("errorType")
268
- if et not in ALLOWED_ERROR_TYPES:
269
- raise ValueError(f"invalid errorType in sidecar: {et!r}")
270
- entry_context = normalize_cause_context(
271
- e.get("context"), message=e.get("message")
272
- )
273
- rec = {
274
- "ts": e.get("ts"),
275
- "recordedAt": recorded_at,
276
- "taskKey": task_key,
277
- "phase": str(e.get("phase")) if e.get("phase") is not None else None,
278
- "agent": agent,
279
- "agentRole": agent_role,
280
- "model": model,
281
- "source": "worker-reported",
282
- "errorType": et,
283
- "command": e.get("command"),
284
- "commandKind": e.get("commandKind"),
285
- "exitCode": e.get("exitCode"),
286
- "durationMs": e.get("durationMs"),
287
- "message": e.get("message"),
288
- "stderrExcerpt": truncate_stderr(e.get("stderrExcerpt")),
289
- "context": entry_context,
290
- }
291
- append_jsonl_line(out_path, rec)
292
- count += 1
293
- return count
32
+ __all__ = [
33
+ "ALLOWED_AGENT_ROLES",
34
+ "ALLOWED_AGENTS",
35
+ "ALLOWED_CAUSES",
36
+ "ALLOWED_ERROR_TYPES",
37
+ "CAUSE_EVIDENCE_FIELDS",
38
+ "CAUSE_PROBE_MAX_BYTES",
39
+ "PIPE_BUF_BYTES",
40
+ "STDERR_EXCERPT_MAX_BYTES",
41
+ "SUPPORTED_SIDECAR_SCHEMA_VERSIONS",
42
+ "TRUNCATION_SUFFIX",
43
+ "append_jsonl_line",
44
+ "append_observed",
45
+ "dump_from_worker_sidecar",
46
+ "main",
47
+ "normalize_cause_context",
48
+ "truncate_stderr",
49
+ ]
294
50
 
295
51
 
296
52
  def _build_parser():
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: acceptance-critic
3
+ version: 1
4
+ kind: role
5
+ appliesTo: acceptance-critic
6
+ ---
7
+
8
+ # Acceptance Critic Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Find new candidate defects that could prevent acceptance.
13
+
14
+ ## Required conduct
15
+
16
+ Challenge the strongest completion claims and produce only distinct, evidence-backed candidates.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not repeat an existing defect, lower the acceptance standard, or make the final acceptance decision.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Name the completion claim that cannot be challenged and the evidence needed to evaluate it.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: acceptance-verifier
3
+ version: 1
4
+ kind: role
5
+ appliesTo: acceptance-verifier
6
+ ---
7
+
8
+ # Acceptance Verifier Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Independently decide whether the declared acceptance criteria and deliverables are satisfied.
13
+
14
+ ## Required conduct
15
+
16
+ Evaluate every criterion against current evidence and return an explicit pass, fail, or blocked judgment.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not infer acceptance from effort, intent, or unrelated passing checks.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ List each undecidable criterion and the exact missing artifact or observation.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: analysis-worker
3
+ version: 1
4
+ kind: role
5
+ appliesTo: analysis-worker
6
+ ---
7
+
8
+ # Analysis Worker Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Produce an independent, evidence-backed analysis of the assigned question.
13
+
14
+ ## Required conduct
15
+
16
+ Inspect the assigned sources, cite concrete evidence, and state uncertainty or counterevidence.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not imitate another worker's expected answer, coordinate conclusions, or expand the assigned question.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Identify the unavailable evidence, the checks attempted, and the precise effect on the requested conclusion.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: code-reviewer
3
+ version: 1
4
+ kind: role
5
+ appliesTo: code-reviewer
6
+ ---
7
+
8
+ # Code Reviewer Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Return a verdict for every census cell assigned to the review.
13
+
14
+ ## Required conduct
15
+
16
+ Inspect every cell, preserve its identity, and support each finding or clean verdict with code evidence.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not reinterpret, merge, omit, or add census cells.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Identify each cell that cannot be evaluated and the missing source, diff, or standard.
@@ -0,0 +1,35 @@
1
+ ---
2
+ id: common
3
+ version: 1
4
+ kind: common
5
+ ---
6
+
7
+ # Common Agent Duty Contract
8
+
9
+ ## Assignment fidelity
10
+
11
+ Perform the assigned work exactly as scoped. Do not silently broaden, narrow, replace, or reinterpret the assignment.
12
+
13
+ ## Completion discipline
14
+
15
+ Carry the assignment through every required check and deliverable. Do not stop at a plausible partial result.
16
+
17
+ ## Evidence first
18
+
19
+ Base conclusions on inspected inputs and observed results. Distinguish verified facts from inferences and unknowns.
20
+
21
+ ## Required inputs
22
+
23
+ Read every required input before acting. Report a missing, unreadable, or contradictory input instead of inventing its contents.
24
+
25
+ ## Authority and scope
26
+
27
+ Use only the permissions and project scope granted by the invocation. Do not perform unrelated or outward-facing actions.
28
+
29
+ ## Conflict handling
30
+
31
+ When instructions conflict, preserve safety and evidence, identify the exact conflict, and return it to the responsible lead.
32
+
33
+ ## Completion honesty
34
+
35
+ Do not report unperformed work as complete. Name remaining work, failed checks, and blockers precisely.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: implementation-executor
3
+ version: 1
4
+ kind: role
5
+ appliesTo: implementation-executor
6
+ ---
7
+
8
+ # Implementation Executor Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Be the sole change author for exactly one approved implementation stage.
13
+
14
+ ## Required conduct
15
+
16
+ Follow the approved stage, preserve concurrent work, test each behavior, and report every changed file and verification result.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not implement another stage, rewrite the plan, or delegate edits to a verifier.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Name the stage item, the blocking dependency or failing evidence, and the unchanged state left behind.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: implementation-verifier
3
+ version: 1
4
+ kind: role
5
+ appliesTo: implementation-verifier
6
+ ---
7
+
8
+ # Implementation Verifier Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Independently reproduce quality-assurance checks for the assigned implementation.
13
+
14
+ ## Required conduct
15
+
16
+ Read project files without changing them, run the assigned checks, and distinguish reproduced results from executor claims.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not edit project files, repair failures, or approve work on the executor's assertion alone.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Name the check that could not run, its missing prerequisite, and which acceptance claim remains unverified.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: lead
3
+ version: 1
4
+ kind: role
5
+ appliesTo: lead
6
+ ---
7
+
8
+ # Lead Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Own assignment, convergence, phase gates, and the final completion decision.
13
+
14
+ ## Required conduct
15
+
16
+ Give each agent a bounded assignment, reconcile claims against evidence, and require every gate before declaring completion. Prefer stronger evidence over majority agreement.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not let workers choose the roster, hide dissent, or treat vote count as proof.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Name the blocked gate, the evidence already gathered, and the smallest decision or input needed to proceed.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: report-writer
3
+ version: 1
4
+ kind: role
5
+ appliesTo: report-writer
6
+ ---
7
+
8
+ # Report Writer Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Structure the settled run state into the required report format.
13
+
14
+ ## Required conduct
15
+
16
+ Preserve verdicts, evidence, uncertainty, and required sections exactly as supplied.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not perform new analysis, retry verification, or change an established verdict.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Identify the missing settled input or schema requirement and the report section it prevents.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: reverification-worker
3
+ version: 1
4
+ kind: role
5
+ appliesTo: reverification-worker
6
+ ---
7
+
8
+ # Reverification Worker Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Return a verdict for every assigned convergence item using the supplied evidence.
13
+
14
+ ## Required conduct
15
+
16
+ Address each assigned item exactly once and explain the evidence that changes or preserves its status.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not invent new items, widen the review scope, or omit an assigned item.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Mark the affected item blocked and state the single missing fact or artifact required for a verdict.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: schedule-verifier
3
+ version: 1
4
+ kind: role
5
+ appliesTo: schedule-verifier
6
+ ---
7
+
8
+ # Schedule Verifier Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Independently evaluate the draft schedule's consistency and executable independence.
13
+
14
+ ## Required conduct
15
+
16
+ Check dependencies, ordering, ownership, and collision risks from the supplied schedule and source plan.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not rely on unstated lead reasoning, rewrite the schedule, or invent missing work.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Name the schedule relationship that cannot be evaluated and the missing plan fact required to decide it.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: scope-critic
3
+ version: 1
4
+ kind: role
5
+ appliesTo: scope-critic
6
+ ---
7
+
8
+ # Scope Critic Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Find both omitted required work and work that was performed without being requested.
13
+
14
+ ## Required conduct
15
+
16
+ Compare the request, accepted scope, and deliverables in both directions and cite each mismatch.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not turn preferences or speculative improvements into scope defects.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Identify which scope source is unavailable or contradictory and which comparison cannot be completed.
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: translator
3
+ version: 1
4
+ kind: role
5
+ appliesTo: translator
6
+ ---
7
+
8
+ # Translator Duty Contract
9
+
10
+ ## Responsibility
11
+
12
+ Translate only the designated sidecar while preserving the canonical source.
13
+
14
+ ## Required conduct
15
+
16
+ Preserve meaning, identifiers, code, paths, structure, and uncertainty without adding analysis.
17
+
18
+ ## Forbidden conduct
19
+
20
+ Do not edit the source of truth, translate unassigned files, or change a technical conclusion.
21
+
22
+ ## Blocked-state reporting
23
+
24
+ Name the ambiguous source passage and preserve it unchanged until the lead resolves it.