agentflow-proof 1.0.0__py3-none-any.whl
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.
- agentflow/__init__.py +5 -0
- agentflow/__main__.py +5 -0
- agentflow/aggregate.py +1015 -0
- agentflow/artifacts.py +331 -0
- agentflow/capabilities.py +124 -0
- agentflow/cli.py +2108 -0
- agentflow/cli_contract.py +238 -0
- agentflow/contracts.py +263 -0
- agentflow/coverage.py +438 -0
- agentflow/draft_plan.py +402 -0
- agentflow/events.py +201 -0
- agentflow/execution.py +1027 -0
- agentflow/execution_coverage.py +646 -0
- agentflow/git.py +89 -0
- agentflow/handoff.py +112 -0
- agentflow/hunks.py +245 -0
- agentflow/locks.py +71 -0
- agentflow/mcp_server.py +710 -0
- agentflow/packs.py +398 -0
- agentflow/porcelain.py +1014 -0
- agentflow/proof.py +1062 -0
- agentflow/receipts.py +604 -0
- agentflow/recommend.py +299 -0
- agentflow/review.py +924 -0
- agentflow/review_runner.py +516 -0
- agentflow/risk.py +328 -0
- agentflow/runtime.py +863 -0
- agentflow/stuck.py +344 -0
- agentflow/validation.py +696 -0
- agentflow/versioning.py +120 -0
- agentflow/viewer.py +391 -0
- agentflow/workflow_contract.py +164 -0
- agentflow_proof-1.0.0.dist-info/METADATA +524 -0
- agentflow_proof-1.0.0.dist-info/RECORD +38 -0
- agentflow_proof-1.0.0.dist-info/WHEEL +5 -0
- agentflow_proof-1.0.0.dist-info/entry_points.txt +3 -0
- agentflow_proof-1.0.0.dist-info/licenses/LICENSE +21 -0
- agentflow_proof-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"""Generator for the machine-readable CLI contract manifest.
|
|
2
|
+
|
|
3
|
+
``docs/cli-contract.json`` is produced by ``scripts/gen_cli_contract.py`` from
|
|
4
|
+
:func:`build_cli_contract`; ``tests/test_stability_policy.py`` re-derives the
|
|
5
|
+
same inventory so any undocumented CLI surface drift fails CI.
|
|
6
|
+
|
|
7
|
+
The serialized argument records are a *stable projection* of the parser: they
|
|
8
|
+
deliberately expose only user-visible facts (names, requiredness, arity,
|
|
9
|
+
defaults, choices) and never argparse internals such as action class names or
|
|
10
|
+
``type`` callable names, which docs/stability.md classifies as changeable
|
|
11
|
+
Python internals.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
|
|
18
|
+
from .cli import build_parser
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
STEP_EVENT = {
|
|
22
|
+
"schema_version": "string", "event": "string", "step_id": "string",
|
|
23
|
+
"attempt_id": "string", "agent_id": "string|null", "recorded_at": "string",
|
|
24
|
+
"lease_expires_at": "string|null", "reason": "string|null",
|
|
25
|
+
"reason_code": "string|null", "findings": "array|null",
|
|
26
|
+
"amends_attempt": "string|null", "amends_completed_at": "string|null",
|
|
27
|
+
}
|
|
28
|
+
COMMAND_RECEIPT = {
|
|
29
|
+
"schema_version": "string", "id": "string", "step_id": "string",
|
|
30
|
+
"attempt_id": "string", "command": "array", "cwd": "string", "env_names": "array",
|
|
31
|
+
"gate": "string|null", "decision": "string", "risk": "object", "provenance": "string",
|
|
32
|
+
"started_at": "string", "finished_at": "string", "exit_code": "integer",
|
|
33
|
+
"timed_out": "boolean", "timeout_seconds": "number|null", "truncated": "boolean",
|
|
34
|
+
"stdout_path": "string", "stdout_sha256": "string", "stdout_truncated": "boolean",
|
|
35
|
+
"stderr_path": "string", "stderr_sha256": "string", "stderr_truncated": "boolean",
|
|
36
|
+
}
|
|
37
|
+
FILE_RECEIPT = {
|
|
38
|
+
"schema_version": "string", "id": "string", "step_id": "string",
|
|
39
|
+
"attempt_id": "string", "path": "string", "previous_path": "string|null",
|
|
40
|
+
"change_kind": "string", "before_git_blob": "string|null", "after_sha256": "string|null",
|
|
41
|
+
"diff_engine": "string", "diff_algorithm": "string", "diff_command_version": "string",
|
|
42
|
+
"diff_unified": "integer", "hunks": "array", "hunk_attribution": "string",
|
|
43
|
+
"recorded_at": "string",
|
|
44
|
+
}
|
|
45
|
+
VERIFICATION = {
|
|
46
|
+
"schema_version": "string", "id": "string", "scope": "string", "status": "string",
|
|
47
|
+
"step_id": "string|null", "attempt_id": "string|null", "strict": "boolean",
|
|
48
|
+
"replay": "boolean", "findings": "array", "recorded_at": "string",
|
|
49
|
+
}
|
|
50
|
+
RESUMABILITY = {
|
|
51
|
+
"type": "object|null",
|
|
52
|
+
"keys": {
|
|
53
|
+
"contract": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"keys": {
|
|
56
|
+
"plan_schema_version": "string|null",
|
|
57
|
+
"plan_sha256": "string|null",
|
|
58
|
+
"locked": "boolean",
|
|
59
|
+
"locked_at": "string|null",
|
|
60
|
+
"execution_schema_version": "string|null",
|
|
61
|
+
"execution_contract_sha256": "string|null",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
"agent_id": "string|null",
|
|
65
|
+
"step": {
|
|
66
|
+
"type": "object|null",
|
|
67
|
+
"keys": {
|
|
68
|
+
"id": "string",
|
|
69
|
+
"state": "string",
|
|
70
|
+
"completed": "boolean",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
"attempt": {
|
|
74
|
+
"type": "object|null",
|
|
75
|
+
"keys": {
|
|
76
|
+
"id": "string",
|
|
77
|
+
"state": "string|null",
|
|
78
|
+
"owner": "string|null",
|
|
79
|
+
"open": "boolean",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
"lease": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"keys": {
|
|
85
|
+
"policy": "string|null",
|
|
86
|
+
"ttl_minutes": "integer|null",
|
|
87
|
+
"grace_seconds": "integer|null",
|
|
88
|
+
"expires_at": "string|null",
|
|
89
|
+
"state": "string",
|
|
90
|
+
"exclusive": "boolean",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
"receipts": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"keys": {
|
|
96
|
+
"commands": {
|
|
97
|
+
"type": "array",
|
|
98
|
+
"items": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"keys": {
|
|
101
|
+
"id": "string",
|
|
102
|
+
"gate": "string|null",
|
|
103
|
+
"command": "array|null",
|
|
104
|
+
"exit_code": "integer|null",
|
|
105
|
+
"decision": "string|null",
|
|
106
|
+
"timed_out": "boolean",
|
|
107
|
+
"provenance": "string|null",
|
|
108
|
+
"finished_at": "string|null",
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
"files": {
|
|
113
|
+
"type": "array",
|
|
114
|
+
"items": {
|
|
115
|
+
"type": "object",
|
|
116
|
+
"keys": {
|
|
117
|
+
"id": "string",
|
|
118
|
+
"path": "string|null",
|
|
119
|
+
"change_kind": "string|null",
|
|
120
|
+
"recorded_at": "string|null",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
"gates": {
|
|
127
|
+
"type": "array",
|
|
128
|
+
"items": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"keys": {
|
|
131
|
+
"kind": "string",
|
|
132
|
+
"label": "string",
|
|
133
|
+
"status": "string",
|
|
134
|
+
"receipt_id": "string|null",
|
|
135
|
+
"evidence_id": "string|null",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
"recovery_actions": {
|
|
140
|
+
"type": "array",
|
|
141
|
+
"items": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"keys": {
|
|
144
|
+
"action": "string",
|
|
145
|
+
"allowed": "boolean",
|
|
146
|
+
"automatic": "boolean",
|
|
147
|
+
"break_glass": "boolean",
|
|
148
|
+
"reason": "string",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
"diagnostics": {
|
|
153
|
+
"type": "array",
|
|
154
|
+
"items": {
|
|
155
|
+
"type": "object",
|
|
156
|
+
"keys": {
|
|
157
|
+
"code": "string",
|
|
158
|
+
"message": "string",
|
|
159
|
+
"artifact": "string",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
JSON_OUTPUTS = {
|
|
167
|
+
"pack inspect": [{"type": "object", "keys": {"status": "string", "errors": "array", "id": "string|null", "version": "string|null", "profiles": "array|null", "manifest_sha256": "string|null"}}],
|
|
168
|
+
"doctor": [{"type": "object", "keys": {"status": "string", "contract": "object|null", "findings": "array"}}],
|
|
169
|
+
"lock-plan": [{"type": "object", "keys": {"status": "string", "errors": "array", "path": "string|null"}}],
|
|
170
|
+
"recommend-workflow": [{"type": "object", "keys": {"status": "string", "errors": "array", "recommended": "object|null", "selected": "object|null", "selection_mode": "string|null", "reason": "string|null"}}],
|
|
171
|
+
"draft-plan": [{"type": "object", "keys": {"schema_version": "string|null", "status": "string", "errors": "array|null", "path": "string|null", "contract_path": "string|null", "plan_candidate": "object|null", "workflow_contract": "object|null", "recommended": "object|null", "selected": "object|null", "selection_mode": "string|null", "warnings": "array|null"}}],
|
|
172
|
+
"record-review": [{"type": "object", "keys": {"schema_version": "string", "review_run_id": "string", "recorded_at": "string", "state_dir": "string", "manifest_path": "string", "manifest_sha256": "string", "plan_sha256": "string", "policy": "string|null", "gate_status": "string", "active_blocking": "array", "depth_profile": "string", "amendment_ready": "boolean", "findings": "object", "artifacts": "array"}}],
|
|
173
|
+
"review-manifest": [{"type": "object", "keys": {"schema_version": "string", "review_run_id": "string", "state_dir": "string", "policy": "string", "gate_status": "string", "active_blocking": "array", "depth_profile": "string", "amendment_ready": "boolean", "findings": "object", "artifacts": "array"}}],
|
|
174
|
+
"next-step": [{"type": "object", "keys": {"id": "string", "action": "string", "files": "array", "preconditions": "array", "validation": "array", "expected_diff": "array", "evidence_ids": "array", "design_decision_ids": "array|null"}}, {"type": "null"}],
|
|
175
|
+
"claim-step": [{"type": "object", "keys": STEP_EVENT}],
|
|
176
|
+
"amend-step": [{"type": "object", "keys": STEP_EVENT}],
|
|
177
|
+
"complete-step": [{"type": "object", "keys": STEP_EVENT}],
|
|
178
|
+
"block-step": [{"type": "object", "keys": STEP_EVENT}],
|
|
179
|
+
"fail-step": [{"type": "object", "keys": STEP_EVENT}],
|
|
180
|
+
"reclaim-step": [{"type": "object", "keys": STEP_EVENT}],
|
|
181
|
+
"renew-lease": [{"type": "object", "keys": STEP_EVENT}],
|
|
182
|
+
"run": [{"type": "object", "keys": COMMAND_RECEIPT}],
|
|
183
|
+
"record-command": [{"type": "object", "keys": COMMAND_RECEIPT}],
|
|
184
|
+
"record-file-change": [{"type": "array", "items": {"type": "object", "keys": FILE_RECEIPT}}],
|
|
185
|
+
"verify-step": [{"type": "object", "keys": VERIFICATION}],
|
|
186
|
+
"verify-run": [{"type": "object", "keys": VERIFICATION}],
|
|
187
|
+
"aggregate-ledgers": [
|
|
188
|
+
{"type": "object", "keys": {"status": "string", "sources": "array", "collisions": "array", "planned": "object"}},
|
|
189
|
+
{"type": "object", "keys": {"status": "string", "sources": "array", "written": "object"}},
|
|
190
|
+
],
|
|
191
|
+
"detect-stuck": [{"type": "object", "keys": {"schema_version": "string", "status": "string", "findings": "array", "thresholds": "object", "recorded_at": "string"}}],
|
|
192
|
+
"lint-handoff": [{"type": "object", "keys": {"findings": "array"}}],
|
|
193
|
+
"replay-gates": [{"type": "object", "keys": {"status": "string", "errors": "array", "warnings": "array", "receipts": "array", "recorded": "boolean"}}],
|
|
194
|
+
"runtime-status": [{"type": "object", "keys": {"schema_version": "string|null", "id": "string|null", "status": "string|null", "runtimes": "array|null", "mcp_servers": "array|null", "routes": "array|null", "findings": "array", "runtime_config_sha256": "string|null", "created_at": "string|null"}}],
|
|
195
|
+
"events": [{"type": "array", "items": {"type": "object", "keys": {"timestamp": "string", "type": "string", "step_id": "string|null", "attempt_id": "string|null", "source": "object", "data": "object"}}}],
|
|
196
|
+
"next-action": [{"type": "object", "keys": {"state": "string", "reason": "string", "blocking": "boolean", "command": "string|null", "args": "array|null", "step_id": "string|null", "gate": "string|null", "diagnostics": "array", "resumability": RESUMABILITY}}],
|
|
197
|
+
"finish-step": [{"type": "object", "keys": {"verification_status": "string", "verified": "boolean", "completed": "boolean", "diagnostics": "array"}}],
|
|
198
|
+
"finish-run": [{"type": "object", "keys": {"ok": "boolean", "gates": "array", "stopped_at": "string|null", "diagnostics": "array"}}],
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
_MULTI_VALUE_NARGS = ("*", "+", argparse.REMAINDER)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def build_cli_contract() -> dict:
|
|
205
|
+
def arguments(parser: argparse.ArgumentParser) -> list:
|
|
206
|
+
result = []
|
|
207
|
+
for action in parser._actions:
|
|
208
|
+
if isinstance(action, argparse._SubParsersAction) or action.dest == "help":
|
|
209
|
+
continue
|
|
210
|
+
default = action.default
|
|
211
|
+
if default is argparse.SUPPRESS or callable(default):
|
|
212
|
+
default = None
|
|
213
|
+
required = bool(action.option_strings and action.required) or (
|
|
214
|
+
not action.option_strings
|
|
215
|
+
and action.nargs not in ("?", "*", argparse.REMAINDER)
|
|
216
|
+
)
|
|
217
|
+
result.append({
|
|
218
|
+
"names": action.option_strings or [action.dest],
|
|
219
|
+
"required": required, "nargs": action.nargs, "default": default,
|
|
220
|
+
"choices": list(action.choices) if action.choices is not None else None,
|
|
221
|
+
"takes_value": action.nargs != 0,
|
|
222
|
+
"multiple": action.nargs in _MULTI_VALUE_NARGS
|
|
223
|
+
or isinstance(action, argparse._AppendAction),
|
|
224
|
+
})
|
|
225
|
+
return result
|
|
226
|
+
|
|
227
|
+
commands: dict = {}
|
|
228
|
+
|
|
229
|
+
def walk(parser: argparse.ArgumentParser, prefix: str = "") -> None:
|
|
230
|
+
for action in parser._actions:
|
|
231
|
+
if isinstance(action, argparse._SubParsersAction):
|
|
232
|
+
for name, child in action.choices.items():
|
|
233
|
+
command = f"{prefix} {name}".strip()
|
|
234
|
+
commands[command] = arguments(child)
|
|
235
|
+
walk(child, command)
|
|
236
|
+
|
|
237
|
+
walk(build_parser())
|
|
238
|
+
return {"schema_version": "1.0.0", "commands": commands, "json_outputs": JSON_OUTPUTS}
|
agentflow/contracts.py
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"""Shared Agentflow artifact contracts and enums."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
TOOL_VERSION = "0.3.0"
|
|
10
|
+
|
|
11
|
+
PLAN_SCHEMA_VERSION = "1.0.0"
|
|
12
|
+
EVIDENCE_SCHEMA_VERSION = "0.2.0"
|
|
13
|
+
ASSUMPTIONS_SCHEMA_VERSION = "0.2.0"
|
|
14
|
+
AMENDMENTS_SCHEMA_VERSION = "0.2.0"
|
|
15
|
+
CONTEXT_RECEIPTS_SCHEMA_VERSION = "0.2.0"
|
|
16
|
+
FAILURES_SCHEMA_VERSION = "0.2.0"
|
|
17
|
+
DRIFT_REPORT_SCHEMA_VERSION = "1.0.0"
|
|
18
|
+
PROOF_PACK_SCHEMA_VERSION = "1.0.0"
|
|
19
|
+
RUNTIME_CONFIG_SCHEMA_VERSION = "0.3.0"
|
|
20
|
+
RUNTIME_SNAPSHOT_SCHEMA_VERSION = "0.3.0"
|
|
21
|
+
WORKFLOW_CONTRACT_SCHEMA_VERSION = "0.1.0"
|
|
22
|
+
WORKFLOW_PACK_SCHEMA_VERSION = "0.1.0"
|
|
23
|
+
CAPABILITY_RECEIPTS_SCHEMA_VERSION = "0.1.0"
|
|
24
|
+
AGGREGATION_SCHEMA_VERSION = "0.1.0"
|
|
25
|
+
|
|
26
|
+
EXECUTION_CONTRACT_SCHEMA_VERSION = "1.0.0"
|
|
27
|
+
STEP_RUNS_SCHEMA_VERSION = "1.0.0"
|
|
28
|
+
COMMAND_RECEIPTS_SCHEMA_VERSION = "1.0.0"
|
|
29
|
+
FILE_RECEIPTS_SCHEMA_VERSION = "1.0.0"
|
|
30
|
+
VERIFICATION_RUNS_SCHEMA_VERSION = "1.0.0"
|
|
31
|
+
|
|
32
|
+
REVIEW_RUNS_SCHEMA_VERSION = "0.6.0"
|
|
33
|
+
REVIEW_MANIFEST_SCHEMA_VERSION = "1.0.0" # keep in lockstep with review_runner.MANIFEST_SCHEMA_VERSION
|
|
34
|
+
|
|
35
|
+
ARTIFACT_SCHEMA_VERSIONS = {
|
|
36
|
+
"plan-lock": PLAN_SCHEMA_VERSION,
|
|
37
|
+
"evidence": EVIDENCE_SCHEMA_VERSION,
|
|
38
|
+
"assumptions": ASSUMPTIONS_SCHEMA_VERSION,
|
|
39
|
+
"amendments": AMENDMENTS_SCHEMA_VERSION,
|
|
40
|
+
"context-receipts": CONTEXT_RECEIPTS_SCHEMA_VERSION,
|
|
41
|
+
"failures": FAILURES_SCHEMA_VERSION,
|
|
42
|
+
"drift-report": DRIFT_REPORT_SCHEMA_VERSION,
|
|
43
|
+
"proof-pack": PROOF_PACK_SCHEMA_VERSION,
|
|
44
|
+
"runtime-config": RUNTIME_CONFIG_SCHEMA_VERSION,
|
|
45
|
+
"runtime-snapshot": RUNTIME_SNAPSHOT_SCHEMA_VERSION,
|
|
46
|
+
"workflow-contract": WORKFLOW_CONTRACT_SCHEMA_VERSION,
|
|
47
|
+
"capability-receipts": CAPABILITY_RECEIPTS_SCHEMA_VERSION,
|
|
48
|
+
"review-runs": REVIEW_RUNS_SCHEMA_VERSION,
|
|
49
|
+
"aggregation": AGGREGATION_SCHEMA_VERSION,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
EXECUTION_ARTIFACT_SCHEMA_VERSIONS = {
|
|
53
|
+
"execution-contract": EXECUTION_CONTRACT_SCHEMA_VERSION,
|
|
54
|
+
"step-runs": STEP_RUNS_SCHEMA_VERSION,
|
|
55
|
+
"command-receipts": COMMAND_RECEIPTS_SCHEMA_VERSION,
|
|
56
|
+
"file-receipts": FILE_RECEIPTS_SCHEMA_VERSION,
|
|
57
|
+
"verification-runs": VERIFICATION_RUNS_SCHEMA_VERSION,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Working-state ingestion policy. Historical cross-major proof compatibility is
|
|
61
|
+
# handled only by verify-proof; no generic reader inherits that promise.
|
|
62
|
+
POLICY_EXACT = "exact"
|
|
63
|
+
POLICY_SAME_MAJOR = "same_major"
|
|
64
|
+
POLICY_NONE = "none"
|
|
65
|
+
# Fallback used by validate_schema_version for artifacts outside this table
|
|
66
|
+
# (e.g. the transient task-brief intake); named so the default is a visible
|
|
67
|
+
# decision, not an accident of a .get() call.
|
|
68
|
+
DEFAULT_COMPATIBILITY_POLICY = POLICY_SAME_MAJOR
|
|
69
|
+
|
|
70
|
+
# Every declared artifact is classified explicitly (no comprehension fill), so
|
|
71
|
+
# adding an artifact forces a policy decision here and the guard test in
|
|
72
|
+
# test_schema_contracts can actually fail on an unclassified one.
|
|
73
|
+
ARTIFACT_COMPATIBILITY_POLICIES = {
|
|
74
|
+
"plan-lock": POLICY_SAME_MAJOR,
|
|
75
|
+
"evidence": POLICY_SAME_MAJOR,
|
|
76
|
+
"assumptions": POLICY_SAME_MAJOR,
|
|
77
|
+
"amendments": POLICY_SAME_MAJOR,
|
|
78
|
+
"context-receipts": POLICY_SAME_MAJOR,
|
|
79
|
+
"failures": POLICY_SAME_MAJOR,
|
|
80
|
+
"drift-report": POLICY_SAME_MAJOR,
|
|
81
|
+
"proof-pack": POLICY_NONE,
|
|
82
|
+
"runtime-config": POLICY_SAME_MAJOR,
|
|
83
|
+
"runtime-snapshot": POLICY_SAME_MAJOR,
|
|
84
|
+
"workflow-contract": POLICY_SAME_MAJOR,
|
|
85
|
+
"capability-receipts": POLICY_SAME_MAJOR,
|
|
86
|
+
"review-runs": POLICY_SAME_MAJOR,
|
|
87
|
+
"aggregation": POLICY_SAME_MAJOR,
|
|
88
|
+
"execution-contract": POLICY_EXACT,
|
|
89
|
+
"step-runs": POLICY_SAME_MAJOR,
|
|
90
|
+
"command-receipts": POLICY_SAME_MAJOR,
|
|
91
|
+
"file-receipts": POLICY_SAME_MAJOR,
|
|
92
|
+
"verification-runs": POLICY_SAME_MAJOR,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Derived summaries and transient intake files are intentionally excluded.
|
|
96
|
+
BASE_ARTIFACT_PATHS = {
|
|
97
|
+
"plan-lock": ".agent/plan.lock.json",
|
|
98
|
+
"evidence": ".agent/evidence.jsonl",
|
|
99
|
+
"assumptions": ".agent/assumptions.json",
|
|
100
|
+
"context-receipts": ".agent/context-receipts.jsonl",
|
|
101
|
+
"failures": ".agent/failures.jsonl",
|
|
102
|
+
"amendments": ".agent/amendments.jsonl",
|
|
103
|
+
"drift-report": ".agent/drift-report.json",
|
|
104
|
+
"runtime-config": ".agent/runtime.config.json",
|
|
105
|
+
"runtime-snapshot": ".agent/runtime-snapshots.jsonl",
|
|
106
|
+
"workflow-contract": ".agent/workflow.contract.json",
|
|
107
|
+
"capability-receipts": ".agent/capability-receipts.jsonl",
|
|
108
|
+
"review-runs": ".agent/review-runs.jsonl",
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
EXECUTION_ARTIFACT_PATHS = {
|
|
112
|
+
"execution-contract": ".agent/execution.contract.json",
|
|
113
|
+
"step-runs": ".agent/step-runs.jsonl",
|
|
114
|
+
"command-receipts": ".agent/command-receipts.jsonl",
|
|
115
|
+
"file-receipts": ".agent/file-receipts.jsonl",
|
|
116
|
+
"verification-runs": ".agent/verification-runs.jsonl",
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
ARTIFACT_PATHS = {
|
|
120
|
+
**BASE_ARTIFACT_PATHS,
|
|
121
|
+
**EXECUTION_ARTIFACT_PATHS,
|
|
122
|
+
# "aggregation" lives only here, not in BASE_ARTIFACT_PATHS or
|
|
123
|
+
# EXECUTION_ARTIFACT_PATHS: those two dicts drive aggregate.py's own
|
|
124
|
+
# merge-source path list (_ALL_PATHS) and proof.py's normalized execution
|
|
125
|
+
# hash, and adding aggregation.json to either would fold it into the
|
|
126
|
+
# cross-worktree merge/hash it is itself the output of.
|
|
127
|
+
"aggregation": ".agent/aggregation.json",
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
ADAPTERS = ("claude", "codex", "custom", "go-llm", "openai-compatible")
|
|
131
|
+
ROUTE_POLICIES = (
|
|
132
|
+
"manual_only",
|
|
133
|
+
"prefer_local",
|
|
134
|
+
"prefer_low_cost",
|
|
135
|
+
"prefer_quality",
|
|
136
|
+
"prefer_speed",
|
|
137
|
+
)
|
|
138
|
+
READINESS_CHECKS = ("command_exists", "command_spawn", "http", "http_status", "none")
|
|
139
|
+
# #19: MCP servers are evidence-only. http (the /v1/models capability probe) is
|
|
140
|
+
# runtime-specific; MCP liveness uses http_status.
|
|
141
|
+
MCP_READINESS_CHECKS = ("command_exists", "command_spawn", "http_status", "none")
|
|
142
|
+
MCP_TRANSPORTS = ("http", "sse", "stdio")
|
|
143
|
+
MCP_SERVER_STATUSES = ("configured", "ready", "unavailable")
|
|
144
|
+
RUNTIME_STATUSES = ("configured", "ready", "degraded", "unavailable")
|
|
145
|
+
CAPABILITY_SOURCES = ("declared", "probed", "none")
|
|
146
|
+
EVIDENCE_KINDS = ("command", "file", "log", "review", "runtime", "test", "url", "user")
|
|
147
|
+
CHECK_STATUSES = (
|
|
148
|
+
"failed",
|
|
149
|
+
"not_applicable",
|
|
150
|
+
"not_run",
|
|
151
|
+
"passed",
|
|
152
|
+
"skipped",
|
|
153
|
+
"warning",
|
|
154
|
+
)
|
|
155
|
+
EXECUTION_MODES = ("assistive", "external", "manual", "same_session")
|
|
156
|
+
AUTHORITIES = ("advise", "commit", "edit", "read", "verify")
|
|
157
|
+
RISK_LEVELS = ("low", "medium", "high")
|
|
158
|
+
RISK_POLICIES = ("block", "require-confirmation", "warn")
|
|
159
|
+
REVIEW_GATE_POLICIES = ("block", "ignore", "warn")
|
|
160
|
+
WORKFLOW_REVIEW_DEPTHS = ("deep", "light", "none", "spec_quality", "standard")
|
|
161
|
+
# #74: each workflow review_depth contributes a (review-gate floor, requires-run)
|
|
162
|
+
# policy. Joined over the execution-contract gate at proof time; the floor can only
|
|
163
|
+
# raise strictness, never lower it. ``none`` requires no run but does not suppress a
|
|
164
|
+
# recorded review run's own gate (the join leaves the execution default in place).
|
|
165
|
+
REVIEW_DEPTH_POLICY = {
|
|
166
|
+
"none": ("ignore", False),
|
|
167
|
+
"light": ("warn", False),
|
|
168
|
+
"standard": ("warn", False),
|
|
169
|
+
"spec_quality": ("block", True),
|
|
170
|
+
"deep": ("block", True),
|
|
171
|
+
}
|
|
172
|
+
# Total order over review depths (#71 draft-plan solver, #92 recorded-run depth).
|
|
173
|
+
REVIEW_DEPTH_ORDER = {"none": 0, "light": 1, "standard": 2, "spec_quality": 3, "deep": 4}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def review_depth_rank(depth: str) -> int:
|
|
177
|
+
"""Rank a validated review depth (KeyError on an unknown value)."""
|
|
178
|
+
return REVIEW_DEPTH_ORDER[depth]
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def recorded_review_depth(depth: Optional[str]) -> str:
|
|
182
|
+
"""Resolve a recorded run's ``depth_profile``.
|
|
183
|
+
|
|
184
|
+
Absent (``None``) is a legacy pre-#92 run and ranks as ``deep`` — it
|
|
185
|
+
satisfies every requirement, so old ledgers keep verifying. A present but
|
|
186
|
+
out-of-enum value is malformed review evidence, not a silent ``deep``.
|
|
187
|
+
"""
|
|
188
|
+
if depth is None:
|
|
189
|
+
return "deep"
|
|
190
|
+
if depth not in REVIEW_DEPTH_ORDER:
|
|
191
|
+
raise ValueError(f"review depth invalid: {depth!r}")
|
|
192
|
+
return depth
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def review_depth_satisfies(recorded: str, required: Optional[str]) -> bool:
|
|
196
|
+
"""True when a recorded run depth satisfies a required depth.
|
|
197
|
+
|
|
198
|
+
``required=None`` means a run is required but no depth floor was declared
|
|
199
|
+
(e.g. an execution-contract-only ``require_review_run``), so any recorded
|
|
200
|
+
run satisfies it. Never treat ``None`` as ``deep`` — that would silently
|
|
201
|
+
raise strictness.
|
|
202
|
+
"""
|
|
203
|
+
if required is None:
|
|
204
|
+
return True
|
|
205
|
+
return review_depth_rank(recorded) >= review_depth_rank(required)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
CAPABILITY_STATUSES = ("used", "waived")
|
|
209
|
+
CAPABILITY_IDS = (
|
|
210
|
+
"tdd",
|
|
211
|
+
"debugging",
|
|
212
|
+
"security-review",
|
|
213
|
+
"frontend-qa",
|
|
214
|
+
"review-spec",
|
|
215
|
+
"review-quality",
|
|
216
|
+
"strict-verification",
|
|
217
|
+
)
|
|
218
|
+
DEFAULT_COMMAND_TIMEOUT_SECONDS = 600
|
|
219
|
+
COMMAND_DECISIONS = ("allowed", "blocked", "timeout")
|
|
220
|
+
RISK_CATEGORIES = (
|
|
221
|
+
"blocked_path",
|
|
222
|
+
"credential_read",
|
|
223
|
+
"destructive_delete",
|
|
224
|
+
"permission_change",
|
|
225
|
+
"pipe_to_shell",
|
|
226
|
+
"privilege_escalation",
|
|
227
|
+
"write_outside_scope",
|
|
228
|
+
)
|
|
229
|
+
PROVENANCE_VALUES = ("attested", "managed", "observed", "reconstructed")
|
|
230
|
+
TRUSTED_PROVENANCE_VALUES = ("managed", "observed", "reconstructed")
|
|
231
|
+
CHANGE_KINDS = ("added", "deleted", "modified", "renamed")
|
|
232
|
+
DIFF_COMMAND_VERSION = "afhunk-v1"
|
|
233
|
+
HUNK_ATTRIBUTION_POLICIES = ("enforce", "observe", "off")
|
|
234
|
+
UNMAPPED_HUNK_REASONS = ("no_matching_hunk",)
|
|
235
|
+
GATE_KINDS = ("command", "inspection")
|
|
236
|
+
STEP_EVENT_KINDS = (
|
|
237
|
+
"abandoned",
|
|
238
|
+
"blocked",
|
|
239
|
+
"claimed",
|
|
240
|
+
"completed",
|
|
241
|
+
"failed",
|
|
242
|
+
"in_progress",
|
|
243
|
+
"lease_renewed",
|
|
244
|
+
"verified",
|
|
245
|
+
)
|
|
246
|
+
RECEIPT_STORES = ("by_attempt", "content_addressed")
|
|
247
|
+
WRITER_MODELS = ("single_writer",)
|
|
248
|
+
LEASE_POLICIES = ("advisory", "enforce")
|
|
249
|
+
DEFAULT_LEASE_TTL_MINUTES = 30
|
|
250
|
+
DEFAULT_LEASE_GRACE_SECONDS = 30
|
|
251
|
+
PROVIDER_NEUTRAL_DENYLIST = (
|
|
252
|
+
"browser tool",
|
|
253
|
+
"chatgpt",
|
|
254
|
+
"claude",
|
|
255
|
+
"codex",
|
|
256
|
+
"mcp",
|
|
257
|
+
"provider function",
|
|
258
|
+
"superpowers",
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def strict_mode(cli_strict: bool = False) -> bool:
|
|
263
|
+
return cli_strict or os.environ.get("AGENTFLOW_STRICT") == "1"
|