@ccoalm/ccl-skills 0.17.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.
Files changed (34) hide show
  1. package/dist/assets/marketplace/plugins/ccl-skills/agent-context/session-start.md +8 -7
  2. package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +22 -0
  3. package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-review-covers-head.sh +128 -0
  4. package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-untracked-background.sh +53 -0
  5. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_review_covers_head.sh +104 -0
  6. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_untracked_background.sh +75 -0
  7. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +8 -0
  8. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/development-completion.md +13 -1
  9. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +5 -3
  10. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +401 -21
  11. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +8 -1
  12. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +230 -7
  13. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/SKILL.md +1 -1
  14. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +1 -1
  15. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +6 -6
  16. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +48 -119
  17. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +9 -9
  18. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +8 -0
  19. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +2 -2
  20. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check_review_evidence_present.py +122 -0
  21. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/contract-anchors.tsv +0 -1
  22. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh +37 -8
  23. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +102 -20
  24. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ai_coding_implementation_gates.sh +16 -27
  25. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +3 -5
  26. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_review_evidence_present.sh +81 -0
  27. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_extraction_review_gate.sh +130 -310
  28. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +49 -3
  29. package/dist/assets/release.json +55 -45
  30. package/package.json +1 -1
  31. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/review_ledger_binding.py +0 -1242
  32. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_review_ledger_binding.sh +0 -978
  33. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_extraction_review_state.sh +0 -1477
  34. 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