its-magic 0.1.3-3 → 0.1.3-4

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.
@@ -0,0 +1,168 @@
1
+ """
2
+ Contract tests for US-0119 — Autonomous-autonomy presets.
3
+
4
+ 10 test markers per DEC-0119 §9, covering AC-6, AC-7, AC-10, AC-12.
5
+ """
6
+ import pytest
7
+ import sys
8
+ from pathlib import Path
9
+
10
+
11
+ def test_us0119_preset_none_is_noop():
12
+ """AC-6: AUTONOMY_PRESET=none produces byte-identical pre-US-0119 behaviour (empty expansion)."""
13
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
14
+ from autonomy_preset_lib import expand_autonomy_preset
15
+
16
+ result = expand_autonomy_preset("none")
17
+ assert result == {}, "AUTONOMY_PRESET=none MUST produce empty expansion (byte-identical pre-US-0119)"
18
+
19
+
20
+ def test_us0119_preset_balanced_expansion():
21
+ """AC-2: balanced preset expands into documented 8 flags per DEC-0119 §7."""
22
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
23
+ from autonomy_preset_lib import expand_autonomy_preset
24
+
25
+ result = expand_autonomy_preset("balanced")
26
+ assert len(result) == 8, f"balanced preset MUST expand to 8 flags, got {len(result)}"
27
+ expected_keys = {
28
+ "WORK_KIND_AUTO_ACCEPT",
29
+ "CROSS_MODEL_REWORK_EXHAUSTED_POLICY",
30
+ "CROSS_MODEL_SKIP_PHASES",
31
+ "RESUME_BRIEF_AUTO_REFRESH",
32
+ "RUNTIME_PROOF_KIND",
33
+ "GOAL_CONVERGENCE_INTERVAL",
34
+ "SOVEREIGN_DRAIN_AUTO_ACCEPT",
35
+ "AUTONOMY_STOP_POLICY",
36
+ }
37
+ assert set(result.keys()) == expected_keys, f"balanced preset keys mismatch: {set(result.keys())} != {expected_keys}"
38
+
39
+
40
+ def test_us0119_preset_full_expansion():
41
+ """AC-2: full preset expands into documented 12 flags per DEC-0119 §7."""
42
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
43
+ from autonomy_preset_lib import expand_autonomy_preset
44
+
45
+ result = expand_autonomy_preset("full")
46
+ assert len(result) == 12, f"full preset MUST expand to 12 flags, got {len(result)}"
47
+ expected_keys = {
48
+ "INTAKE_AUTONOMY_MODE",
49
+ "INTAKE_MINIMAL_PACK",
50
+ "INTAKE_ASSUME_STACK_CONTEXT",
51
+ "WORK_KIND_AUTO_ACCEPT",
52
+ "CROSS_MODEL_REWORK_EXHAUSTED_POLICY",
53
+ "CROSS_MODEL_SKIP_PHASES",
54
+ "RESUME_BRIEF_AUTO_REFRESH",
55
+ "RUNTIME_PROOF_KIND",
56
+ "GOAL_CONVERGENCE_INTERVAL",
57
+ "SOVEREIGN_DRAIN_AUTO_ACCEPT",
58
+ "RELEASE_PUBLISH_AUTO_CONFIRM",
59
+ "AUTONOMY_STOP_POLICY",
60
+ }
61
+ assert set(result.keys()) == expected_keys, f"full preset keys mismatch: {set(result.keys())} != {expected_keys}"
62
+
63
+
64
+ def test_us0119_explicit_flag_overrides_preset():
65
+ """AC-2: explicit per-flag > preset expansion (LOCKED precedence)."""
66
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
67
+ from autonomy_preset_lib import expand_autonomy_preset
68
+
69
+ result = expand_autonomy_preset("balanced", {"WORK_KIND_AUTO_ACCEPT": "0"})
70
+ assert result["WORK_KIND_AUTO_ACCEPT"] == "0", "explicit override MUST win over preset value"
71
+
72
+
73
+ def test_us0119_preset_expansion_uses_known_keys_only():
74
+ """AC-12: expansion output contains only keys in pre-US-0119 scratchpad schema (compose guard)."""
75
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
76
+ from autonomy_preset_lib import expand_autonomy_preset, AUTONOMY_FLAGS
77
+
78
+ for preset in ["none", "balanced", "full"]:
79
+ result = expand_autonomy_preset(preset)
80
+ unknown_keys = set(result.keys()) - AUTONOMY_FLAGS
81
+ assert not unknown_keys, f"preset={preset} expansion contains unknown keys: {unknown_keys}"
82
+
83
+
84
+ def test_us0119_matrix_validator_passes():
85
+ """AC-4: scripts/validate_autonomy_stop_matrix.py --self-test exits 0."""
86
+ import subprocess
87
+
88
+ validator_path = Path(__file__).parent.parent / "scripts" / "validate_autonomy_stop_matrix.py"
89
+ result = subprocess.run(
90
+ ["python", str(validator_path), "--self-test"],
91
+ capture_output=True,
92
+ text=True,
93
+ )
94
+ assert result.returncode == 0, f"validator --self-test MUST exit 0, got {result.returncode}\nstderr: {result.stderr}"
95
+
96
+
97
+ def test_us0119_security_hard_gates_never_auto_repaired():
98
+ """AC-7: matrix security_hard rows all carry auto_repair_kind=n/a."""
99
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
100
+ from validate_autonomy_stop_matrix import parse_yaml_matrix, REPO_ROOT
101
+
102
+ yaml_path = REPO_ROOT / "scripts" / "data" / "autonomy_stop_matrix.yaml"
103
+ matrix = parse_yaml_matrix(yaml_path)
104
+
105
+ for entry in matrix.get("reason_codes", []):
106
+ if entry.get("stop_class") == "security_hard":
107
+ assert entry.get("auto_repair_kind") == "n/a", (
108
+ f"security_hard code {entry['code']} MUST have auto_repair_kind=n/a, "
109
+ f"got {entry.get('auto_repair_kind')}"
110
+ )
111
+
112
+
113
+ def test_us0119_stop_policy_affects_repair_dispatch():
114
+ """AC-3: auto_repair_then_block vs auto_repair_then_skip dispatch correctly."""
115
+ # This test verifies the stop-policy dispatch logic is documented in scratchpad
116
+ # Actual dispatch happens at runtime based on AUTONOMY_STOP_POLICY value
117
+
118
+ scratchpad_path = Path(__file__).parent.parent / ".cursor" / "scratchpad.md"
119
+ content = scratchpad_path.read_text(encoding="utf-8")
120
+
121
+ assert "AUTONOMY_STOP_POLICY=" in content, "AUTONOMY_STOP_POLICY MUST be documented in scratchpad"
122
+ assert "block|" in content or "auto_repair_then_block|" in content, (
123
+ "AUTONOMY_STOP_POLICY MUST document block/auto_repair_then_block/auto_repair_then_skip enum"
124
+ )
125
+
126
+
127
+ def test_us0119_repair_ledger_cap_escalates():
128
+ """AC-8: cap exhaustion -> AUTONOMY_REPAIR_CAP_EXHAUSTED terminal stop."""
129
+ # This test verifies the terminal stop code is in the matrix
130
+
131
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
132
+ from validate_autonomy_stop_matrix import parse_yaml_matrix, REPO_ROOT
133
+
134
+ yaml_path = REPO_ROOT / "scripts" / "data" / "autonomy_stop_matrix.yaml"
135
+ matrix = parse_yaml_matrix(yaml_path)
136
+
137
+ reason_codes = {entry["code"]: entry for entry in matrix.get("reason_codes", [])}
138
+ assert "AUTONOMY_REPAIR_CAP_EXHAUSTED" in reason_codes, (
139
+ "AUTONOMY_REPAIR_CAP_EXHAUSTED terminal stop code MUST be in matrix"
140
+ )
141
+
142
+ terminal_entry = reason_codes["AUTONOMY_REPAIR_CAP_EXHAUSTED"]
143
+ assert terminal_entry["stop_class"] == "autonomy_resolvable", (
144
+ "AUTONOMY_REPAIR_CAP_EXHAUSTED MUST be autonomy_resolvable (bounded cap)"
145
+ )
146
+ assert terminal_entry["auto_repair_kind"] == "n/a", (
147
+ "AUTONOMY_REPAIR_CAP_EXHAUSTED MUST have auto_repair_kind=n/a (terminal)"
148
+ )
149
+ assert terminal_entry["cap"] == 0, (
150
+ "AUTONOMY_REPAIR_CAP_EXHAUSTED MUST have cap=0 (terminal stop)"
151
+ )
152
+
153
+
154
+ def test_us0119_matrix_no_orphan_codes():
155
+ """AC-4: no orphan reason codes outside YAML manifest."""
156
+ # This test is implicitly covered by test_us0119_matrix_validator_passes,
157
+ # which runs the validator's --self-test. If the validator passes, no orphan
158
+ # codes exist.
159
+
160
+ sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
161
+ from validate_autonomy_stop_matrix import self_test
162
+
163
+ passed, violations = self_test()
164
+ assert passed, f"validator self_test MUST pass, got violations: {violations}"
165
+
166
+
167
+ if __name__ == "__main__":
168
+ pytest.main([__file__, "-v"])