claude-dev-env 2.36.0 → 4.1.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/.agents/skills/_shared/advisor/scripts/README.md +1 -1
- package/.agents/skills/syncing-submodules/SKILL.md +101 -0
- package/.agents/skills/syncing-submodules/reference/run-tasks.md +9 -0
- package/.agents/skills/syncing-submodules/scripts/submodule_sync.py +383 -0
- package/.agents/skills/syncing-submodules/scripts/submodule_sync_constants/__init__.py +1 -0
- package/.agents/skills/syncing-submodules/scripts/submodule_sync_constants/config/__init__.py +1 -0
- package/.agents/skills/syncing-submodules/scripts/submodule_sync_constants/config/constants.py +66 -0
- package/.agents/skills/syncing-submodules/scripts/sync_parent_pointer.py +88 -0
- package/.agents/skills/syncing-submodules/scripts/test_submodule_sync.py +303 -0
- package/.agents/skills/syncing-submodules/scripts/test_sync_parent_pointer.py +83 -0
- package/.agents/skills/team-advisor/SKILL.md +11 -11
- package/_shared/advisor/advisor-protocol.md +51 -51
- package/_shared/advisor/reference/advisor-block.md +9 -9
- package/_shared/advisor/reference/astra-rung.md +39 -0
- package/_shared/advisor/reference/identity.md +4 -4
- package/_shared/advisor/reference/lifecycle.md +6 -6
- package/_shared/advisor/reference/spawn-walk-log.md +9 -9
- package/_shared/advisor/reference/third-party-bind.md +11 -11
- package/_shared/advisor/reference/warm-up.md +13 -13
- package/_shared/advisor/scripts/codex_astra_advisor.py +308 -0
- package/_shared/advisor/scripts/codex_astra_preflight.py +115 -0
- package/_shared/advisor/scripts/codex_astra_reply.py +159 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/advisor_route_constants.py +3 -3
- package/_shared/advisor/scripts/config/advisor_scripts_constants/astra_advisor_constants.py +38 -0
- package/_shared/advisor/scripts/model_tier_run_validator.py +17 -18
- package/_shared/advisor/scripts/tests/test_codex_astra_advisor.py +271 -0
- package/_shared/advisor/scripts/tests/test_codex_astra_preflight.py +24 -0
- package/_shared/advisor/scripts/tests/test_codex_astra_reply.py +42 -0
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +55 -30
- package/_shared/advisor/scripts/tests/test_tier_model_ids.py +14 -4
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +14 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +138 -50
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +13 -1
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/ever-shipped-skills.test.mjs +30 -0
- package/bin/git_hooks_installer.mjs +0 -1
- package/bin/git_hooks_installer.test.mjs +16 -1
- package/bin/install.mjs +5 -2
- package/bin/install.prune.test.mjs +36 -24
- package/bin/install.test.mjs +7 -0
- package/docs/references/team-advisor-skill.md +3 -3
- package/hooks/validators/README.md +35 -1
- package/package.json +1 -1
- package/scripts/check.ps1 +18 -6
- package/scripts/policy_lint/adapter_detectors.py +42 -2
- package/scripts/policy_lint/adapters.py +24 -0
- package/scripts/policy_lint/config/constants.py +11 -0
- package/scripts/policy_lint/engine.py +1 -1
- package/scripts/policy_lint/model.py +1 -0
- package/scripts/policy_lint/registry.py +10 -1
- package/scripts/repository_checks/__init__.py +1 -0
- package/scripts/repository_checks/claude_md.py +108 -0
- package/scripts/repository_checks/config/__init__.py +1 -0
- package/scripts/repository_checks/config/constants.py +150 -0
- package/scripts/repository_checks/env_var_documentation.py +243 -0
- package/scripts/repository_checks/hook_modules.py +34 -0
- package/scripts/repository_checks/models.py +37 -0
- package/scripts/repository_checks/package_inventory.py +118 -0
- package/scripts/repository_checks/pytest_testpaths.py +84 -0
- package/scripts/repository_checks/reporting.py +39 -0
- package/scripts/repository_checks/runner.py +93 -0
- package/scripts/repository_checks/tracked_secrets.py +147 -0
- package/scripts/repository_checks/tracked_tree.py +28 -0
- package/scripts/repository_policy.py +120 -0
- package/scripts/tests/repository_policy_test_support.py +89 -0
- package/scripts/tests/test_cde_lint.py +25 -1
- package/scripts/tests/test_claude_md.py +68 -0
- package/scripts/tests/test_env_var_documentation.py +133 -0
- package/scripts/tests/test_hook_modules.py +17 -0
- package/scripts/tests/test_models.py +26 -0
- package/scripts/tests/test_package_inventory.py +96 -0
- package/scripts/tests/test_policy_lint_rules_registry.py +117 -0
- package/scripts/tests/test_pytest_testpaths.py +66 -0
- package/scripts/tests/test_reporting.py +54 -0
- package/scripts/tests/test_repository_policy.py +71 -0
- package/scripts/tests/test_runner.py +59 -0
- package/scripts/tests/test_tracked_secrets.py +175 -0
- package/scripts/tests/test_tracked_tree.py +28 -0
- package/_shared/advisor/reference/sol-rung.md +0 -39
- package/_shared/advisor/scripts/codex_sol_advisor.py +0 -581
- package/_shared/advisor/scripts/config/advisor_scripts_constants/sol_advisor_constants.py +0 -38
- package/_shared/advisor/scripts/tests/test_codex_sol_advisor.py +0 -740
- package/hooks/git-hooks/post_commit.py +0 -241
- package/hooks/git-hooks/test_post_commit.py +0 -298
package/scripts/check.ps1
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env pwsh
|
|
2
2
|
<#
|
|
3
3
|
.SYNOPSIS
|
|
4
|
-
One-shot quality gate
|
|
5
|
-
process-tree mypy, and the blocking pytest suite from a
|
|
4
|
+
One-shot quality gate. Runs ruff, hooks mypy, pr-loop mypy,
|
|
5
|
+
process-tree mypy, repository-policy, and the blocking pytest suite from a
|
|
6
|
+
single entry point.
|
|
6
7
|
|
|
7
8
|
.DESCRIPTION
|
|
8
9
|
Resolves paths relative to $PSScriptRoot so the script works from any CWD
|
|
@@ -11,9 +12,10 @@
|
|
|
11
12
|
propagates this file). Tools: ruff over hooks/, mypy over hooks blocking
|
|
12
13
|
and validators, mypy-pr-loop over _shared/pr-loop/scripts production
|
|
13
14
|
modules, mypy-process-tree over the shared process-tree kill helper and
|
|
14
|
-
its constants,
|
|
15
|
-
|
|
16
|
-
script's exit code so CI
|
|
15
|
+
its constants, repository-policy over the committed tree, and optional
|
|
16
|
+
pytest over the blocking enforcer suite. Each tool runs in sequence. The
|
|
17
|
+
first non-zero exit code is preserved as the script's exit code so CI and
|
|
18
|
+
pre-commit can stop on the first failure.
|
|
17
19
|
|
|
18
20
|
.PARAMETER SkipTests
|
|
19
21
|
Skip the pytest run. Useful during local iteration when you want only the
|
|
@@ -25,19 +27,23 @@
|
|
|
25
27
|
.PARAMETER SkipRuff
|
|
26
28
|
Skip the ruff run.
|
|
27
29
|
|
|
30
|
+
.PARAMETER SkipRepositoryPolicy
|
|
31
|
+
Skip the committed-tree repository_policy.py run.
|
|
32
|
+
|
|
28
33
|
.PARAMETER CommentPolicyBase
|
|
29
34
|
Optional git reference used as the comment-policy baseline.
|
|
30
35
|
|
|
31
36
|
.OUTPUTS
|
|
32
37
|
Per-tool status lines on stdout. Final summary line:
|
|
33
38
|
CHECK: OK
|
|
34
|
-
CHECK: FAILED tools=ruff,mypy,mypy-pr-loop,mypy-process-tree,pytest
|
|
39
|
+
CHECK: FAILED tools=ruff,repository-policy,mypy,mypy-pr-loop,mypy-process-tree,pytest
|
|
35
40
|
#>
|
|
36
41
|
[CmdletBinding()]
|
|
37
42
|
param(
|
|
38
43
|
[switch]$SkipTests,
|
|
39
44
|
[switch]$SkipMypy,
|
|
40
45
|
[switch]$SkipRuff,
|
|
46
|
+
[switch]$SkipRepositoryPolicy,
|
|
41
47
|
[string]$CommentPolicyBase
|
|
42
48
|
)
|
|
43
49
|
|
|
@@ -121,6 +127,12 @@ Invoke-Tool -Label 'comment-policy' -Action {
|
|
|
121
127
|
}
|
|
122
128
|
}
|
|
123
129
|
|
|
130
|
+
if (-not $SkipRepositoryPolicy) {
|
|
131
|
+
Invoke-Tool -Label 'repository-policy' -Action {
|
|
132
|
+
python (Join-Path $PSScriptRoot 'repository_policy.py') --repository-root $repositoryRoot
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
124
136
|
if (-not $SkipMypy) {
|
|
125
137
|
Invoke-Tool -Label 'mypy' -Action {
|
|
126
138
|
Push-Location $hooksRoot
|
|
@@ -3,11 +3,51 @@ from __future__ import annotations
|
|
|
3
3
|
from collections.abc import Iterable
|
|
4
4
|
from contextlib import redirect_stderr, redirect_stdout
|
|
5
5
|
from io import StringIO
|
|
6
|
-
from pathlib import Path
|
|
6
|
+
from pathlib import Path, PurePosixPath
|
|
7
7
|
|
|
8
8
|
from . import adapter_support
|
|
9
9
|
from .config import constants
|
|
10
|
-
from .model import Diagnostic, Document
|
|
10
|
+
from .model import Diagnostic, Document, DocumentSet, Location, SelectionKind, Severity
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _terminology_diagnostic(finding: str) -> Diagnostic:
|
|
14
|
+
finding_match = constants.TERMINOLOGY_FINDING_PATTERN.fullmatch(finding)
|
|
15
|
+
if finding_match is None:
|
|
16
|
+
raise ValueError(finding)
|
|
17
|
+
return Diagnostic(
|
|
18
|
+
constants.TERMINOLOGY_SWEEP_RULE_ID,
|
|
19
|
+
Severity.ERROR,
|
|
20
|
+
finding_match.group(constants.TERMINOLOGY_MESSAGE_GROUP),
|
|
21
|
+
Location(
|
|
22
|
+
PurePosixPath(finding_match.group(constants.TERMINOLOGY_PATH_GROUP)),
|
|
23
|
+
int(finding_match.group(constants.TERMINOLOGY_LINE_NUMBER_GROUP)),
|
|
24
|
+
),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def terminology_diagnostics(
|
|
29
|
+
document_set: DocumentSet,
|
|
30
|
+
load_module: adapter_support.HookModuleLoader,
|
|
31
|
+
) -> tuple[Diagnostic, ...]:
|
|
32
|
+
"""Report staged prose that near-misses a newly introduced identifier.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
document_set: Candidate staged documents and repository root.
|
|
36
|
+
load_module: Shared script module loader.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Diagnostics that name the prose file and line.
|
|
40
|
+
"""
|
|
41
|
+
if document_set.selection is not SelectionKind.STAGED:
|
|
42
|
+
return ()
|
|
43
|
+
terminology_module = load_module(constants.TERMINOLOGY_SWEEP_MODULE_NAME)
|
|
44
|
+
helper_stdout = StringIO()
|
|
45
|
+
helper_stderr = StringIO()
|
|
46
|
+
with redirect_stdout(helper_stdout), redirect_stderr(helper_stderr):
|
|
47
|
+
all_findings = terminology_module.strict_staged_terminology_findings(
|
|
48
|
+
document_set.repository_root
|
|
49
|
+
)
|
|
50
|
+
return tuple(_terminology_diagnostic(each_finding) for each_finding in all_findings)
|
|
11
51
|
|
|
12
52
|
|
|
13
53
|
def _stable_validator_message(document: Document, raw_message: str) -> str:
|
|
@@ -23,6 +23,16 @@ def _hooks_module(module_name: str) -> ModuleType:
|
|
|
23
23
|
return importlib.import_module(module_name)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def _pr_loop_script_module(module_name: str) -> ModuleType:
|
|
27
|
+
package_directory = Path(__file__).resolve().parent.parent.parent
|
|
28
|
+
scripts_directory = str(
|
|
29
|
+
package_directory.joinpath(*constants.ALL_PR_LOOP_SCRIPTS_PATH_SEGMENTS)
|
|
30
|
+
)
|
|
31
|
+
if scripts_directory not in sys.path:
|
|
32
|
+
sys.path.insert(0, scripts_directory)
|
|
33
|
+
return importlib.import_module(module_name)
|
|
34
|
+
|
|
35
|
+
|
|
26
36
|
def validator_diagnostics(
|
|
27
37
|
document: Document, repository_root: Path
|
|
28
38
|
) -> tuple[Diagnostic, ...]:
|
|
@@ -222,6 +232,20 @@ def test_pairing_diagnostics(document_set: DocumentSet) -> tuple[Diagnostic, ...
|
|
|
222
232
|
return adapter_pairing.test_pairing_diagnostics(document_set, _hooks_module)
|
|
223
233
|
|
|
224
234
|
|
|
235
|
+
def terminology_diagnostics(document_set: DocumentSet) -> tuple[Diagnostic, ...]:
|
|
236
|
+
"""Report staged prose that near-misses a newly introduced identifier.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
document_set: Candidate staged documents and repository root.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Diagnostics that name the prose file and line.
|
|
243
|
+
"""
|
|
244
|
+
return adapter_detectors.terminology_diagnostics(
|
|
245
|
+
document_set, _pr_loop_script_module
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
225
249
|
def hook_format_diagnostics(
|
|
226
250
|
document: Document, repository_root: Path
|
|
227
251
|
) -> tuple[Diagnostic, ...]:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
1
3
|
INCOMPLETE_EXIT_CODE = 3
|
|
2
4
|
INVALID_INPUT_EXIT_CODE = 2
|
|
3
5
|
GIT_EXECUTABLE = "git"
|
|
@@ -64,3 +66,12 @@ FAST_SAVE_VALIDATORS_STEM = "fast_save_validators"
|
|
|
64
66
|
ALL_OVERLAPPING_VALIDATOR_NAMES = frozenset(
|
|
65
67
|
{"Python Style", "Magic Values", "Type Safety", "Test Safety", "React"}
|
|
66
68
|
)
|
|
69
|
+
ALL_PR_LOOP_SCRIPTS_PATH_SEGMENTS = ("_shared", "pr-loop", "scripts")
|
|
70
|
+
TERMINOLOGY_SWEEP_MODULE_NAME = "terminology_sweep"
|
|
71
|
+
TERMINOLOGY_SWEEP_RULE_ID = "terminology-sweep"
|
|
72
|
+
TERMINOLOGY_FINDING_PATTERN = re.compile(
|
|
73
|
+
r"^(?P<path>.+):(?P<line_number>\d+): (?P<message>.+)$"
|
|
74
|
+
)
|
|
75
|
+
TERMINOLOGY_PATH_GROUP = "path"
|
|
76
|
+
TERMINOLOGY_LINE_NUMBER_GROUP = "line_number"
|
|
77
|
+
TERMINOLOGY_MESSAGE_GROUP = "message"
|
|
@@ -180,7 +180,7 @@ def _run_changeset_rule(
|
|
|
180
180
|
all_diagnostics: list[Diagnostic],
|
|
181
181
|
all_skipped_rules: list[str],
|
|
182
182
|
) -> None:
|
|
183
|
-
if document_set.selection not in
|
|
183
|
+
if document_set.selection not in rule.selections:
|
|
184
184
|
all_skipped_rules.append(rule.rule_id)
|
|
185
185
|
return
|
|
186
186
|
all_diagnostics.extend(rule.check(document_set))
|
|
@@ -133,7 +133,16 @@ def default_registry() -> tuple[model.Rule, ...]:
|
|
|
133
133
|
*_text_document_rules(),
|
|
134
134
|
*_configuration_document_rules(),
|
|
135
135
|
model.ChangeSetRule(
|
|
136
|
-
"test-pairing",
|
|
136
|
+
"test-pairing",
|
|
137
|
+
frozenset({"changed"}),
|
|
138
|
+
frozenset({model.SelectionKind.STAGED, model.SelectionKind.BASE}),
|
|
139
|
+
adapters.test_pairing_diagnostics,
|
|
140
|
+
),
|
|
141
|
+
model.ChangeSetRule(
|
|
142
|
+
"terminology-sweep",
|
|
143
|
+
frozenset({"changed"}),
|
|
144
|
+
frozenset({model.SelectionKind.STAGED}),
|
|
145
|
+
adapters.terminology_diagnostics,
|
|
137
146
|
),
|
|
138
147
|
model.RepositoryRule(
|
|
139
148
|
"repository-path-collision",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Committed-tree repository checks used by the repository_policy command."""
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""CLAUDE.md reference checks for committed trees."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections import deque
|
|
6
|
+
from collections.abc import Sequence
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from types import ModuleType
|
|
9
|
+
|
|
10
|
+
from policy_lint.config.constants import PATH_SEPARATOR, UTF8_ENCODING
|
|
11
|
+
|
|
12
|
+
from repository_checks.config.constants import (
|
|
13
|
+
CHECK_ID_CLAUDE_MD_ORPHANS,
|
|
14
|
+
CLAUDE_MD_CONSTANTS_MODULE_NAME,
|
|
15
|
+
CLAUDE_MD_MISSING_FILE_MESSAGE_TEMPLATE,
|
|
16
|
+
CLAUDE_MD_SCAN_MODULE_NAME,
|
|
17
|
+
WINDOWS_PATH_SEPARATOR,
|
|
18
|
+
)
|
|
19
|
+
from repository_checks.hook_modules import load_hooks_module
|
|
20
|
+
from repository_checks.models import RepositoryFinding
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def collect_claude_md_orphan_findings(
|
|
24
|
+
repository_root: Path, all_tracked_paths: Sequence[str]
|
|
25
|
+
) -> list[RepositoryFinding]:
|
|
26
|
+
"""Return missing CLAUDE.md references in the tracked tree.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
repository_root: Git repository root.
|
|
30
|
+
all_tracked_paths: Repository-relative tracked paths.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Findings for references whose files are absent.
|
|
34
|
+
"""
|
|
35
|
+
subtree_scan = load_hooks_module(CLAUDE_MD_SCAN_MODULE_NAME)
|
|
36
|
+
claude_md_constants = load_hooks_module(CLAUDE_MD_CONSTANTS_MODULE_NAME)
|
|
37
|
+
all_findings: list[RepositoryFinding] = []
|
|
38
|
+
for each_relative_path in all_tracked_paths:
|
|
39
|
+
all_findings.extend(
|
|
40
|
+
find_orphan_findings_for_path(
|
|
41
|
+
repository_root,
|
|
42
|
+
each_relative_path,
|
|
43
|
+
subtree_scan,
|
|
44
|
+
claude_md_constants,
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
return all_findings
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def find_orphan_findings_for_path(
|
|
51
|
+
repository_root: Path,
|
|
52
|
+
relative_path: str,
|
|
53
|
+
subtree_scan: ModuleType,
|
|
54
|
+
claude_md_constants: ModuleType,
|
|
55
|
+
) -> list[RepositoryFinding]:
|
|
56
|
+
"""Return missing files named by one CLAUDE.md file.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
repository_root: Git repository root.
|
|
60
|
+
relative_path: Repository-relative path to inspect.
|
|
61
|
+
subtree_scan: Existing reference detector module.
|
|
62
|
+
claude_md_constants: Existing detector constants module.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Findings for referenced files that are absent from the scan root.
|
|
66
|
+
"""
|
|
67
|
+
if Path(relative_path).name != claude_md_constants.CLAUDE_MD_FILENAME:
|
|
68
|
+
return []
|
|
69
|
+
absolute_path = repository_root / relative_path
|
|
70
|
+
if not absolute_path.is_file():
|
|
71
|
+
return []
|
|
72
|
+
return _find_orphans_in_claude_md(absolute_path, relative_path, subtree_scan)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _find_orphans_in_claude_md(
|
|
76
|
+
absolute_path: Path,
|
|
77
|
+
relative_path: str,
|
|
78
|
+
subtree_scan: ModuleType,
|
|
79
|
+
) -> list[RepositoryFinding]:
|
|
80
|
+
content = absolute_path.read_text(encoding=UTF8_ENCODING)
|
|
81
|
+
claude_md_directory = absolute_path.parent
|
|
82
|
+
subtree_root = _subtree_root_for(claude_md_directory)
|
|
83
|
+
subtree_root.stat()
|
|
84
|
+
deque(subtree_root.rglob("*"), maxlen=0)
|
|
85
|
+
all_missing_filenames = subtree_scan.find_missing_filenames(
|
|
86
|
+
content, claude_md_directory
|
|
87
|
+
)
|
|
88
|
+
return _build_findings(relative_path, all_missing_filenames)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _subtree_root_for(claude_md_directory: Path) -> Path:
|
|
92
|
+
parent_directory = claude_md_directory.parent
|
|
93
|
+
if parent_directory == claude_md_directory:
|
|
94
|
+
return claude_md_directory
|
|
95
|
+
return parent_directory
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _build_findings(
|
|
99
|
+
relative_path: str, all_missing_filenames: Sequence[str]
|
|
100
|
+
) -> list[RepositoryFinding]:
|
|
101
|
+
return [
|
|
102
|
+
RepositoryFinding(
|
|
103
|
+
CHECK_ID_CLAUDE_MD_ORPHANS,
|
|
104
|
+
relative_path.replace(WINDOWS_PATH_SEPARATOR, PATH_SEPARATOR),
|
|
105
|
+
CLAUDE_MD_MISSING_FILE_MESSAGE_TEMPLATE.format(filename=each_filename),
|
|
106
|
+
)
|
|
107
|
+
for each_filename in all_missing_filenames
|
|
108
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Configuration for the committed-tree repository checker."""
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""Stable identifiers, report tokens, and committed-tree exemption tables."""
|
|
2
|
+
|
|
3
|
+
from policy_lint.config.constants import (
|
|
4
|
+
GIT_FILES_ARGUMENT,
|
|
5
|
+
GIT_ZERO_TERMINATED_FLAG,
|
|
6
|
+
INCOMPLETE_EXIT_CODE,
|
|
7
|
+
INVALID_INPUT_EXIT_CODE,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
CHECK_ID_CLAUDE_MD_ORPHANS = "claude-md-orphans"
|
|
11
|
+
CHECK_ID_ENV_VAR_DOCUMENTATION = "env-var-documentation"
|
|
12
|
+
CHECK_ID_PACKAGE_INVENTORY = "package-inventory"
|
|
13
|
+
CHECK_ID_PYTEST_TESTPATHS = "pytest-testpaths"
|
|
14
|
+
CHECK_ID_TRACKED_PERSONAL_DATA = "tracked-secrets"
|
|
15
|
+
|
|
16
|
+
ALL_CHECK_IDS = (
|
|
17
|
+
CHECK_ID_CLAUDE_MD_ORPHANS,
|
|
18
|
+
CHECK_ID_ENV_VAR_DOCUMENTATION,
|
|
19
|
+
CHECK_ID_PACKAGE_INVENTORY,
|
|
20
|
+
CHECK_ID_PYTEST_TESTPATHS,
|
|
21
|
+
CHECK_ID_TRACKED_PERSONAL_DATA,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
SUCCESS_EXIT_CODE = 0
|
|
25
|
+
FINDINGS_EXIT_CODE = 1
|
|
26
|
+
FAILED_CHECK_EXIT_CODE = INCOMPLETE_EXIT_CODE
|
|
27
|
+
USAGE_EXIT_CODE = INVALID_INPUT_EXIT_CODE
|
|
28
|
+
|
|
29
|
+
REPOSITORY_ROOT_FLAG = "--repository-root"
|
|
30
|
+
FINDING_LINE_TEMPLATE = "{check_id}: {relative_path}: {message}"
|
|
31
|
+
RULE_FAILED_LINE_TEMPLATE = "error: rule failed: {check_id}"
|
|
32
|
+
REPORT_LINE_SEPARATOR = "\n"
|
|
33
|
+
EMPTY_REPORT_TEXT = ""
|
|
34
|
+
TRACKED_MATCH_MESSAGE_TEMPLATE = "[{category}] {preview}"
|
|
35
|
+
CLAUDE_MD_MISSING_FILE_MESSAGE_TEMPLATE = "references missing file {filename}"
|
|
36
|
+
PACKAGE_INVENTORY_MESSAGE_TEMPLATE = "production file is absent from package inventory"
|
|
37
|
+
PYTEST_TESTPATH_MESSAGE_TEMPLATE = (
|
|
38
|
+
"test file is outside the package testpaths allowlist"
|
|
39
|
+
)
|
|
40
|
+
ALL_GIT_LS_FILES_ARGUMENTS = (GIT_FILES_ARGUMENT, GIT_ZERO_TERMINATED_FLAG)
|
|
41
|
+
PYPROJECT_FILENAME = "pyproject.toml"
|
|
42
|
+
WINDOWS_PATH_SEPARATOR = "\\"
|
|
43
|
+
|
|
44
|
+
CLAUDE_MD_SCAN_MODULE_NAME = "blocking.claude_md_orphan_file_blocker_parts.subtree_scan"
|
|
45
|
+
CLAUDE_MD_CONSTANTS_MODULE_NAME = (
|
|
46
|
+
"hooks_constants.claude_md_orphan_file_blocker_constants"
|
|
47
|
+
)
|
|
48
|
+
ENV_VAR_DRIFT_MODULE_NAME = "blocking.env_var_table_code_drift_blocker"
|
|
49
|
+
ENV_VAR_DRIFT_CONSTANTS_MODULE_NAME = (
|
|
50
|
+
"hooks_constants.env_var_table_code_drift_constants"
|
|
51
|
+
)
|
|
52
|
+
PACKAGE_INVENTORY_DETECTION_MODULE_NAME = (
|
|
53
|
+
"blocking.package_inventory_stale_blocker_parts.inventory_detection"
|
|
54
|
+
)
|
|
55
|
+
PACKAGE_INVENTORY_CONSTANTS_MODULE_NAME = (
|
|
56
|
+
"hooks_constants.package_inventory_stale_blocker_constants"
|
|
57
|
+
)
|
|
58
|
+
PYTEST_TESTPATHS_MODULE_NAME = "blocking.pytest_testpaths_orphan_blocker"
|
|
59
|
+
PII_SCANNER_MODULE_NAME = "blocking.pii_scanner"
|
|
60
|
+
REPOSITORY_EXEMPTION_MODULE_NAME = (
|
|
61
|
+
"blocking.pii_prevention_blocker_parts.repository_exemption"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
ALL_FAIL_CLOSED_EXCEPTION_TYPES = (
|
|
65
|
+
AttributeError,
|
|
66
|
+
ImportError,
|
|
67
|
+
KeyError,
|
|
68
|
+
OSError,
|
|
69
|
+
RuntimeError,
|
|
70
|
+
SyntaxError,
|
|
71
|
+
TypeError,
|
|
72
|
+
UnicodeError,
|
|
73
|
+
ValueError,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
ALL_ARCHIVED_SKILL_DIRECTORY_SEGMENTS = (".agents", "skills-archived")
|
|
77
|
+
ALL_TRACKED_SECRET_EXACT_EXEMPTIONS: frozenset[tuple[str, str, str]] = frozenset(
|
|
78
|
+
(
|
|
79
|
+
(
|
|
80
|
+
"packages/claude-dev-env/.agents/skills-archived/pr-converge/reference/per-tick.md",
|
|
81
|
+
"email",
|
|
82
|
+
"3de132cd98be7bf26b6f08e81c31c799a891bc32046b61f0b6fe3671ca2e44b5",
|
|
83
|
+
),
|
|
84
|
+
(
|
|
85
|
+
"packages/claude-dev-env/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml",
|
|
86
|
+
"home-path",
|
|
87
|
+
"805e3271caeec55a94438e221726e9349e46fa4970592bd03ffd3adac5e0ea8a",
|
|
88
|
+
),
|
|
89
|
+
(
|
|
90
|
+
"packages/claude-dev-env/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py",
|
|
91
|
+
"home-path",
|
|
92
|
+
"a4f1f978f88b601288424144a5f5066cdc9154868cf2aaab6e0869a103be72a5",
|
|
93
|
+
),
|
|
94
|
+
(
|
|
95
|
+
"packages/claude-dev-env/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py",
|
|
96
|
+
"home-path",
|
|
97
|
+
"665e48f1b198dd2a6526e25700fbcb86566d1f8b47d4475a6cc318b1634a4546",
|
|
98
|
+
),
|
|
99
|
+
(
|
|
100
|
+
"packages/claude-dev-env/_shared/pr-loop/scripts/_claude_permissions_common.py",
|
|
101
|
+
"home-path",
|
|
102
|
+
"9c48917645524d03ea0a4f4d8755aa8f0d59f3108e1aa976202a02e613c1444d",
|
|
103
|
+
),
|
|
104
|
+
(
|
|
105
|
+
"packages/claude-dev-env/_shared/pr-loop/scripts/_claude_permissions_common.py",
|
|
106
|
+
"home-path",
|
|
107
|
+
"07ba214cb23325675bc68e5513c030e968eccf2760cb5917d932ae5da29d5af1",
|
|
108
|
+
),
|
|
109
|
+
(
|
|
110
|
+
"packages/claude-dev-env/_shared/pr-loop/scripts/_claude_permissions_common.py",
|
|
111
|
+
"home-path",
|
|
112
|
+
"d41ce8d0f21de2d5320bdd8cd4e8693a2f3d6ea59db6df5ea102a7d2be4b2c22",
|
|
113
|
+
),
|
|
114
|
+
(
|
|
115
|
+
"packages/claude-dev-env/audit-rubrics/prompts/category-n-test-name-scenario-verifier.md",
|
|
116
|
+
"home-path",
|
|
117
|
+
"550c7b16a2a04e1d05a8a6b4f5b764b8d4fdef65e9d79d09e5dbb3a15a855812",
|
|
118
|
+
),
|
|
119
|
+
(
|
|
120
|
+
"packages/claude-dev-env/audit-rubrics/prompts/category-n-test-name-scenario-verifier.md",
|
|
121
|
+
"home-path",
|
|
122
|
+
"b8bbdd1a7ebdad16f4e51377a3f21d05dd35992d89e35971b28b05f53245c69d",
|
|
123
|
+
),
|
|
124
|
+
(
|
|
125
|
+
"packages/claude-dev-env/bin/expand_home_directory_tokens.mjs",
|
|
126
|
+
"home-path",
|
|
127
|
+
"10d5571e7126d2018ee7fb06aa29c72a9d503cac79a4e52d6848602ee10e8832",
|
|
128
|
+
),
|
|
129
|
+
(
|
|
130
|
+
"packages/claude-dev-env/bin/expand_home_directory_tokens.mjs",
|
|
131
|
+
"home-path",
|
|
132
|
+
"09f83c224a02c370d3d63de5c330e1a830fc92866330fc7963b5b5fd20ffcb91",
|
|
133
|
+
),
|
|
134
|
+
(
|
|
135
|
+
"packages/claude-dev-env/hooks/blocking/volatile_path_in_post_blocker.py",
|
|
136
|
+
"home-path",
|
|
137
|
+
"ed9203c8078e4c6b832600085f28f24656d679aa8dca82ecc2557afc3df25036",
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
"packages/claude-dev-env/hooks/hooks_constants/hardcoded_user_path_constants.py",
|
|
141
|
+
"home-path",
|
|
142
|
+
"0967160658d782c558722232cad7d47dc19267943d4667b41d3eff1e605be2f4",
|
|
143
|
+
),
|
|
144
|
+
(
|
|
145
|
+
"packages/claude-dev-env/hooks/hooks_constants/hardcoded_user_path_constants.py",
|
|
146
|
+
"home-path",
|
|
147
|
+
"a541acfac2e649581bca0cd03e4c3dcf306344915017d9cd6be4ad57a8fd7379",
|
|
148
|
+
),
|
|
149
|
+
)
|
|
150
|
+
)
|