@ccoalm/ccl-skills 0.16.0 → 0.18.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/dist/assets/marketplace/plugins/ccl-skills/agent-context/session-start.md +8 -7
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +22 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-review-covers-head.sh +128 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-untracked-background.sh +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_review_covers_head.sh +104 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_untracked_background.sh +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/SKILL.md +6 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/development-completion.md +13 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +78 -126
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/wording-only-review.md +136 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +521 -32
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +25 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_order.sh +30 -15
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +439 -19
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_update_review_plan_intent.sh +14 -7
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/SKILL.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +6 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/attention-budget-ratchet.md +1 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +48 -119
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +9 -9
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +22 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check_review_evidence_present.py +122 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/contract-anchors.tsv +4 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh +37 -8
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +102 -20
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ai_coding_implementation_gates.sh +16 -27
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +3 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_review_evidence_present.sh +81 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_extraction_review_gate.sh +137 -279
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_resolution.sh +41 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +49 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +3 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/closeout-reread.md +40 -0
- package/dist/assets/release.json +72 -52
- package/package.json +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/review_ledger_binding.py +0 -1242
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_review_ledger_binding.sh +0 -978
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_extraction_review_state.sh +0 -1477
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate_extraction_review_state.py +0 -1183
|
@@ -1,1477 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Regression for receipt-bound extraction review terminal-state validation.
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
6
|
-
VALIDATOR="$SCRIPT_DIR/validate_extraction_review_state.py"
|
|
7
|
-
[ -f "$VALIDATOR" ] || { echo "FAIL: validator not found: $VALIDATOR" >&2; exit 1; }
|
|
8
|
-
|
|
9
|
-
TMP="$(mktemp -d "${TMPDIR:-/tmp}/extraction-review-state.XXXXXX")"
|
|
10
|
-
trap 'rm -rf "$TMP"' EXIT
|
|
11
|
-
|
|
12
|
-
python3 - "$VALIDATOR" "$TMP" <<'PY'
|
|
13
|
-
import copy
|
|
14
|
-
import hashlib
|
|
15
|
-
import json
|
|
16
|
-
import os
|
|
17
|
-
import subprocess
|
|
18
|
-
import sys
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
|
|
21
|
-
validator = Path(sys.argv[1])
|
|
22
|
-
root = Path(sys.argv[2])
|
|
23
|
-
A, B, C = (character * 40 for character in "abc")
|
|
24
|
-
CANDIDATE = "d" * 64
|
|
25
|
-
OTHER_CANDIDATE = "e" * 64
|
|
26
|
-
CLOSED_DISPOSITIONS = {
|
|
27
|
-
"fixed",
|
|
28
|
-
"source_refuted",
|
|
29
|
-
"accepted_tradeoff",
|
|
30
|
-
"pre_existing_out_of_scope",
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def canonical_hash(value):
|
|
35
|
-
encoded = json.dumps(
|
|
36
|
-
value, ensure_ascii=False, sort_keys=True, separators=(",", ":")
|
|
37
|
-
).encode()
|
|
38
|
-
return hashlib.sha256(encoded).hexdigest()
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def write_json(name, payload):
|
|
42
|
-
encoded = (json.dumps(payload, ensure_ascii=False, indent=2) + "\n").encode()
|
|
43
|
-
(root / name).write_bytes(encoded)
|
|
44
|
-
return hashlib.sha256(encoded).hexdigest()
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def encode_duplicate_key(payload, field, first_value):
|
|
48
|
-
pairs = []
|
|
49
|
-
for key, value in payload.items():
|
|
50
|
-
if key == field:
|
|
51
|
-
pairs.append((key, first_value))
|
|
52
|
-
pairs.append((key, value))
|
|
53
|
-
return (
|
|
54
|
-
"{"
|
|
55
|
-
+ ",".join(
|
|
56
|
-
f"{json.dumps(key)}:{json.dumps(value, ensure_ascii=False)}"
|
|
57
|
-
for key, value in pairs
|
|
58
|
-
)
|
|
59
|
-
+ "}\n"
|
|
60
|
-
).encode()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def write_duplicate_json(name, payload, field, first_value):
|
|
64
|
-
encoded = encode_duplicate_key(payload, field, first_value)
|
|
65
|
-
(root / name).write_bytes(encoded)
|
|
66
|
-
return hashlib.sha256(encoded).hexdigest()
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def write_base_evidence(name, base_sha, ref="refs/heads/dev"):
|
|
70
|
-
encoded = f"{base_sha}\t{ref}\n".encode()
|
|
71
|
-
(root / name).write_bytes(encoded)
|
|
72
|
-
return hashlib.sha256(encoded).hexdigest()
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def occurrence_ref(occurrence):
|
|
76
|
-
return {
|
|
77
|
-
"receipt_sha256": occurrence["receipt_sha256"],
|
|
78
|
-
"finding_sha256": occurrence["finding_sha256"],
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def bind_disposition_evidence(name, occurrence, *, resolves=None, evidence=None):
|
|
83
|
-
if resolves is None:
|
|
84
|
-
resolves = [occurrence_ref(occurrence)]
|
|
85
|
-
if evidence is None:
|
|
86
|
-
evidence = [
|
|
87
|
-
f"synthetic {occurrence['disposition']} evidence for the current candidate"
|
|
88
|
-
]
|
|
89
|
-
payload = {
|
|
90
|
-
"schema_version": 1,
|
|
91
|
-
"candidate_sha256": CANDIDATE,
|
|
92
|
-
"receipt_sha256": occurrence["receipt_sha256"],
|
|
93
|
-
"finding_sha256": occurrence["finding_sha256"],
|
|
94
|
-
"disposition": occurrence["disposition"],
|
|
95
|
-
"resolves_occurrences": copy.deepcopy(resolves),
|
|
96
|
-
"evidence": list(evidence),
|
|
97
|
-
}
|
|
98
|
-
evidence_hash = write_json(name, payload)
|
|
99
|
-
occurrence.update(
|
|
100
|
-
disposition_evidence_file=name,
|
|
101
|
-
disposition_evidence_sha256=evidence_hash,
|
|
102
|
-
)
|
|
103
|
-
return payload
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def clear_disposition_evidence(occurrence):
|
|
107
|
-
occurrence.pop("disposition_evidence_file", None)
|
|
108
|
-
occurrence.pop("disposition_evidence_sha256", None)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def mutate_disposition_evidence(occurrence, mutator):
|
|
112
|
-
evidence_path = root / occurrence["disposition_evidence_file"]
|
|
113
|
-
payload = json.loads(evidence_path.read_text(encoding="utf-8"))
|
|
114
|
-
mutator(payload)
|
|
115
|
-
occurrence["disposition_evidence_sha256"] = write_json(
|
|
116
|
-
occurrence["disposition_evidence_file"], payload
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def duplicate_disposition_evidence_key(occurrence, field, first_value):
|
|
121
|
-
evidence_path = root / occurrence["disposition_evidence_file"]
|
|
122
|
-
payload = json.loads(evidence_path.read_text(encoding="utf-8"))
|
|
123
|
-
encoded = encode_duplicate_key(payload, field, first_value)
|
|
124
|
-
evidence_path.write_bytes(encoded)
|
|
125
|
-
occurrence["disposition_evidence_sha256"] = hashlib.sha256(encoded).hexdigest()
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def finding(number):
|
|
129
|
-
return {
|
|
130
|
-
"severity": "P1",
|
|
131
|
-
"title": f"receipt-bound finding {number}",
|
|
132
|
-
"body": f"failure path {number}",
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def make_fixture(
|
|
137
|
-
name,
|
|
138
|
-
*,
|
|
139
|
-
receipt_findings=None,
|
|
140
|
-
receipt_mutators=None,
|
|
141
|
-
completion=True,
|
|
142
|
-
completion_mutator=None,
|
|
143
|
-
budget=1,
|
|
144
|
-
base_shas=None,
|
|
145
|
-
closeout=None,
|
|
146
|
-
unmatched=0,
|
|
147
|
-
open_last=False,
|
|
148
|
-
succession=False,
|
|
149
|
-
):
|
|
150
|
-
if receipt_findings is None:
|
|
151
|
-
receipt_findings = [[finding(1)], []]
|
|
152
|
-
receipt_mutators = receipt_mutators or {}
|
|
153
|
-
rounds = len(receipt_findings)
|
|
154
|
-
scope = {
|
|
155
|
-
"schema_version": 3,
|
|
156
|
-
"intent_sha256": "1" * 64,
|
|
157
|
-
"acceptance_sha256": "2" * 64,
|
|
158
|
-
"stage": "release",
|
|
159
|
-
"review_depth": "release",
|
|
160
|
-
"risk_tags": ["shared-gate"],
|
|
161
|
-
"challenge_budget": budget,
|
|
162
|
-
"wording_only_proof_sha256": None,
|
|
163
|
-
"wording_only_scope_sha256": None,
|
|
164
|
-
}
|
|
165
|
-
scope_sha = canonical_hash(scope)
|
|
166
|
-
receipts = []
|
|
167
|
-
receipt_hashes = []
|
|
168
|
-
receipt_refs = []
|
|
169
|
-
for index, findings in enumerate(receipt_findings, start=1):
|
|
170
|
-
# With a succession the LAST round opens a second chain: its own chain
|
|
171
|
-
# arithmetic restarts at one while its lane position keeps counting.
|
|
172
|
-
is_succession = succession and index == rounds
|
|
173
|
-
chain_position = 1 if is_succession else index
|
|
174
|
-
mode = "challenge" if is_succession else "review" if index == 1 else "challenge"
|
|
175
|
-
status = "findings" if findings else "passed"
|
|
176
|
-
remaining = 2 - chain_position
|
|
177
|
-
if status == "findings":
|
|
178
|
-
state = "post_review_budget" if chain_position == 2 else "findings_pending"
|
|
179
|
-
else:
|
|
180
|
-
state = "reviewed"
|
|
181
|
-
receipt = {
|
|
182
|
-
"schema_version": 3,
|
|
183
|
-
"mode": mode,
|
|
184
|
-
"status": status,
|
|
185
|
-
"findings": copy.deepcopy(findings),
|
|
186
|
-
"review_chain_tracked": True,
|
|
187
|
-
"review_chain_id": (
|
|
188
|
-
"extraction-succession" if is_succession else "extraction-chain"
|
|
189
|
-
),
|
|
190
|
-
"autonomous_review_index": chain_position,
|
|
191
|
-
"autonomous_review_budget": 2,
|
|
192
|
-
"autonomous_reviews_remaining": remaining,
|
|
193
|
-
"autonomous_review_allowed": remaining > 0,
|
|
194
|
-
"challenge_index": 1 if is_succession else 0 if index == 1 else index - 1,
|
|
195
|
-
"challenge_budget": budget,
|
|
196
|
-
"prior_review_result_sha256": [] if is_succession else list(receipt_hashes),
|
|
197
|
-
"predecessor_chain_id": "extraction-chain" if is_succession else None,
|
|
198
|
-
"predecessor_result_sha256": (
|
|
199
|
-
receipt_hashes[-1] if is_succession and receipt_hashes else None
|
|
200
|
-
),
|
|
201
|
-
"predecessor_candidate_sha256": OTHER_CANDIDATE if is_succession else None,
|
|
202
|
-
"candidate_sha256": (
|
|
203
|
-
OTHER_CANDIDATE if succession and not is_succession else CANDIDATE
|
|
204
|
-
),
|
|
205
|
-
"packet_sha256": (
|
|
206
|
-
OTHER_CANDIDATE if succession and not is_succession else CANDIDATE
|
|
207
|
-
),
|
|
208
|
-
"review_scope": copy.deepcopy(scope),
|
|
209
|
-
"review_scope_sha256": scope_sha,
|
|
210
|
-
"wording_only_proof_sha256": None,
|
|
211
|
-
"wording_only_scope": None,
|
|
212
|
-
"stage": "release",
|
|
213
|
-
"review_depth": "release",
|
|
214
|
-
"risk_tags": ["shared-gate"],
|
|
215
|
-
"review_state": state,
|
|
216
|
-
"human_decision_required": state == "post_review_budget",
|
|
217
|
-
}
|
|
218
|
-
mutator = receipt_mutators.get(index)
|
|
219
|
-
if mutator is not None:
|
|
220
|
-
mutator(receipt)
|
|
221
|
-
receipt_name = f"{name}-round-{index}.json"
|
|
222
|
-
receipt_hash = write_json(receipt_name, receipt)
|
|
223
|
-
receipts.append(receipt)
|
|
224
|
-
receipt_hashes.append(receipt_hash)
|
|
225
|
-
receipt_refs.append(
|
|
226
|
-
{"sequence": index, "file": receipt_name, "sha256": receipt_hash}
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
completion_ref = None
|
|
230
|
-
if completion:
|
|
231
|
-
final = receipts[-1]
|
|
232
|
-
complete = {
|
|
233
|
-
"schema_version": 3,
|
|
234
|
-
"mode": "complete",
|
|
235
|
-
"status": "passed",
|
|
236
|
-
"findings": [],
|
|
237
|
-
"review_chain_tracked": True,
|
|
238
|
-
"review_chain_id": final["review_chain_id"],
|
|
239
|
-
"autonomous_review_index": final["autonomous_review_index"],
|
|
240
|
-
"autonomous_review_budget": 2,
|
|
241
|
-
"autonomous_reviews_remaining": final["autonomous_reviews_remaining"],
|
|
242
|
-
"autonomous_review_allowed": False,
|
|
243
|
-
"challenge_budget": budget,
|
|
244
|
-
"prior_review_result_sha256": copy.deepcopy(
|
|
245
|
-
final["prior_review_result_sha256"]
|
|
246
|
-
),
|
|
247
|
-
"candidate_sha256": final["candidate_sha256"],
|
|
248
|
-
"packet_sha256": final["packet_sha256"],
|
|
249
|
-
"review_scope": copy.deepcopy(final["review_scope"]),
|
|
250
|
-
"review_scope_sha256": final["review_scope_sha256"],
|
|
251
|
-
"wording_only_proof_sha256": None,
|
|
252
|
-
"wording_only_scope": None,
|
|
253
|
-
"stage": final["stage"],
|
|
254
|
-
"review_depth": final["review_depth"],
|
|
255
|
-
"risk_tags": copy.deepcopy(final["risk_tags"]),
|
|
256
|
-
"review_state": "self_reviewed",
|
|
257
|
-
"completion_gated": False,
|
|
258
|
-
"completion_review_result_sha256": receipt_hashes[-1],
|
|
259
|
-
"next_action": "complete",
|
|
260
|
-
}
|
|
261
|
-
if completion_mutator is not None:
|
|
262
|
-
completion_mutator(complete)
|
|
263
|
-
complete_name = f"{name}-complete.json"
|
|
264
|
-
complete_hash = write_json(complete_name, complete)
|
|
265
|
-
completion_ref = {"file": complete_name, "sha256": complete_hash}
|
|
266
|
-
|
|
267
|
-
if base_shas is None:
|
|
268
|
-
base_shas = [A] * rounds
|
|
269
|
-
attestations = []
|
|
270
|
-
for sequence, base_sha in enumerate(base_shas, start=1):
|
|
271
|
-
evidence_name = f"{name}-base-{sequence}.txt"
|
|
272
|
-
evidence_hash = write_base_evidence(evidence_name, base_sha)
|
|
273
|
-
attestations.append(
|
|
274
|
-
{
|
|
275
|
-
"sequence": sequence,
|
|
276
|
-
"remote": "origin",
|
|
277
|
-
"ref": "refs/heads/dev",
|
|
278
|
-
"sha": base_sha,
|
|
279
|
-
"confirmed_at": f"2026-08-29T12:{sequence:02d}:00Z",
|
|
280
|
-
"controller_receipt_sha256": (
|
|
281
|
-
receipt_hashes[sequence - 1] if sequence <= rounds else None
|
|
282
|
-
),
|
|
283
|
-
"evidence_file": evidence_name,
|
|
284
|
-
"evidence_sha256": evidence_hash,
|
|
285
|
-
}
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
occurrences = []
|
|
289
|
-
for receipt, receipt_hash in zip(receipts, receipt_hashes):
|
|
290
|
-
for finding_hash in dict.fromkeys(canonical_hash(item) for item in receipt["findings"]):
|
|
291
|
-
occurrences.append(
|
|
292
|
-
{
|
|
293
|
-
"receipt_sha256": receipt_hash,
|
|
294
|
-
"finding_sha256": finding_hash,
|
|
295
|
-
"disposition": "fixed",
|
|
296
|
-
}
|
|
297
|
-
)
|
|
298
|
-
if open_last and occurrences:
|
|
299
|
-
occurrences[-1]["disposition"] = "open"
|
|
300
|
-
for occurrence_index, occurrence in enumerate(occurrences, start=1):
|
|
301
|
-
if occurrence["disposition"] in CLOSED_DISPOSITIONS:
|
|
302
|
-
bind_disposition_evidence(
|
|
303
|
-
f"{name}-disposition-{occurrence_index}.json",
|
|
304
|
-
occurrence,
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
classes = []
|
|
308
|
-
if occurrences:
|
|
309
|
-
sweep = None
|
|
310
|
-
if len(occurrences) >= 3:
|
|
311
|
-
searched_set = [
|
|
312
|
-
"skills/code-review",
|
|
313
|
-
"skills/skill-extraction-workflow",
|
|
314
|
-
]
|
|
315
|
-
unmatched_items = [f"unmatched-{index}" for index in range(unmatched)]
|
|
316
|
-
manifest = {
|
|
317
|
-
"schema_version": 1,
|
|
318
|
-
"candidate_sha256": CANDIDATE,
|
|
319
|
-
"searched_set": searched_set,
|
|
320
|
-
"unmatched_instances": unmatched_items,
|
|
321
|
-
}
|
|
322
|
-
manifest_name = f"{name}-sweep.json"
|
|
323
|
-
manifest_hash = write_json(manifest_name, manifest)
|
|
324
|
-
sweep = {
|
|
325
|
-
"candidate_sha256": CANDIDATE,
|
|
326
|
-
"manifest_file": manifest_name,
|
|
327
|
-
"manifest_sha256": manifest_hash,
|
|
328
|
-
"searched_set": searched_set,
|
|
329
|
-
"unmatched_instances": unmatched,
|
|
330
|
-
}
|
|
331
|
-
classes.append(
|
|
332
|
-
{
|
|
333
|
-
"key": "receipt-binding",
|
|
334
|
-
"root_cause_predicate": "A closeout field is accepted without controller evidence.",
|
|
335
|
-
"affected_surface": "extraction closeout ledger",
|
|
336
|
-
"occurrences": occurrences,
|
|
337
|
-
"authoritative_sweep": sweep,
|
|
338
|
-
}
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
if closeout is None:
|
|
342
|
-
closeout = (
|
|
343
|
-
"ready_for_human_decision"
|
|
344
|
-
if completion
|
|
345
|
-
else "continuation_authorization_required"
|
|
346
|
-
)
|
|
347
|
-
controller_state = (
|
|
348
|
-
"self_reviewed" if completion else receipts[-1]["review_state"]
|
|
349
|
-
)
|
|
350
|
-
ledger = {
|
|
351
|
-
"schema_version": 3,
|
|
352
|
-
"candidate_sha256": CANDIDATE,
|
|
353
|
-
"controller_receipts": receipt_refs,
|
|
354
|
-
"completion_receipt": completion_ref,
|
|
355
|
-
"base_attestations": attestations,
|
|
356
|
-
"autonomous_round": rounds,
|
|
357
|
-
"controller_review_state": controller_state,
|
|
358
|
-
"finding_classes": classes,
|
|
359
|
-
"unreviewed_delta": [],
|
|
360
|
-
"closeout_state": closeout,
|
|
361
|
-
}
|
|
362
|
-
return {
|
|
363
|
-
"ledger": ledger,
|
|
364
|
-
"receipts": receipts,
|
|
365
|
-
"receipt_hashes": receipt_hashes,
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
def invoke_encoded(name, encoded):
|
|
370
|
-
path = root / f"{name}-ledger.json"
|
|
371
|
-
path.write_bytes(encoded)
|
|
372
|
-
try:
|
|
373
|
-
return subprocess.run(
|
|
374
|
-
[sys.executable, str(validator), str(path)],
|
|
375
|
-
stdout=subprocess.PIPE,
|
|
376
|
-
stderr=subprocess.STDOUT,
|
|
377
|
-
text=True,
|
|
378
|
-
check=False,
|
|
379
|
-
timeout=5,
|
|
380
|
-
)
|
|
381
|
-
except subprocess.TimeoutExpired as exc:
|
|
382
|
-
raise AssertionError((name, "validator blocked", exc)) from exc
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
def invoke(name, payload):
|
|
386
|
-
encoded = (json.dumps(payload, indent=2) + "\n").encode()
|
|
387
|
-
return invoke_encoded(name, encoded)
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
def run(name, payload, expected_rc, token):
|
|
391
|
-
result = invoke(name, payload)
|
|
392
|
-
assert result.returncode == expected_rc, (name, result.returncode, result.stdout)
|
|
393
|
-
assert token in result.stdout, (name, token, result.stdout)
|
|
394
|
-
assert "Traceback" not in result.stdout, (name, result.stdout)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
ready = make_fixture("ready")
|
|
398
|
-
run("ready", ready["ledger"], 0, "closeout_state=ready_for_human_decision")
|
|
399
|
-
|
|
400
|
-
schema_v3 = make_fixture("schema-v3")
|
|
401
|
-
schema_v3["ledger"]["schema_version"] = 3
|
|
402
|
-
legacy_v2 = make_fixture("legacy-v2")
|
|
403
|
-
legacy_v2["ledger"]["schema_version"] = 2
|
|
404
|
-
schema_results = [
|
|
405
|
-
("schema-v3", invoke("schema-v3", schema_v3["ledger"])),
|
|
406
|
-
("legacy-v2", invoke("legacy-v2", legacy_v2["ledger"])),
|
|
407
|
-
]
|
|
408
|
-
assert [
|
|
409
|
-
(result.returncode, expected_token in result.stdout, "Traceback" in result.stdout)
|
|
410
|
-
for (name, result), expected_token in zip(
|
|
411
|
-
schema_results,
|
|
412
|
-
("closeout_state=ready_for_human_decision", "schema_version must be 3"),
|
|
413
|
-
strict=True,
|
|
414
|
-
)
|
|
415
|
-
] == [(0, True, False), (1, True, False)], [
|
|
416
|
-
(name, result.returncode, result.stdout) for name, result in schema_results
|
|
417
|
-
]
|
|
418
|
-
|
|
419
|
-
bad_digest = make_fixture("bad-digest")
|
|
420
|
-
bad_digest["ledger"]["controller_receipts"][0]["sha256"] = "f" * 64
|
|
421
|
-
run("bad-digest", bad_digest["ledger"], 1, "digest does not match")
|
|
422
|
-
|
|
423
|
-
# JSON floats equal to the expected integers must not satisfy integer guards.
|
|
424
|
-
float_schema = make_fixture("float-schema")
|
|
425
|
-
float_schema["ledger"]["schema_version"] = 3.0
|
|
426
|
-
run("float-schema", float_schema["ledger"], 1, "schema_version must be 3")
|
|
427
|
-
|
|
428
|
-
float_budget = make_fixture(
|
|
429
|
-
"float-budget",
|
|
430
|
-
receipt_mutators={2: lambda row: row.update(challenge_budget=1.0)},
|
|
431
|
-
)
|
|
432
|
-
run("float-budget", float_budget["ledger"], 1, "challenge_budget must be 1")
|
|
433
|
-
|
|
434
|
-
nan_schema = make_fixture("nan-schema")
|
|
435
|
-
nan_schema["ledger"]["schema_version"] = float("nan")
|
|
436
|
-
run("nan-schema", nan_schema["ledger"], 1, "non-standard JSON constant")
|
|
437
|
-
|
|
438
|
-
control_chain = make_fixture(
|
|
439
|
-
"control-chain",
|
|
440
|
-
receipt_mutators={
|
|
441
|
-
2: lambda row: row.update(review_chain_id="chain\x1b[31mred")
|
|
442
|
-
},
|
|
443
|
-
)
|
|
444
|
-
run("control-chain", control_chain["ledger"], 1, "must not contain control characters")
|
|
445
|
-
|
|
446
|
-
# C1 controls and Unicode line/paragraph separators forge diagnostic line
|
|
447
|
-
# breaks just like C0 escapes; each must be rejected, not echoed.
|
|
448
|
-
for label, hostile in (
|
|
449
|
-
("c1-csi", "chain\x9bred"),
|
|
450
|
-
("c1-nel", "chain\x85red"),
|
|
451
|
-
("line-sep", "chain\u2028red"),
|
|
452
|
-
("para-sep", "chain\u2029red"),
|
|
453
|
-
):
|
|
454
|
-
hostile_chain = make_fixture(
|
|
455
|
-
f"hostile-{label}",
|
|
456
|
-
receipt_mutators={2: lambda row, value=hostile: row.update(review_chain_id=value)},
|
|
457
|
-
)
|
|
458
|
-
run(
|
|
459
|
-
f"hostile-{label}",
|
|
460
|
-
hostile_chain["ledger"],
|
|
461
|
-
1,
|
|
462
|
-
"must not contain control characters",
|
|
463
|
-
)
|
|
464
|
-
|
|
465
|
-
# A float completion schema_version must not satisfy the completion guard.
|
|
466
|
-
float_completion = make_fixture(
|
|
467
|
-
"float-completion",
|
|
468
|
-
completion_mutator=lambda row: row.update(schema_version=3.0),
|
|
469
|
-
)
|
|
470
|
-
run(
|
|
471
|
-
"float-completion",
|
|
472
|
-
float_completion["ledger"],
|
|
473
|
-
1,
|
|
474
|
-
"completion receipt must be a passed self_reviewed complete result",
|
|
475
|
-
)
|
|
476
|
-
|
|
477
|
-
wrong_chain = make_fixture(
|
|
478
|
-
"wrong-chain",
|
|
479
|
-
receipt_mutators={2: lambda row: row.update(review_chain_id="other-chain")},
|
|
480
|
-
)
|
|
481
|
-
run("wrong-chain", wrong_chain["ledger"], 1, "review_chain_id")
|
|
482
|
-
|
|
483
|
-
wrong_mode = make_fixture(
|
|
484
|
-
"wrong-mode", receipt_mutators={2: lambda row: row.update(mode="review")}
|
|
485
|
-
)
|
|
486
|
-
run("wrong-mode", wrong_mode["ledger"], 1, "mode challenge")
|
|
487
|
-
|
|
488
|
-
wrong_prior = make_fixture(
|
|
489
|
-
"wrong-prior",
|
|
490
|
-
receipt_mutators={
|
|
491
|
-
2: lambda row: row.update(prior_review_result_sha256=["f" * 64])
|
|
492
|
-
},
|
|
493
|
-
)
|
|
494
|
-
run("wrong-prior", wrong_prior["ledger"], 1, "prior_review_result_sha256")
|
|
495
|
-
|
|
496
|
-
packet_mismatch = make_fixture(
|
|
497
|
-
"packet-mismatch",
|
|
498
|
-
receipt_mutators={2: lambda row: row.update(packet_sha256=OTHER_CANDIDATE)},
|
|
499
|
-
)
|
|
500
|
-
run("packet-mismatch", packet_mismatch["ledger"], 1, "packet_sha256 must equal candidate_sha256")
|
|
501
|
-
|
|
502
|
-
def drift_scope(row):
|
|
503
|
-
row["review_scope"]["stage"] = "build"
|
|
504
|
-
row["review_scope_sha256"] = canonical_hash(row["review_scope"])
|
|
505
|
-
row["stage"] = "build"
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
scope_mismatch = make_fixture("scope-mismatch", receipt_mutators={2: drift_scope})
|
|
509
|
-
run("scope-mismatch", scope_mismatch["ledger"], 1, "review scope changed")
|
|
510
|
-
|
|
511
|
-
budget_four = make_fixture("budget-four", budget=4)
|
|
512
|
-
run("budget-four", budget_four["ledger"], 1, "challenge_budget must be 1")
|
|
513
|
-
|
|
514
|
-
review_only = make_fixture("review-only", receipt_findings=[[]])
|
|
515
|
-
run("review-only", review_only["ledger"], 1, "ready requires at least one tracked challenge")
|
|
516
|
-
|
|
517
|
-
# A caller must not out-run the wrapper budget by supplying extra receipts: a
|
|
518
|
-
# third receipt under budget 1 claims a negative remaining count and would
|
|
519
|
-
# otherwise reach completion validation as a ready-state budget bypass.
|
|
520
|
-
over_budget = make_fixture("over-budget", receipt_findings=[[], [], []])
|
|
521
|
-
run("over-budget", over_budget["ledger"], 1, "exceeds the wrapper budget")
|
|
522
|
-
|
|
523
|
-
# Chain succession. A fix that edits the reviewed owner package ends its chain, so
|
|
524
|
-
# the landing candidate can only be challenged in a succeeding chain. The lane then
|
|
525
|
-
# spans two chains and three rounds, and the succession round is the only one that
|
|
526
|
-
# binds what actually lands.
|
|
527
|
-
succession_ready = make_fixture(
|
|
528
|
-
"succession-ready", receipt_findings=[[finding(1)], [], []], succession=True
|
|
529
|
-
)
|
|
530
|
-
run("succession-ready", succession_ready["ledger"], 0, "closeout_state=ready_for_human_decision")
|
|
531
|
-
|
|
532
|
-
# The failure this whole mechanism exists to make visible: the fix batch moved the
|
|
533
|
-
# candidate and no round ever inspected what lands.
|
|
534
|
-
succession_absent = make_fixture(
|
|
535
|
-
"succession-absent",
|
|
536
|
-
receipt_findings=[[finding(1)], []],
|
|
537
|
-
receipt_mutators={
|
|
538
|
-
1: lambda row: row.update(
|
|
539
|
-
candidate_sha256=OTHER_CANDIDATE, packet_sha256=OTHER_CANDIDATE
|
|
540
|
-
),
|
|
541
|
-
2: lambda row: row.update(
|
|
542
|
-
candidate_sha256=OTHER_CANDIDATE, packet_sha256=OTHER_CANDIDATE
|
|
543
|
-
),
|
|
544
|
-
},
|
|
545
|
-
)
|
|
546
|
-
run("succession-absent", succession_absent["ledger"], 1, "does not bind the ledger candidate")
|
|
547
|
-
|
|
548
|
-
# A succession whose predecessor saw the same candidate reviewed nothing new.
|
|
549
|
-
succession_unmoved = make_fixture(
|
|
550
|
-
"succession-unmoved",
|
|
551
|
-
receipt_findings=[[finding(1)], [], []],
|
|
552
|
-
succession=True,
|
|
553
|
-
receipt_mutators={
|
|
554
|
-
1: lambda row: row.update(candidate_sha256=CANDIDATE, packet_sha256=CANDIDATE),
|
|
555
|
-
2: lambda row: row.update(candidate_sha256=CANDIDATE, packet_sha256=CANDIDATE),
|
|
556
|
-
3: lambda row: row.update(predecessor_candidate_sha256=CANDIDATE),
|
|
557
|
-
},
|
|
558
|
-
)
|
|
559
|
-
run(
|
|
560
|
-
"succession-unmoved",
|
|
561
|
-
succession_unmoved["ledger"],
|
|
562
|
-
1,
|
|
563
|
-
"must bind a candidate the wrapper chain never saw",
|
|
564
|
-
)
|
|
565
|
-
|
|
566
|
-
succession_foreign_terminal = make_fixture(
|
|
567
|
-
"succession-foreign-terminal",
|
|
568
|
-
receipt_findings=[[finding(1)], [], []],
|
|
569
|
-
succession=True,
|
|
570
|
-
receipt_mutators={3: lambda row: row.update(predecessor_result_sha256="f" * 64)},
|
|
571
|
-
)
|
|
572
|
-
run(
|
|
573
|
-
"succession-foreign-terminal",
|
|
574
|
-
succession_foreign_terminal["ledger"],
|
|
575
|
-
1,
|
|
576
|
-
"does not bind the succeeded chain's terminal receipt",
|
|
577
|
-
)
|
|
578
|
-
|
|
579
|
-
succession_self = make_fixture(
|
|
580
|
-
"succession-self",
|
|
581
|
-
receipt_findings=[[finding(1)], [], []],
|
|
582
|
-
succession=True,
|
|
583
|
-
receipt_mutators={3: lambda row: row.update(review_chain_id="extraction-chain")},
|
|
584
|
-
)
|
|
585
|
-
run("succession-self", succession_self["ledger"], 1, "succeeds its own chain")
|
|
586
|
-
|
|
587
|
-
succession_misplaced = make_fixture(
|
|
588
|
-
"succession-misplaced",
|
|
589
|
-
receipt_findings=[[finding(1)], [], []],
|
|
590
|
-
succession=True,
|
|
591
|
-
receipt_mutators={
|
|
592
|
-
2: lambda row: row.update(predecessor_chain_id="extraction-chain"),
|
|
593
|
-
},
|
|
594
|
-
)
|
|
595
|
-
run(
|
|
596
|
-
"succession-misplaced",
|
|
597
|
-
succession_misplaced["ledger"],
|
|
598
|
-
1,
|
|
599
|
-
"must be the lane's final round",
|
|
600
|
-
)
|
|
601
|
-
|
|
602
|
-
succession_over_lane = make_fixture(
|
|
603
|
-
"succession-over-lane",
|
|
604
|
-
receipt_findings=[[finding(1)], [], [], []],
|
|
605
|
-
succession=True,
|
|
606
|
-
)
|
|
607
|
-
run(
|
|
608
|
-
"succession-over-lane",
|
|
609
|
-
succession_over_lane["ledger"],
|
|
610
|
-
1,
|
|
611
|
-
"controller_receipts must contain one to 3 ordered Agent rounds",
|
|
612
|
-
)
|
|
613
|
-
|
|
614
|
-
missing_complete = make_fixture("missing-complete")
|
|
615
|
-
missing_complete["ledger"]["completion_receipt"] = None
|
|
616
|
-
run("missing-complete", missing_complete["ledger"], 1, "requires a completion receipt")
|
|
617
|
-
|
|
618
|
-
bad_complete_state = make_fixture(
|
|
619
|
-
"bad-complete-state",
|
|
620
|
-
completion_mutator=lambda row: row.update(review_state="reviewed"),
|
|
621
|
-
)
|
|
622
|
-
run("bad-complete-state", bad_complete_state["ledger"], 1, "passed self_reviewed")
|
|
623
|
-
|
|
624
|
-
bad_complete_hash = make_fixture(
|
|
625
|
-
"bad-complete-hash",
|
|
626
|
-
completion_mutator=lambda row: row.update(
|
|
627
|
-
completion_review_result_sha256="f" * 64
|
|
628
|
-
),
|
|
629
|
-
)
|
|
630
|
-
run("bad-complete-hash", bad_complete_hash["ledger"], 1, "completion_review_result_sha256")
|
|
631
|
-
|
|
632
|
-
bad_complete_candidate = make_fixture(
|
|
633
|
-
"bad-complete-candidate",
|
|
634
|
-
completion_mutator=lambda row: row.update(
|
|
635
|
-
candidate_sha256=OTHER_CANDIDATE, packet_sha256=OTHER_CANDIDATE
|
|
636
|
-
),
|
|
637
|
-
)
|
|
638
|
-
run("bad-complete-candidate", bad_complete_candidate["ledger"], 1, "exact final candidate")
|
|
639
|
-
|
|
640
|
-
bad_complete_remaining = make_fixture(
|
|
641
|
-
"bad-complete-remaining",
|
|
642
|
-
completion_mutator=lambda row: row.update(autonomous_reviews_remaining=2),
|
|
643
|
-
)
|
|
644
|
-
run(
|
|
645
|
-
"bad-complete-remaining",
|
|
646
|
-
bad_complete_remaining["ledger"],
|
|
647
|
-
1,
|
|
648
|
-
"autonomous_reviews_remaining",
|
|
649
|
-
)
|
|
650
|
-
|
|
651
|
-
continuation = make_fixture(
|
|
652
|
-
"continuation",
|
|
653
|
-
receipt_findings=[[finding(1)], [finding(2)]],
|
|
654
|
-
completion=False,
|
|
655
|
-
open_last=True,
|
|
656
|
-
)
|
|
657
|
-
run(
|
|
658
|
-
"continuation",
|
|
659
|
-
continuation["ledger"],
|
|
660
|
-
0,
|
|
661
|
-
"closeout_state=continuation_authorization_required",
|
|
662
|
-
)
|
|
663
|
-
|
|
664
|
-
continuation_unconsumed_first_drift = make_fixture(
|
|
665
|
-
"continuation-unconsumed-first-drift",
|
|
666
|
-
receipt_findings=[[finding(1)], [finding(2)]],
|
|
667
|
-
completion=False,
|
|
668
|
-
open_last=True,
|
|
669
|
-
base_shas=[A, A, B],
|
|
670
|
-
)
|
|
671
|
-
run(
|
|
672
|
-
"continuation-unconsumed-first-drift",
|
|
673
|
-
continuation_unconsumed_first_drift["ledger"],
|
|
674
|
-
1,
|
|
675
|
-
"final controller receipt does not consume the latest attested base",
|
|
676
|
-
)
|
|
677
|
-
|
|
678
|
-
continuation_candidate = make_fixture(
|
|
679
|
-
"continuation-candidate",
|
|
680
|
-
receipt_findings=[[finding(1)], [finding(2)]],
|
|
681
|
-
completion=False,
|
|
682
|
-
open_last=True,
|
|
683
|
-
)
|
|
684
|
-
continuation_candidate["ledger"]["candidate_sha256"] = OTHER_CANDIDATE
|
|
685
|
-
run(
|
|
686
|
-
"continuation-candidate",
|
|
687
|
-
continuation_candidate["ledger"],
|
|
688
|
-
1,
|
|
689
|
-
"controller receipt 1 does not bind the ledger candidate",
|
|
690
|
-
)
|
|
691
|
-
|
|
692
|
-
# A chain whose FIRST round reviewed a different candidate must not close out
|
|
693
|
-
# a ledger for the final candidate, even when the final round binds it.
|
|
694
|
-
drifted_round = make_fixture(
|
|
695
|
-
"drifted-round-candidate",
|
|
696
|
-
receipt_mutators={
|
|
697
|
-
1: lambda row: row.update(
|
|
698
|
-
candidate_sha256=OTHER_CANDIDATE, packet_sha256=OTHER_CANDIDATE
|
|
699
|
-
)
|
|
700
|
-
},
|
|
701
|
-
)
|
|
702
|
-
run(
|
|
703
|
-
"drifted-round-candidate",
|
|
704
|
-
drifted_round["ledger"],
|
|
705
|
-
1,
|
|
706
|
-
"controller receipt 1 does not bind the ledger candidate",
|
|
707
|
-
)
|
|
708
|
-
|
|
709
|
-
unknown_state = make_fixture(
|
|
710
|
-
"unknown-state",
|
|
711
|
-
receipt_findings=[[finding(1)], [finding(2)]],
|
|
712
|
-
receipt_mutators={2: lambda row: row.update(review_state="potato")},
|
|
713
|
-
completion=False,
|
|
714
|
-
open_last=True,
|
|
715
|
-
)
|
|
716
|
-
unknown_state["ledger"]["controller_review_state"] = "potato"
|
|
717
|
-
run("unknown-state", unknown_state["ledger"], 1, "unknown controller review_state")
|
|
718
|
-
|
|
719
|
-
passed_continuation = make_fixture(
|
|
720
|
-
"passed-continuation",
|
|
721
|
-
receipt_findings=[[finding(1)], []],
|
|
722
|
-
completion=False,
|
|
723
|
-
)
|
|
724
|
-
run("passed-continuation", passed_continuation["ledger"], 1, "findings in post_review_budget")
|
|
725
|
-
|
|
726
|
-
bad_finding_hash = make_fixture("bad-finding-hash")
|
|
727
|
-
bad_finding_hash["ledger"]["finding_classes"][0]["occurrences"][0][
|
|
728
|
-
"finding_sha256"
|
|
729
|
-
] = "f" * 64
|
|
730
|
-
run("bad-finding-hash", bad_finding_hash["ledger"], 1, "does not identify a finding")
|
|
731
|
-
|
|
732
|
-
omitted_finding = make_fixture("omitted-finding")
|
|
733
|
-
omitted_finding["ledger"]["finding_classes"] = []
|
|
734
|
-
run("omitted-finding", omitted_finding["ledger"], 1, "omits controller findings")
|
|
735
|
-
|
|
736
|
-
reordered_findings = make_fixture(
|
|
737
|
-
"reordered-findings", receipt_findings=[[finding(1), finding(2)], []]
|
|
738
|
-
)
|
|
739
|
-
reordered_findings["ledger"]["finding_classes"][0]["occurrences"].reverse()
|
|
740
|
-
run("reordered-findings", reordered_findings["ledger"], 1, "not in controller receipt order")
|
|
741
|
-
|
|
742
|
-
fixed_without_evidence = make_fixture("fixed-without-evidence")
|
|
743
|
-
clear_disposition_evidence(
|
|
744
|
-
fixed_without_evidence["ledger"]["finding_classes"][0]["occurrences"][-1]
|
|
745
|
-
)
|
|
746
|
-
run(
|
|
747
|
-
"fixed-without-evidence",
|
|
748
|
-
fixed_without_evidence["ledger"],
|
|
749
|
-
1,
|
|
750
|
-
"disposition_evidence_file",
|
|
751
|
-
)
|
|
752
|
-
|
|
753
|
-
for disposition in ("accepted_tradeoff", "pre_existing_out_of_scope"):
|
|
754
|
-
case_name = f"{disposition.replace('_', '-')}-without-evidence"
|
|
755
|
-
without_evidence = make_fixture(case_name)
|
|
756
|
-
without_evidence_occurrence = without_evidence["ledger"]["finding_classes"][0][
|
|
757
|
-
"occurrences"
|
|
758
|
-
][-1]
|
|
759
|
-
without_evidence_occurrence["disposition"] = disposition
|
|
760
|
-
clear_disposition_evidence(without_evidence_occurrence)
|
|
761
|
-
run(case_name, without_evidence["ledger"], 1, "disposition_evidence_file")
|
|
762
|
-
|
|
763
|
-
bound_case_name = f"{disposition.replace('_', '-')}-bound"
|
|
764
|
-
bound = make_fixture(bound_case_name)
|
|
765
|
-
bound_occurrence = bound["ledger"]["finding_classes"][0]["occurrences"][-1]
|
|
766
|
-
bound_occurrence["disposition"] = disposition
|
|
767
|
-
bind_disposition_evidence(
|
|
768
|
-
f"{bound_case_name}-disposition.json",
|
|
769
|
-
bound_occurrence,
|
|
770
|
-
)
|
|
771
|
-
run(bound_case_name, bound["ledger"], 0, "ready_for_human_decision")
|
|
772
|
-
|
|
773
|
-
stale_disposition_evidence = make_fixture("stale-disposition-evidence")
|
|
774
|
-
stale_disposition_evidence_occurrence = stale_disposition_evidence["ledger"][
|
|
775
|
-
"finding_classes"
|
|
776
|
-
][0]["occurrences"][-1]
|
|
777
|
-
mutate_disposition_evidence(
|
|
778
|
-
stale_disposition_evidence_occurrence,
|
|
779
|
-
lambda evidence: evidence.update(candidate_sha256=OTHER_CANDIDATE),
|
|
780
|
-
)
|
|
781
|
-
run(
|
|
782
|
-
"stale-disposition-evidence",
|
|
783
|
-
stale_disposition_evidence["ledger"],
|
|
784
|
-
1,
|
|
785
|
-
"stale for the current candidate",
|
|
786
|
-
)
|
|
787
|
-
|
|
788
|
-
wrong_disposition_evidence = make_fixture("wrong-disposition-evidence")
|
|
789
|
-
wrong_disposition_evidence_occurrence = wrong_disposition_evidence["ledger"][
|
|
790
|
-
"finding_classes"
|
|
791
|
-
][0]["occurrences"][-1]
|
|
792
|
-
mutate_disposition_evidence(
|
|
793
|
-
wrong_disposition_evidence_occurrence,
|
|
794
|
-
lambda evidence: evidence.update(disposition="accepted_tradeoff"),
|
|
795
|
-
)
|
|
796
|
-
run(
|
|
797
|
-
"wrong-disposition-evidence",
|
|
798
|
-
wrong_disposition_evidence["ledger"],
|
|
799
|
-
1,
|
|
800
|
-
"does not bind its disposition",
|
|
801
|
-
)
|
|
802
|
-
|
|
803
|
-
duplicate_key_cases = []
|
|
804
|
-
for case_name, field, first_value in (
|
|
805
|
-
("duplicate-candidate-evidence", "candidate_sha256", OTHER_CANDIDATE),
|
|
806
|
-
("duplicate-disposition-evidence", "disposition", "accepted_tradeoff"),
|
|
807
|
-
):
|
|
808
|
-
duplicate_case = make_fixture(case_name)
|
|
809
|
-
duplicate_occurrence = duplicate_case["ledger"]["finding_classes"][0][
|
|
810
|
-
"occurrences"
|
|
811
|
-
][-1]
|
|
812
|
-
duplicate_disposition_evidence_key(duplicate_occurrence, field, first_value)
|
|
813
|
-
duplicate_result = invoke(case_name, duplicate_case["ledger"])
|
|
814
|
-
duplicate_key_cases.append(
|
|
815
|
-
(
|
|
816
|
-
case_name,
|
|
817
|
-
duplicate_result.returncode,
|
|
818
|
-
f"duplicate object key: {field}" in duplicate_result.stdout,
|
|
819
|
-
"Traceback" in duplicate_result.stdout,
|
|
820
|
-
duplicate_result.stdout,
|
|
821
|
-
)
|
|
822
|
-
)
|
|
823
|
-
assert [item[1:4] for item in duplicate_key_cases] == [
|
|
824
|
-
(1, True, False),
|
|
825
|
-
(1, True, False),
|
|
826
|
-
], duplicate_key_cases
|
|
827
|
-
|
|
828
|
-
wrong_receipt_evidence = make_fixture("wrong-receipt-evidence")
|
|
829
|
-
wrong_receipt_evidence_occurrence = wrong_receipt_evidence["ledger"][
|
|
830
|
-
"finding_classes"
|
|
831
|
-
][0]["occurrences"][-1]
|
|
832
|
-
mutate_disposition_evidence(
|
|
833
|
-
wrong_receipt_evidence_occurrence,
|
|
834
|
-
lambda evidence: evidence.update(receipt_sha256="f" * 64),
|
|
835
|
-
)
|
|
836
|
-
run(
|
|
837
|
-
"wrong-receipt-evidence",
|
|
838
|
-
wrong_receipt_evidence["ledger"],
|
|
839
|
-
1,
|
|
840
|
-
"does not bind its controller receipt",
|
|
841
|
-
)
|
|
842
|
-
|
|
843
|
-
wrong_finding_evidence = make_fixture("wrong-finding-evidence")
|
|
844
|
-
wrong_finding_evidence_occurrence = wrong_finding_evidence["ledger"][
|
|
845
|
-
"finding_classes"
|
|
846
|
-
][0]["occurrences"][-1]
|
|
847
|
-
mutate_disposition_evidence(
|
|
848
|
-
wrong_finding_evidence_occurrence,
|
|
849
|
-
lambda evidence: evidence.update(finding_sha256="f" * 64),
|
|
850
|
-
)
|
|
851
|
-
run(
|
|
852
|
-
"wrong-finding-evidence",
|
|
853
|
-
wrong_finding_evidence["ledger"],
|
|
854
|
-
1,
|
|
855
|
-
"does not bind its controller finding",
|
|
856
|
-
)
|
|
857
|
-
|
|
858
|
-
historical_open = make_fixture(
|
|
859
|
-
"historical-open",
|
|
860
|
-
receipt_findings=[[finding(1), finding(2)], []],
|
|
861
|
-
)
|
|
862
|
-
historical_open["ledger"]["finding_classes"][0]["occurrences"][0][
|
|
863
|
-
"disposition"
|
|
864
|
-
] = "open"
|
|
865
|
-
clear_disposition_evidence(
|
|
866
|
-
historical_open["ledger"]["finding_classes"][0]["occurrences"][0]
|
|
867
|
-
)
|
|
868
|
-
run("historical-open", historical_open["ledger"], 1, "unresolved finding occurrence")
|
|
869
|
-
|
|
870
|
-
historical_open_linked = make_fixture(
|
|
871
|
-
"historical-open-linked",
|
|
872
|
-
receipt_findings=[[finding(1), finding(2)], []],
|
|
873
|
-
)
|
|
874
|
-
historical_open_linked_occurrences = historical_open_linked["ledger"][
|
|
875
|
-
"finding_classes"
|
|
876
|
-
][0]["occurrences"]
|
|
877
|
-
historical_open_linked_occurrences[0]["disposition"] = "open"
|
|
878
|
-
clear_disposition_evidence(historical_open_linked_occurrences[0])
|
|
879
|
-
bind_disposition_evidence(
|
|
880
|
-
"historical-open-linked-disposition.json",
|
|
881
|
-
historical_open_linked_occurrences[1],
|
|
882
|
-
resolves=[
|
|
883
|
-
occurrence_ref(historical_open_linked_occurrences[0]),
|
|
884
|
-
occurrence_ref(historical_open_linked_occurrences[1]),
|
|
885
|
-
],
|
|
886
|
-
)
|
|
887
|
-
run(
|
|
888
|
-
"historical-open-linked",
|
|
889
|
-
historical_open_linked["ledger"],
|
|
890
|
-
0,
|
|
891
|
-
"ready_for_human_decision",
|
|
892
|
-
)
|
|
893
|
-
|
|
894
|
-
source_refuted_without_evidence = make_fixture("source-refuted-without-evidence")
|
|
895
|
-
source_refuted_without_evidence_occurrence = source_refuted_without_evidence["ledger"][
|
|
896
|
-
"finding_classes"
|
|
897
|
-
][0]["occurrences"][-1]
|
|
898
|
-
source_refuted_without_evidence_occurrence["disposition"] = "source_refuted"
|
|
899
|
-
clear_disposition_evidence(source_refuted_without_evidence_occurrence)
|
|
900
|
-
run(
|
|
901
|
-
"source-refuted-without-evidence",
|
|
902
|
-
source_refuted_without_evidence["ledger"],
|
|
903
|
-
1,
|
|
904
|
-
"disposition_evidence_file",
|
|
905
|
-
)
|
|
906
|
-
|
|
907
|
-
source_refuted = make_fixture("source-refuted")
|
|
908
|
-
source_refuted_occurrence = source_refuted["ledger"]["finding_classes"][0][
|
|
909
|
-
"occurrences"
|
|
910
|
-
][-1]
|
|
911
|
-
source_refuted_occurrence["disposition"] = "source_refuted"
|
|
912
|
-
bind_disposition_evidence(
|
|
913
|
-
"source-refuted-evidence.json",
|
|
914
|
-
source_refuted_occurrence,
|
|
915
|
-
evidence=["synthetic first-hand source evidence"],
|
|
916
|
-
)
|
|
917
|
-
run("source-refuted", source_refuted["ledger"], 0, "ready_for_human_decision")
|
|
918
|
-
|
|
919
|
-
source_refuted_bad_hash = copy.deepcopy(source_refuted["ledger"])
|
|
920
|
-
source_refuted_bad_hash["finding_classes"][0]["occurrences"][-1][
|
|
921
|
-
"disposition_evidence_sha256"
|
|
922
|
-
] = "f" * 64
|
|
923
|
-
run(
|
|
924
|
-
"source-refuted-bad-hash",
|
|
925
|
-
source_refuted_bad_hash,
|
|
926
|
-
1,
|
|
927
|
-
"digest does not match",
|
|
928
|
-
)
|
|
929
|
-
|
|
930
|
-
needs_human = make_fixture("needs-human")
|
|
931
|
-
needs_human["ledger"]["finding_classes"][0]["occurrences"][-1][
|
|
932
|
-
"disposition"
|
|
933
|
-
] = "needs_human_decision"
|
|
934
|
-
clear_disposition_evidence(
|
|
935
|
-
needs_human["ledger"]["finding_classes"][0]["occurrences"][-1]
|
|
936
|
-
)
|
|
937
|
-
run("needs-human", needs_human["ledger"], 1, "unresolved finding occurrence")
|
|
938
|
-
|
|
939
|
-
third_occurrence = make_fixture(
|
|
940
|
-
"third-occurrence",
|
|
941
|
-
receipt_findings=[[finding(1), finding(2)], [finding(3)]],
|
|
942
|
-
completion=False,
|
|
943
|
-
unmatched=1,
|
|
944
|
-
open_last=True,
|
|
945
|
-
)
|
|
946
|
-
run("third-occurrence", third_occurrence["ledger"], 0, "continuation_authorization_required")
|
|
947
|
-
|
|
948
|
-
split_predicate = copy.deepcopy(third_occurrence["ledger"])
|
|
949
|
-
original_class = split_predicate["finding_classes"][0]
|
|
950
|
-
predicate_variants = [
|
|
951
|
-
"A closeout field is accepted without controller evidence.",
|
|
952
|
-
"a closeout field is accepted without controller evidence.",
|
|
953
|
-
"A closeout field is accepted without controller evidence.",
|
|
954
|
-
]
|
|
955
|
-
split_predicate["finding_classes"] = [
|
|
956
|
-
{
|
|
957
|
-
"key": f"receipt-binding-{index}",
|
|
958
|
-
"root_cause_predicate": predicate_variants[index - 1],
|
|
959
|
-
"affected_surface": original_class["affected_surface"],
|
|
960
|
-
"occurrences": [copy.deepcopy(occurrence)],
|
|
961
|
-
"authoritative_sweep": None,
|
|
962
|
-
}
|
|
963
|
-
for index, occurrence in enumerate(original_class["occurrences"], start=1)
|
|
964
|
-
]
|
|
965
|
-
run(
|
|
966
|
-
"split-predicate",
|
|
967
|
-
split_predicate,
|
|
968
|
-
1,
|
|
969
|
-
"duplicate normalized root_cause_predicate",
|
|
970
|
-
)
|
|
971
|
-
|
|
972
|
-
distinct_predicates = copy.deepcopy(split_predicate)
|
|
973
|
-
for index, row in enumerate(distinct_predicates["finding_classes"], start=1):
|
|
974
|
-
row["root_cause_predicate"] = (
|
|
975
|
-
f"Distinct controller-evidence failure predicate {index}."
|
|
976
|
-
)
|
|
977
|
-
run(
|
|
978
|
-
"distinct-predicates",
|
|
979
|
-
distinct_predicates,
|
|
980
|
-
0,
|
|
981
|
-
"closeout_state=continuation_authorization_required",
|
|
982
|
-
)
|
|
983
|
-
|
|
984
|
-
missing_sweep = copy.deepcopy(third_occurrence["ledger"])
|
|
985
|
-
missing_sweep["finding_classes"][0]["authoritative_sweep"] = None
|
|
986
|
-
run("missing-sweep", missing_sweep, 1, "authoritative_sweep")
|
|
987
|
-
|
|
988
|
-
bad_sweep_set = copy.deepcopy(third_occurrence["ledger"])
|
|
989
|
-
bad_sweep_set["finding_classes"][0]["authoritative_sweep"]["searched_set"] = [
|
|
990
|
-
"skills/code-review"
|
|
991
|
-
]
|
|
992
|
-
run("bad-sweep-set", bad_sweep_set, 1, "searched_set does not match")
|
|
993
|
-
|
|
994
|
-
ready_unmatched = make_fixture(
|
|
995
|
-
"ready-unmatched",
|
|
996
|
-
receipt_findings=[[finding(1), finding(2), finding(3)], []],
|
|
997
|
-
unmatched=1,
|
|
998
|
-
)
|
|
999
|
-
run("ready-unmatched", ready_unmatched["ledger"], 1, "ready sweep must report zero unmatched")
|
|
1000
|
-
|
|
1001
|
-
wrong_remote = make_fixture("wrong-remote")
|
|
1002
|
-
wrong_remote["ledger"]["base_attestations"][1]["remote"] = "upstream"
|
|
1003
|
-
run("wrong-remote", wrong_remote["ledger"], 1, "same remote and ref")
|
|
1004
|
-
|
|
1005
|
-
bad_sequence = make_fixture("bad-sequence")
|
|
1006
|
-
bad_sequence["ledger"]["base_attestations"][1]["sequence"] = 3
|
|
1007
|
-
run("bad-sequence", bad_sequence["ledger"], 1, "sequence must be contiguous")
|
|
1008
|
-
|
|
1009
|
-
bad_time = make_fixture("bad-time")
|
|
1010
|
-
bad_time["ledger"]["base_attestations"][1]["confirmed_at"] = "2026-08-29T12:01:00Z"
|
|
1011
|
-
run("bad-time", bad_time["ledger"], 1, "strictly increase")
|
|
1012
|
-
|
|
1013
|
-
invalid_time = make_fixture("invalid-time")
|
|
1014
|
-
invalid_time["ledger"]["base_attestations"][0]["confirmed_at"] = "2026-08-29 12:00:00"
|
|
1015
|
-
run("invalid-time", invalid_time["ledger"], 1, "strict RFC3339")
|
|
1016
|
-
|
|
1017
|
-
missing_mapping = make_fixture("missing-mapping")
|
|
1018
|
-
missing_mapping["ledger"]["base_attestations"][1]["controller_receipt_sha256"] = None
|
|
1019
|
-
run("missing-mapping", missing_mapping["ledger"], 1, "map every controller receipt")
|
|
1020
|
-
|
|
1021
|
-
consumed_first_drift = make_fixture("consumed-first-drift", base_shas=[A, B])
|
|
1022
|
-
run(
|
|
1023
|
-
"consumed-first-drift",
|
|
1024
|
-
consumed_first_drift["ledger"],
|
|
1025
|
-
0,
|
|
1026
|
-
"closeout_state=ready_for_human_decision",
|
|
1027
|
-
)
|
|
1028
|
-
|
|
1029
|
-
stable_trailing_recheck = make_fixture(
|
|
1030
|
-
"stable-trailing-recheck", base_shas=[A, A, A]
|
|
1031
|
-
)
|
|
1032
|
-
run(
|
|
1033
|
-
"stable-trailing-recheck",
|
|
1034
|
-
stable_trailing_recheck["ledger"],
|
|
1035
|
-
0,
|
|
1036
|
-
"closeout_state=ready_for_human_decision",
|
|
1037
|
-
)
|
|
1038
|
-
|
|
1039
|
-
unconsumed_first_drift = make_fixture(
|
|
1040
|
-
"unconsumed-first-drift", base_shas=[A, A, B]
|
|
1041
|
-
)
|
|
1042
|
-
run(
|
|
1043
|
-
"unconsumed-first-drift",
|
|
1044
|
-
unconsumed_first_drift["ledger"],
|
|
1045
|
-
1,
|
|
1046
|
-
"final controller receipt does not consume the latest attested base",
|
|
1047
|
-
)
|
|
1048
|
-
|
|
1049
|
-
bad_evidence = make_fixture("bad-evidence")
|
|
1050
|
-
bad_evidence["ledger"]["base_attestations"][0]["evidence_sha256"] = "f" * 64
|
|
1051
|
-
run("bad-evidence", bad_evidence["ledger"], 1, "digest does not match")
|
|
1052
|
-
|
|
1053
|
-
bad_evidence_content = make_fixture("bad-evidence-content")
|
|
1054
|
-
bad_evidence_row = bad_evidence_content["ledger"]["base_attestations"][0]
|
|
1055
|
-
bad_evidence_path = root / bad_evidence_row["evidence_file"]
|
|
1056
|
-
bad_evidence_path.write_text(f"{A}\trefs/heads/other\n", encoding="utf-8")
|
|
1057
|
-
bad_evidence_row["evidence_sha256"] = hashlib.sha256(
|
|
1058
|
-
bad_evidence_path.read_bytes()
|
|
1059
|
-
).hexdigest()
|
|
1060
|
-
run(
|
|
1061
|
-
"bad-evidence-content",
|
|
1062
|
-
bad_evidence_content["ledger"],
|
|
1063
|
-
1,
|
|
1064
|
-
"canonical ls-remote output",
|
|
1065
|
-
)
|
|
1066
|
-
|
|
1067
|
-
surrogate = make_fixture("surrogate")
|
|
1068
|
-
surrogate["ledger"]["controller_review_state"] = "\ud800"
|
|
1069
|
-
run("surrogate", surrogate["ledger"], 1, "valid UTF-8 text")
|
|
1070
|
-
|
|
1071
|
-
fifo = make_fixture("fifo")
|
|
1072
|
-
fifo_name = "controller-receipt.fifo"
|
|
1073
|
-
os.mkfifo(root / fifo_name)
|
|
1074
|
-
fifo["ledger"]["controller_receipts"][0]["file"] = fifo_name
|
|
1075
|
-
fifo["ledger"]["controller_receipts"][0]["sha256"] = "f" * 64
|
|
1076
|
-
run("fifo", fifo["ledger"], 1, "singly linked regular file")
|
|
1077
|
-
|
|
1078
|
-
second_drift_wrong = make_fixture("second-drift-wrong", base_shas=[A, B, A])
|
|
1079
|
-
run("second-drift-wrong", second_drift_wrong["ledger"], 1, "second base drift")
|
|
1080
|
-
|
|
1081
|
-
flip_flop = make_fixture(
|
|
1082
|
-
"flip-flop",
|
|
1083
|
-
completion=False,
|
|
1084
|
-
base_shas=[A, B, A],
|
|
1085
|
-
closeout="baseline_race",
|
|
1086
|
-
)
|
|
1087
|
-
flip_flop["ledger"]["unreviewed_delta"] = ["target returned to its first SHA"]
|
|
1088
|
-
run("flip-flop", flip_flop["ledger"], 0, "base_changes=2")
|
|
1089
|
-
|
|
1090
|
-
one_round_race = make_fixture(
|
|
1091
|
-
"one-round-race",
|
|
1092
|
-
receipt_findings=[[]],
|
|
1093
|
-
completion=False,
|
|
1094
|
-
base_shas=[A, B, C],
|
|
1095
|
-
closeout="baseline_race",
|
|
1096
|
-
)
|
|
1097
|
-
one_round_race["ledger"]["unreviewed_delta"] = ["second target drift after round 1"]
|
|
1098
|
-
run("one-round-race", one_round_race["ledger"], 0, "base_changes=2")
|
|
1099
|
-
|
|
1100
|
-
post_race_round = make_fixture(
|
|
1101
|
-
"post-race-round",
|
|
1102
|
-
completion=False,
|
|
1103
|
-
base_shas=[A, B, C],
|
|
1104
|
-
closeout="baseline_race",
|
|
1105
|
-
)
|
|
1106
|
-
post_race_round["ledger"]["base_attestations"][1][
|
|
1107
|
-
"controller_receipt_sha256"
|
|
1108
|
-
] = None
|
|
1109
|
-
post_race_round["ledger"]["base_attestations"][2][
|
|
1110
|
-
"controller_receipt_sha256"
|
|
1111
|
-
] = post_race_round["receipt_hashes"][1]
|
|
1112
|
-
post_race_round["ledger"]["unreviewed_delta"] = [
|
|
1113
|
-
"round 2 was started after the second target drift"
|
|
1114
|
-
]
|
|
1115
|
-
run(
|
|
1116
|
-
"post-race-round",
|
|
1117
|
-
post_race_round["ledger"],
|
|
1118
|
-
1,
|
|
1119
|
-
"controller receipt is mapped at or after the second base drift",
|
|
1120
|
-
)
|
|
1121
|
-
|
|
1122
|
-
race_with_complete = make_fixture(
|
|
1123
|
-
"race-with-complete", base_shas=[A, B, C], closeout="baseline_race"
|
|
1124
|
-
)
|
|
1125
|
-
race_with_complete["ledger"]["unreviewed_delta"] = ["second target drift"]
|
|
1126
|
-
run("race-with-complete", race_with_complete["ledger"], 1, "cannot carry a completion receipt")
|
|
1127
|
-
|
|
1128
|
-
race_without_delta = make_fixture(
|
|
1129
|
-
"race-without-delta",
|
|
1130
|
-
completion=False,
|
|
1131
|
-
base_shas=[A, B, C],
|
|
1132
|
-
closeout="baseline_race",
|
|
1133
|
-
)
|
|
1134
|
-
run("race-without-delta", race_without_delta["ledger"], 1, "non-empty unreviewed_delta")
|
|
1135
|
-
|
|
1136
|
-
race_candidate = make_fixture(
|
|
1137
|
-
"race-candidate",
|
|
1138
|
-
completion=False,
|
|
1139
|
-
base_shas=[A, B, C],
|
|
1140
|
-
closeout="baseline_race",
|
|
1141
|
-
)
|
|
1142
|
-
race_candidate["ledger"]["candidate_sha256"] = OTHER_CANDIDATE
|
|
1143
|
-
race_candidate["ledger"]["unreviewed_delta"] = ["second target drift"]
|
|
1144
|
-
run(
|
|
1145
|
-
"race-candidate",
|
|
1146
|
-
race_candidate["ledger"],
|
|
1147
|
-
1,
|
|
1148
|
-
"controller receipt 1 does not bind the ledger candidate",
|
|
1149
|
-
)
|
|
1150
|
-
|
|
1151
|
-
false_race = make_fixture(
|
|
1152
|
-
"false-race", completion=False, closeout="baseline_race"
|
|
1153
|
-
)
|
|
1154
|
-
run("false-race", false_race["ledger"], 1, "baseline_race requires two ordered base changes")
|
|
1155
|
-
|
|
1156
|
-
needs_human_resolution_results = []
|
|
1157
|
-
for closing_disposition in sorted(CLOSED_DISPOSITIONS):
|
|
1158
|
-
case_name = f"historical-needs-human-{closing_disposition.replace('_', '-')}"
|
|
1159
|
-
historical_needs_human_linked = make_fixture(
|
|
1160
|
-
case_name,
|
|
1161
|
-
receipt_findings=[[finding(1), finding(2)], []],
|
|
1162
|
-
)
|
|
1163
|
-
historical_needs_human_occurrences = historical_needs_human_linked["ledger"][
|
|
1164
|
-
"finding_classes"
|
|
1165
|
-
][0]["occurrences"]
|
|
1166
|
-
historical_needs_human_occurrences[0]["disposition"] = "needs_human_decision"
|
|
1167
|
-
clear_disposition_evidence(historical_needs_human_occurrences[0])
|
|
1168
|
-
historical_needs_human_occurrences[1]["disposition"] = closing_disposition
|
|
1169
|
-
bind_disposition_evidence(
|
|
1170
|
-
f"{case_name}-disposition.json",
|
|
1171
|
-
historical_needs_human_occurrences[1],
|
|
1172
|
-
resolves=[
|
|
1173
|
-
occurrence_ref(historical_needs_human_occurrences[0]),
|
|
1174
|
-
occurrence_ref(historical_needs_human_occurrences[1]),
|
|
1175
|
-
],
|
|
1176
|
-
)
|
|
1177
|
-
needs_human_resolution_results.append(
|
|
1178
|
-
(case_name, invoke(case_name, historical_needs_human_linked["ledger"]))
|
|
1179
|
-
)
|
|
1180
|
-
|
|
1181
|
-
duplicate_ledger = make_fixture("duplicate-ledger")
|
|
1182
|
-
duplicate_ledger_result = invoke_encoded(
|
|
1183
|
-
"duplicate-ledger",
|
|
1184
|
-
encode_duplicate_key(duplicate_ledger["ledger"], "schema_version", 2),
|
|
1185
|
-
)
|
|
1186
|
-
|
|
1187
|
-
duplicate_controller = make_fixture("duplicate-controller")
|
|
1188
|
-
duplicate_controller_ledger = duplicate_controller["ledger"]
|
|
1189
|
-
duplicate_controller_name = duplicate_controller_ledger["controller_receipts"][-1][
|
|
1190
|
-
"file"
|
|
1191
|
-
]
|
|
1192
|
-
duplicate_controller_payload = json.loads(
|
|
1193
|
-
(root / duplicate_controller_name).read_text(encoding="utf-8")
|
|
1194
|
-
)
|
|
1195
|
-
duplicate_controller_hash = write_duplicate_json(
|
|
1196
|
-
duplicate_controller_name,
|
|
1197
|
-
duplicate_controller_payload,
|
|
1198
|
-
"status",
|
|
1199
|
-
"findings",
|
|
1200
|
-
)
|
|
1201
|
-
duplicate_controller_ledger["controller_receipts"][-1][
|
|
1202
|
-
"sha256"
|
|
1203
|
-
] = duplicate_controller_hash
|
|
1204
|
-
duplicate_controller_ledger["base_attestations"][-1][
|
|
1205
|
-
"controller_receipt_sha256"
|
|
1206
|
-
] = duplicate_controller_hash
|
|
1207
|
-
duplicate_controller_complete_name = duplicate_controller_ledger[
|
|
1208
|
-
"completion_receipt"
|
|
1209
|
-
]["file"]
|
|
1210
|
-
duplicate_controller_complete = json.loads(
|
|
1211
|
-
(root / duplicate_controller_complete_name).read_text(encoding="utf-8")
|
|
1212
|
-
)
|
|
1213
|
-
duplicate_controller_complete[
|
|
1214
|
-
"completion_review_result_sha256"
|
|
1215
|
-
] = duplicate_controller_hash
|
|
1216
|
-
duplicate_controller_ledger["completion_receipt"]["sha256"] = write_json(
|
|
1217
|
-
duplicate_controller_complete_name,
|
|
1218
|
-
duplicate_controller_complete,
|
|
1219
|
-
)
|
|
1220
|
-
duplicate_controller_result = invoke(
|
|
1221
|
-
"duplicate-controller",
|
|
1222
|
-
duplicate_controller_ledger,
|
|
1223
|
-
)
|
|
1224
|
-
|
|
1225
|
-
duplicate_completion = make_fixture("duplicate-completion")
|
|
1226
|
-
duplicate_completion_ledger = duplicate_completion["ledger"]
|
|
1227
|
-
duplicate_completion_name = duplicate_completion_ledger["completion_receipt"]["file"]
|
|
1228
|
-
duplicate_completion_payload = json.loads(
|
|
1229
|
-
(root / duplicate_completion_name).read_text(encoding="utf-8")
|
|
1230
|
-
)
|
|
1231
|
-
duplicate_completion_ledger["completion_receipt"]["sha256"] = write_duplicate_json(
|
|
1232
|
-
duplicate_completion_name,
|
|
1233
|
-
duplicate_completion_payload,
|
|
1234
|
-
"review_state",
|
|
1235
|
-
"reviewed",
|
|
1236
|
-
)
|
|
1237
|
-
duplicate_completion_result = invoke(
|
|
1238
|
-
"duplicate-completion",
|
|
1239
|
-
duplicate_completion_ledger,
|
|
1240
|
-
)
|
|
1241
|
-
|
|
1242
|
-
duplicate_sweep = make_fixture(
|
|
1243
|
-
"duplicate-sweep",
|
|
1244
|
-
receipt_findings=[[finding(1), finding(2)], [finding(3)]],
|
|
1245
|
-
completion=False,
|
|
1246
|
-
open_last=True,
|
|
1247
|
-
)
|
|
1248
|
-
duplicate_sweep_ledger = duplicate_sweep["ledger"]
|
|
1249
|
-
duplicate_sweep_row = duplicate_sweep_ledger["finding_classes"][0][
|
|
1250
|
-
"authoritative_sweep"
|
|
1251
|
-
]
|
|
1252
|
-
duplicate_sweep_payload = json.loads(
|
|
1253
|
-
(root / duplicate_sweep_row["manifest_file"]).read_text(encoding="utf-8")
|
|
1254
|
-
)
|
|
1255
|
-
duplicate_sweep_row["manifest_sha256"] = write_duplicate_json(
|
|
1256
|
-
duplicate_sweep_row["manifest_file"],
|
|
1257
|
-
duplicate_sweep_payload,
|
|
1258
|
-
"candidate_sha256",
|
|
1259
|
-
OTHER_CANDIDATE,
|
|
1260
|
-
)
|
|
1261
|
-
duplicate_sweep_result = invoke("duplicate-sweep", duplicate_sweep_ledger)
|
|
1262
|
-
|
|
1263
|
-
new_regressions = [
|
|
1264
|
-
*[
|
|
1265
|
-
(
|
|
1266
|
-
case_name,
|
|
1267
|
-
result,
|
|
1268
|
-
"cannot resolve a needs_human_decision occurrence",
|
|
1269
|
-
)
|
|
1270
|
-
for case_name, result in needs_human_resolution_results
|
|
1271
|
-
],
|
|
1272
|
-
("duplicate-ledger", duplicate_ledger_result, "duplicate object key: schema_version"),
|
|
1273
|
-
("duplicate-controller", duplicate_controller_result, "duplicate object key: status"),
|
|
1274
|
-
(
|
|
1275
|
-
"duplicate-completion",
|
|
1276
|
-
duplicate_completion_result,
|
|
1277
|
-
"duplicate object key: review_state",
|
|
1278
|
-
),
|
|
1279
|
-
("duplicate-sweep", duplicate_sweep_result, "duplicate object key: candidate_sha256"),
|
|
1280
|
-
]
|
|
1281
|
-
assert [
|
|
1282
|
-
(name, result.returncode, token in result.stdout, "Traceback" in result.stdout)
|
|
1283
|
-
for name, result, token in new_regressions
|
|
1284
|
-
] == [(name, 1, True, False) for name, _result, _token in new_regressions], [
|
|
1285
|
-
(name, result.returncode, result.stdout) for name, result, _token in new_regressions
|
|
1286
|
-
]
|
|
1287
|
-
|
|
1288
|
-
def make_refuted_completion(name, **kwargs):
|
|
1289
|
-
kwargs.setdefault("receipt_findings", [[finding(1)], [finding(2)]])
|
|
1290
|
-
case = make_fixture(name, **kwargs)
|
|
1291
|
-
ledger = case["ledger"]
|
|
1292
|
-
dispositions = []
|
|
1293
|
-
for row in ledger["finding_classes"]:
|
|
1294
|
-
for index, occurrence in enumerate(row["occurrences"]):
|
|
1295
|
-
occurrence["disposition"] = "source_refuted"
|
|
1296
|
-
witness = bind_disposition_evidence(
|
|
1297
|
-
f"{name}-refuted-{index}.json", occurrence,
|
|
1298
|
-
evidence=[f"synthetic source refutes occurrence {index}"],
|
|
1299
|
-
)
|
|
1300
|
-
dispositions.append({
|
|
1301
|
-
**occurrence_ref(occurrence),
|
|
1302
|
-
"disposition": "source_refuted",
|
|
1303
|
-
"evidence": witness["evidence"],
|
|
1304
|
-
})
|
|
1305
|
-
document = {
|
|
1306
|
-
"schema_version": 1,
|
|
1307
|
-
"candidate_sha256": CANDIDATE,
|
|
1308
|
-
"review_result_sha256": list(case["receipt_hashes"]),
|
|
1309
|
-
"dispositions": dispositions,
|
|
1310
|
-
}
|
|
1311
|
-
name = f"{name}-finding-dispositions.json"
|
|
1312
|
-
ledger["finding_dispositions"] = {"file": name, "sha256": write_json(name, document)}
|
|
1313
|
-
completion_ref = ledger["completion_receipt"]
|
|
1314
|
-
complete = json.loads((root / completion_ref["file"]).read_text())
|
|
1315
|
-
complete.update(
|
|
1316
|
-
completion_basis="source_refuted_findings",
|
|
1317
|
-
finding_dispositions_sha256=ledger["finding_dispositions"]["sha256"],
|
|
1318
|
-
resolved_finding_occurrences=[occurrence_ref(item) for item in dispositions],
|
|
1319
|
-
)
|
|
1320
|
-
completion_ref["sha256"] = write_json(completion_ref["file"], complete)
|
|
1321
|
-
return case
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
def mutate_refuted_completion(case, mutator):
|
|
1325
|
-
ref = case["ledger"]["completion_receipt"]
|
|
1326
|
-
document = json.loads((root / ref["file"]).read_text())
|
|
1327
|
-
mutator(document)
|
|
1328
|
-
ref["sha256"] = write_json(ref["file"], document)
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
def mutate_refuted_document(case, mutator, *, duplicate_key=None):
|
|
1332
|
-
ref = case["ledger"]["finding_dispositions"]
|
|
1333
|
-
document = json.loads((root / ref["file"]).read_text())
|
|
1334
|
-
mutator(document)
|
|
1335
|
-
ref["sha256"] = (
|
|
1336
|
-
write_duplicate_json(ref["file"], document, duplicate_key, "ignored")
|
|
1337
|
-
if duplicate_key else write_json(ref["file"], document)
|
|
1338
|
-
)
|
|
1339
|
-
mutate_refuted_completion(case, lambda row: row.update(finding_dispositions_sha256=ref["sha256"]))
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
adjudicated = make_refuted_completion("adjudicated")
|
|
1343
|
-
run("adjudicated", adjudicated["ledger"], 0, "ready_for_human_decision")
|
|
1344
|
-
for ref in adjudicated["ledger"]["controller_receipts"]:
|
|
1345
|
-
raw = (root / ref["file"]).read_bytes()
|
|
1346
|
-
assert hashlib.sha256(raw).hexdigest() == ref["sha256"]
|
|
1347
|
-
assert json.loads(raw)["status"] == "findings"
|
|
1348
|
-
|
|
1349
|
-
historical_refuted = make_refuted_completion("historical-refuted", receipt_findings=[[finding(1)], []])
|
|
1350
|
-
run("historical-refuted", historical_refuted["ledger"], 0, "ready_for_human_decision")
|
|
1351
|
-
|
|
1352
|
-
duplicate_finding_cases = [
|
|
1353
|
-
("duplicate-only", [[finding(1), dict(reversed(list(finding(1).items())))], []], 1),
|
|
1354
|
-
("duplicate-plus-distinct", [[finding(2), finding(1), finding(2)], []], 2),
|
|
1355
|
-
("duplicate-across-receipts", [[finding(1), finding(1)], [finding(1), finding(1)]], 2),
|
|
1356
|
-
]
|
|
1357
|
-
duplicate_cases = {}
|
|
1358
|
-
for name, receipt_findings, identity_count in duplicate_finding_cases:
|
|
1359
|
-
case = make_refuted_completion(name, receipt_findings=receipt_findings)
|
|
1360
|
-
duplicate_cases[name] = case
|
|
1361
|
-
raw_receipts = [(root / ref["file"]).read_bytes() for ref in case["ledger"]["controller_receipts"]]
|
|
1362
|
-
document = json.loads((root / case["ledger"]["finding_dispositions"]["file"]).read_text())
|
|
1363
|
-
assert len(document["dispositions"]) == identity_count
|
|
1364
|
-
run(name, case["ledger"], 0, "ready_for_human_decision")
|
|
1365
|
-
for ref, raw, original in zip(case["ledger"]["controller_receipts"], raw_receipts, receipt_findings):
|
|
1366
|
-
assert (root / ref["file"]).read_bytes() == raw
|
|
1367
|
-
assert hashlib.sha256(raw).hexdigest() == ref["sha256"]
|
|
1368
|
-
assert json.loads(raw)["findings"] == original
|
|
1369
|
-
|
|
1370
|
-
for name in ("duplicate-plus-distinct", "duplicate-across-receipts"):
|
|
1371
|
-
omitted = copy.deepcopy(duplicate_cases[name]["ledger"])
|
|
1372
|
-
del omitted["finding_classes"][0]["occurrences"][-1]
|
|
1373
|
-
run(f"{name}-missing-class", omitted, 1, "omits controller findings")
|
|
1374
|
-
|
|
1375
|
-
missing_distinct_disposition = make_refuted_completion(
|
|
1376
|
-
"duplicate-missing-disposition", receipt_findings=[[finding(2), finding(1), finding(2)], []]
|
|
1377
|
-
)
|
|
1378
|
-
mutate_refuted_document(missing_distinct_disposition, lambda row: row["dispositions"].pop())
|
|
1379
|
-
run("duplicate-missing-disposition", missing_distinct_disposition["ledger"], 1, "ordered controller findings")
|
|
1380
|
-
|
|
1381
|
-
repeated_class = copy.deepcopy(duplicate_cases["duplicate-only"]["ledger"])
|
|
1382
|
-
repeated_occurrences = repeated_class["finding_classes"][0]["occurrences"]
|
|
1383
|
-
repeated_occurrences.append(copy.deepcopy(repeated_occurrences[0]))
|
|
1384
|
-
run("duplicate-finding-repeated-class", repeated_class, 1, "classified more than once")
|
|
1385
|
-
|
|
1386
|
-
for name, kwargs, token in [
|
|
1387
|
-
("one-round", {"receipt_findings": [[finding(1)]]}, "review and challenge"),
|
|
1388
|
-
("empty", {"receipt_findings": [[], []]}, "at least one controller finding"),
|
|
1389
|
-
("succession", {"receipt_findings": [[finding(1)], [finding(2)], [finding(3)]], "succession": True}, "without succession"),
|
|
1390
|
-
]:
|
|
1391
|
-
case = make_refuted_completion(f"adjudicated-{name}", **kwargs)
|
|
1392
|
-
run(f"adjudicated-{name}", case["ledger"], 1, token)
|
|
1393
|
-
|
|
1394
|
-
external_basis = make_fixture("external-basis", completion_mutator=lambda row: row.update(
|
|
1395
|
-
completion_basis="external_pass", finding_dispositions_sha256=None,
|
|
1396
|
-
resolved_finding_occurrences=[],
|
|
1397
|
-
))
|
|
1398
|
-
run("external-basis", external_basis["ledger"], 0, "ready_for_human_decision")
|
|
1399
|
-
|
|
1400
|
-
orphan_dispositions = make_fixture("orphan-dispositions")
|
|
1401
|
-
orphan_dispositions["ledger"]["finding_dispositions"] = dict(adjudicated["ledger"]["finding_dispositions"])
|
|
1402
|
-
run("orphan-dispositions", orphan_dispositions["ledger"], 1, "requires a source_refuted_findings completion")
|
|
1403
|
-
|
|
1404
|
-
missing_ref = make_refuted_completion("adjudicated-missing-ref")
|
|
1405
|
-
del missing_ref["ledger"]["finding_dispositions"]
|
|
1406
|
-
run("adjudicated-missing-ref", missing_ref["ledger"], 1, "finding_dispositions")
|
|
1407
|
-
|
|
1408
|
-
bad_ref_hash = make_refuted_completion("adjudicated-bad-ref-hash")
|
|
1409
|
-
bad_ref_hash["ledger"]["finding_dispositions"]["sha256"] = "f" * 64
|
|
1410
|
-
run("adjudicated-bad-ref-hash", bad_ref_hash["ledger"], 1, "digest does not match")
|
|
1411
|
-
|
|
1412
|
-
for name, mutate, token in [
|
|
1413
|
-
("stale-candidate", lambda row: row.update(candidate_sha256=OTHER_CANDIDATE), "current candidate"),
|
|
1414
|
-
("missing-prefix", lambda row: row["review_result_sha256"].pop(0), "ordered controller receipts"),
|
|
1415
|
-
("reordered-prefix", lambda row: row["review_result_sha256"].reverse(), "ordered controller receipts"),
|
|
1416
|
-
("missing-occurrence", lambda row: row["dispositions"].pop(0), "ordered controller findings"),
|
|
1417
|
-
("duplicate-occurrence", lambda row: row["dispositions"].append(copy.deepcopy(row["dispositions"][0])), "ordered controller findings"),
|
|
1418
|
-
("reordered-occurrences", lambda row: row["dispositions"].reverse(), "ordered controller findings"),
|
|
1419
|
-
("wrong-finding", lambda row: row["dispositions"][0].update(finding_sha256="f" * 64), "ordered controller findings"),
|
|
1420
|
-
("empty-evidence", lambda row: row["dispositions"][0].update(evidence=[]), "non-empty evidence"),
|
|
1421
|
-
("blank-evidence", lambda row: row["dispositions"][0].update(evidence=[" "]), "normalized string"),
|
|
1422
|
-
("long-evidence", lambda row: row["dispositions"][0].update(evidence=["x" * 1001]), "1000 characters"),
|
|
1423
|
-
("different-evidence", lambda row: row["dispositions"][0].update(evidence=["different source claim"]), "class disposition evidence"),
|
|
1424
|
-
]:
|
|
1425
|
-
case = make_refuted_completion(f"adjudicated-{name}")
|
|
1426
|
-
mutate_refuted_document(case, mutate)
|
|
1427
|
-
run(f"adjudicated-{name}", case["ledger"], 1, token)
|
|
1428
|
-
|
|
1429
|
-
for disposition in ("fixed", "accepted_tradeoff", "pre_existing_out_of_scope", "open", "needs_human_decision"):
|
|
1430
|
-
case = make_refuted_completion(f"adjudicated-mixed-{disposition}")
|
|
1431
|
-
mutate_refuted_document(case, lambda row: row["dispositions"][0].update(disposition=disposition))
|
|
1432
|
-
run(f"adjudicated-mixed-{disposition}", case["ledger"], 1, "only source_refuted")
|
|
1433
|
-
class_case = make_refuted_completion(f"adjudicated-class-{disposition}")
|
|
1434
|
-
occurrence = class_case["ledger"]["finding_classes"][0]["occurrences"][0]
|
|
1435
|
-
occurrence["disposition"] = disposition
|
|
1436
|
-
clear_disposition_evidence(occurrence)
|
|
1437
|
-
if disposition in CLOSED_DISPOSITIONS:
|
|
1438
|
-
bind_disposition_evidence(f"adjudicated-class-{disposition}-witness.json", occurrence)
|
|
1439
|
-
run(f"adjudicated-class-{disposition}", class_case["ledger"], 1, "only source_refuted")
|
|
1440
|
-
|
|
1441
|
-
for name, mutate, token in [
|
|
1442
|
-
("wrong-complete-hash", lambda row: row.update(finding_dispositions_sha256="f" * 64), "completion disposition digest"),
|
|
1443
|
-
("missing-complete-pairs", lambda row: row.update(resolved_finding_occurrences=[]), "resolved_finding_occurrences"),
|
|
1444
|
-
("reordered-complete-pairs", lambda row: row["resolved_finding_occurrences"].reverse(), "resolved_finding_occurrences"),
|
|
1445
|
-
("unknown-basis", lambda row: row.update(completion_basis="author-approved"), "completion_basis"),
|
|
1446
|
-
("basis-downgrade", lambda row: row.update(completion_basis="external_pass"), "final external receipt with findings"),
|
|
1447
|
-
]:
|
|
1448
|
-
case = make_refuted_completion(f"adjudicated-{name}")
|
|
1449
|
-
mutate_refuted_completion(case, mutate)
|
|
1450
|
-
run(f"adjudicated-{name}", case["ledger"], 1, token)
|
|
1451
|
-
|
|
1452
|
-
missing_witness = make_refuted_completion("adjudicated-missing-witness")
|
|
1453
|
-
clear_disposition_evidence(missing_witness["ledger"]["finding_classes"][0]["occurrences"][0])
|
|
1454
|
-
run("adjudicated-missing-witness", missing_witness["ledger"], 1, "disposition_evidence_file")
|
|
1455
|
-
|
|
1456
|
-
duplicate_document = make_refuted_completion("adjudicated-duplicate-key")
|
|
1457
|
-
mutate_refuted_document(duplicate_document, lambda row: None, duplicate_key="candidate_sha256")
|
|
1458
|
-
run("adjudicated-duplicate-key", duplicate_document["ledger"], 1, "duplicate object key")
|
|
1459
|
-
|
|
1460
|
-
linked_document = make_refuted_completion("adjudicated-linked-document")
|
|
1461
|
-
ref = linked_document["ledger"]["finding_dispositions"]
|
|
1462
|
-
linked_path = root / ref["file"]
|
|
1463
|
-
original_path = linked_path.with_suffix(".original")
|
|
1464
|
-
linked_path.rename(original_path)
|
|
1465
|
-
linked_path.symlink_to(original_path)
|
|
1466
|
-
run("adjudicated-linked-document", linked_document["ledger"], 1, "unreadable")
|
|
1467
|
-
|
|
1468
|
-
path_escape = make_refuted_completion("adjudicated-path-escape")
|
|
1469
|
-
path_escape["ledger"]["finding_dispositions"]["file"] = "../outside.json"
|
|
1470
|
-
run("adjudicated-path-escape", path_escape["ledger"], 1, "ledger directory")
|
|
1471
|
-
|
|
1472
|
-
delta_case = make_refuted_completion("adjudicated-delta")
|
|
1473
|
-
delta_case["ledger"]["unreviewed_delta"] = ["post-review implementation edit"]
|
|
1474
|
-
run("adjudicated-delta", delta_case["ledger"], 1, "unreviewed delta")
|
|
1475
|
-
|
|
1476
|
-
print("test_validate_extraction_review_state: ok")
|
|
1477
|
-
PY
|