claude-dev-env 8.10.0 → 8.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_regression.py +85 -3
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_regression.py +34 -0
- package/_shared/pr-loop/scripts/fix_pr_test_proof.py +233 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/fix_pr_test_proof_constants.py +47 -0
- package/_shared/pr-loop/scripts/test_fix_pr_test_proof.py +186 -0
- package/bin/codex-skill-load-block.mjs +93 -0
- package/bin/codex-skill-load-block.test.mjs +134 -0
- package/bin/install.agents-home.test.mjs +76 -1
- package/bin/install.mjs +55 -31
- package/bin/install.test.mjs +57 -0
- package/bin/install.transaction.test.mjs +29 -7
- package/bin/seed-codex-pstack-models.mjs +27 -0
- package/bin/seed-codex-pstack-models.test.mjs +72 -0
- package/docs/CODE_RULES.md +5 -1
- package/hooks/blocking/code_rules_enforcer.py +1 -3
- package/hooks/blocking/code_rules_magic_values.py +1 -3
- package/hooks/blocking/code_rules_paired_test.py +5 -6
- package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +3 -3
- package/hooks/blocking/tdd_enforcer_parts/__init__.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_ephemeral.py +1 -46
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +2 -40
- package/hooks/blocking/tests/test_repository_exemption.py +7 -0
- package/hooks/followup_ledger.py +8 -1
- package/hooks/git-hooks/test_installed_policy_lint.py +4 -2
- package/hooks/hooks.json +15 -0
- package/hooks/hooks_constants/followup_ledger_constants.py +4 -0
- package/hooks/hooks_constants/messages.py +0 -1
- package/hooks/hooks_constants/nested_project_hooks_constants.py +37 -0
- package/hooks/hooks_constants/test_messages.py +1 -7
- package/hooks/lifecycle/nested_project_hooks.py +395 -0
- package/hooks/lifecycle/test_nested_project_hooks.py +251 -0
- package/hooks/test_followup_ledger.py +18 -0
- package/package.json +2 -1
- package/pstack-codex-models.md +37 -0
- package/rules/bdd.md +1 -1
- package/rules/build-needs-a-user.md +53 -0
- package/rules/code-standards.md +1 -1
- package/rules/flag-non-breaking-findings.md +7 -0
- package/rules/paired-test-coverage.md +4 -2
- package/rules/testing.md +5 -1
- package/scripts/cde_lint.py +47 -1
- package/scripts/policy_lint/adapter_callers.py +124 -0
- package/scripts/policy_lint/adapter_pairing.py +4 -2
- package/scripts/policy_lint/adapter_support.py +4 -3
- package/scripts/policy_lint/adapters.py +15 -0
- package/scripts/policy_lint/check_catalog.py +24 -0
- package/scripts/policy_lint/config/approved_test_pairs.py +3 -2
- package/scripts/policy_lint/config/check_catalog_constants.py +13 -0
- package/scripts/policy_lint/config/constants.py +18 -0
- package/scripts/policy_lint/engine.py +9 -3
- package/scripts/policy_lint/model.py +6 -2
- package/scripts/policy_lint/registry.py +6 -0
- package/scripts/policy_lint/selection.py +2 -0
- package/scripts/repository_checks/tracked_private_terms.py +15 -1
- package/scripts/tests/test_cde_lint.py +50 -0
- package/scripts/tests/test_policy_lint_rules_archive.py +16 -0
- package/scripts/tests/test_policy_lint_rules_callers.py +140 -0
- package/scripts/tests/test_policy_lint_rules_check_catalog.py +25 -1
- package/scripts/tests/test_policy_lint_rules_pairing.py +31 -2
- package/scripts/tests/test_policy_lint_selection.py +35 -0
- package/scripts/tests/test_tracked_private_terms.py +35 -0
- package/hooks/blocking/tdd_enforcer.py +0 -195
- package/hooks/blocking/tdd_enforcer_parts/candidate_paths.py +0 -142
- package/hooks/blocking/tdd_enforcer_parts/config/__init__.py +0 -1
- package/hooks/blocking/tdd_enforcer_parts/config/tdd_enforcer_constants.py +0 -49
- package/hooks/blocking/tdd_enforcer_parts/content_hash_store.py +0 -298
- package/hooks/blocking/tdd_enforcer_parts/decisions.py +0 -96
- package/hooks/blocking/tdd_enforcer_parts/freshness.py +0 -95
- package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +0 -132
- package/hooks/blocking/tdd_enforcer_parts/path_classification.py +0 -119
- package/hooks/blocking/tdd_enforcer_parts/tests/test_candidate_paths.py +0 -31
- package/hooks/blocking/tdd_enforcer_parts/tests/test_content_hash_store.py +0 -256
- package/hooks/blocking/tdd_enforcer_parts/tests/test_decisions.py +0 -46
- package/hooks/blocking/tdd_enforcer_parts/tests/test_freshness.py +0 -28
- package/hooks/blocking/tdd_enforcer_parts/tests/test_git_tracking.py +0 -111
- package/hooks/blocking/tdd_enforcer_parts/tests/test_path_classification.py +0 -36
- package/hooks/blocking/test_tdd_enforcer.py +0 -1506
- package/hooks/blocking/test_tdd_enforcer_restore.py +0 -108
- package/hooks/blocking/test_tdd_enforcer_scratchpad.py +0 -105
- package/scripts/codex_compat_watcher.py +0 -502
- package/scripts/tests/test_codex_compat_watcher.py +0 -599
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"""Behavioral tests for the git_tracking parts module."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import subprocess
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
|
|
7
|
-
from tdd_enforcer_parts import git_tracking
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def _git(repository_root: Path, *arguments: str) -> None:
|
|
11
|
-
subprocess.run(
|
|
12
|
-
["git", *arguments],
|
|
13
|
-
cwd=str(repository_root),
|
|
14
|
-
check=True,
|
|
15
|
-
capture_output=True,
|
|
16
|
-
env={**os.environ, "GIT_CONFIG_GLOBAL": os.devnull, "GIT_CONFIG_SYSTEM": os.devnull},
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def _init_repository(repository_root: Path) -> None:
|
|
21
|
-
_git(repository_root, "init", "-q")
|
|
22
|
-
_git(repository_root, "config", "user.email", "test@example.com")
|
|
23
|
-
_git(repository_root, "config", "user.name", "Test")
|
|
24
|
-
_git(repository_root, "config", "commit.gpgsign", "false")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def test_absent_but_tracked_true_after_committed_file_removed(tmp_path: Path) -> None:
|
|
28
|
-
_init_repository(tmp_path)
|
|
29
|
-
tracked = tmp_path / "service.py"
|
|
30
|
-
tracked.write_text("def serve(): return 1\n")
|
|
31
|
-
_git(tmp_path, "add", "-A")
|
|
32
|
-
_git(tmp_path, "commit", "-q", "-m", "init")
|
|
33
|
-
tracked.unlink()
|
|
34
|
-
assert git_tracking.is_absent_but_tracked(tracked) is True
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_absent_but_tracked_false_for_untracked_absent_file(tmp_path: Path) -> None:
|
|
38
|
-
_init_repository(tmp_path)
|
|
39
|
-
assert git_tracking.is_absent_but_tracked(tmp_path / "ghost.py") is False
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def test_absent_but_tracked_false_when_file_present(tmp_path: Path) -> None:
|
|
43
|
-
_init_repository(tmp_path)
|
|
44
|
-
present = tmp_path / "present.py"
|
|
45
|
-
present.write_text("def here(): return 1\n")
|
|
46
|
-
_git(tmp_path, "add", "-A")
|
|
47
|
-
_git(tmp_path, "commit", "-q", "-m", "init")
|
|
48
|
-
assert git_tracking.is_absent_but_tracked(present) is False
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def test_has_uncommitted_change_from_head_true_for_untracked_file(tmp_path: Path) -> None:
|
|
52
|
-
_init_repository(tmp_path)
|
|
53
|
-
untracked = tmp_path / "test_orders.py"
|
|
54
|
-
untracked.write_text("def test_fulfill(): pass\n")
|
|
55
|
-
assert git_tracking.has_uncommitted_change_from_head(untracked) is True
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def test_has_uncommitted_change_from_head_true_for_tracked_modified_file(tmp_path: Path) -> None:
|
|
59
|
-
_init_repository(tmp_path)
|
|
60
|
-
tracked = tmp_path / "test_orders.py"
|
|
61
|
-
tracked.write_text("def test_fulfill(): pass\n")
|
|
62
|
-
_git(tmp_path, "add", "-A")
|
|
63
|
-
_git(tmp_path, "commit", "-q", "-m", "init")
|
|
64
|
-
tracked.write_text("def test_fulfill(): assert True\n")
|
|
65
|
-
assert git_tracking.has_uncommitted_change_from_head(tracked) is True
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def test_has_uncommitted_change_from_head_false_for_tracked_clean_file(tmp_path: Path) -> None:
|
|
69
|
-
_init_repository(tmp_path)
|
|
70
|
-
tracked = tmp_path / "test_orders.py"
|
|
71
|
-
tracked.write_text("def test_fulfill(): pass\n")
|
|
72
|
-
_git(tmp_path, "add", "-A")
|
|
73
|
-
_git(tmp_path, "commit", "-q", "-m", "init")
|
|
74
|
-
tracked.touch()
|
|
75
|
-
assert git_tracking.has_uncommitted_change_from_head(tracked) is False
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def test_has_uncommitted_change_from_head_true_outside_a_git_repository(tmp_path: Path) -> None:
|
|
79
|
-
stray = tmp_path / "test_orders.py"
|
|
80
|
-
stray.write_text("def test_fulfill(): pass\n")
|
|
81
|
-
assert git_tracking.has_uncommitted_change_from_head(stray) is True
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def test_has_uncommitted_change_from_head_true_for_staged_new_file_never_committed(
|
|
85
|
-
tmp_path: Path,
|
|
86
|
-
) -> None:
|
|
87
|
-
"""A brand-new file only ``git add``-ed carries content HEAD never had.
|
|
88
|
-
|
|
89
|
-
Regression guard: comparing the working tree to the index (rather than to
|
|
90
|
-
HEAD) reads a freshly staged file as unchanged, since staging makes the
|
|
91
|
-
index match the working tree exactly. That misses every staged-but-never-
|
|
92
|
-
committed file, which is exactly how a RED-step test file is staged.
|
|
93
|
-
"""
|
|
94
|
-
_init_repository(tmp_path)
|
|
95
|
-
_git(tmp_path, "commit", "--allow-empty", "-q", "-m", "baseline")
|
|
96
|
-
staged_new_test = tmp_path / "test_orders.py"
|
|
97
|
-
staged_new_test.write_text("def test_fulfill(): pass\n")
|
|
98
|
-
_git(tmp_path, "add", "-A")
|
|
99
|
-
assert git_tracking.has_uncommitted_change_from_head(staged_new_test) is True
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def test_has_uncommitted_change_from_head_true_for_staged_modification(tmp_path: Path) -> None:
|
|
103
|
-
"""A tracked test's staged edit still differs from HEAD, not only the index."""
|
|
104
|
-
_init_repository(tmp_path)
|
|
105
|
-
tracked = tmp_path / "test_orders.py"
|
|
106
|
-
tracked.write_text("def test_fulfill(): pass\n")
|
|
107
|
-
_git(tmp_path, "add", "-A")
|
|
108
|
-
_git(tmp_path, "commit", "-q", "-m", "init")
|
|
109
|
-
tracked.write_text("def test_fulfill(): assert True\n")
|
|
110
|
-
_git(tmp_path, "add", "-A")
|
|
111
|
-
assert git_tracking.has_uncommitted_change_from_head(tracked) is True
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"""Behavioral tests for the path_classification parts module."""
|
|
2
|
-
|
|
3
|
-
from tdd_enforcer_parts import path_classification
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test_production_extensions_includes_python_and_typescript() -> None:
|
|
7
|
-
extensions = path_classification.production_extensions()
|
|
8
|
-
assert ".py" in extensions
|
|
9
|
-
assert ".tsx" in extensions
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_skip_extensions_includes_markdown_and_json() -> None:
|
|
13
|
-
extensions = path_classification.skip_extensions()
|
|
14
|
-
assert ".md" in extensions
|
|
15
|
-
assert ".json" in extensions
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def test_is_inside_dotclaude_segment_matches_exact_segment_only() -> None:
|
|
19
|
-
assert path_classification._is_inside_dotclaude_segment("/home/user/.claude/agent.py") is True
|
|
20
|
-
assert path_classification._is_inside_dotclaude_segment("/src/my.claude.helpers.py") is False
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def test_matches_any_skip_pattern_flags_test_file_names() -> None:
|
|
24
|
-
assert (
|
|
25
|
-
path_classification._matches_any_skip_pattern("test_orders.py", "pkg/test_orders.py")
|
|
26
|
-
is True
|
|
27
|
-
)
|
|
28
|
-
assert path_classification._matches_any_skip_pattern("orders.py", "pkg/orders.py") is False
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def test_extract_written_content_reads_write_and_multiedit() -> None:
|
|
32
|
-
assert path_classification._extract_written_content("Write", {"content": "x"}) == "x"
|
|
33
|
-
joined = path_classification._extract_written_content(
|
|
34
|
-
"MultiEdit", {"edits": [{"new_string": "a"}, {"new_string": "b"}]}
|
|
35
|
-
)
|
|
36
|
-
assert joined == "a\nb"
|