claude-dev-env 2.28.1 → 2.30.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/agents/AGENTS.md +0 -31
- package/.agents/agents/clean-coder.md +1 -1
- package/.agents/agents/pr-description-writer.md +21 -6
- package/.agents/agents/reference/README.md +6 -0
- package/.agents/agents/reference/pr-description-illustrative-voice.md +45 -0
- package/.agents/agents/reference/pr-description-verification.md +19 -0
- package/.agents/agents/test_agent_frontmatter.py +3 -1
- package/.agents/agents/test_pr_description_writer_style.py +47 -0
- package/.agents/skills/AGENTS.md +0 -70
- package/.agents/skills/_shared/AGENTS.md +0 -44
- package/.agents/skills/_shared/advisor/AGENTS.md +0 -8
- package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -57
- package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -8
- package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -34
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -23
- package/.agents/skills/autoconverge/AGENTS.md +0 -35
- package/.agents/skills/autoconverge/reference/AGENTS.md +0 -15
- package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -25
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -15
- package/.agents/skills/everything-search/AGENTS.md +0 -16
- package/.agents/skills/fresh-branch/AGENTS.md +0 -13
- package/.agents/skills/grok-spawn/AGENTS.md +0 -27
- package/.agents/skills/orchestrator/.claude/CLAUDE.md +1 -0
- package/.agents/skills/orchestrator/AGENTS.md +1 -0
- package/.agents/skills/orchestrator/SKILL.md +44 -53
- package/.agents/skills/orchestrator/reference/.claude/CLAUDE.md +1 -0
- package/.agents/skills/orchestrator/reference/AGENTS.md +1 -0
- package/.agents/skills/orchestrator/reference/consult-the-orchestrator.md +70 -0
- package/.agents/skills/orchestrator/reference/executor-consult-block.md +62 -0
- package/.agents/skills/orchestrator/reference/host-detect.md +15 -0
- package/.agents/skills/orchestrator/test_orchestrator_skill_contract.py +62 -0
- package/.agents/skills/orchestrator-refresh/SKILL.md +16 -34
- package/.agents/skills/rebase/AGENTS.md +0 -31
- package/.agents/skills/session-log/AGENTS.md +0 -31
- package/.agents/skills/session-tidy/AGENTS.md +0 -35
- package/.agents/skills/skill-builder/AGENTS.md +0 -48
- package/.agents/skills/skill-builder/references/AGENTS.md +0 -24
- package/.agents/skills/skill-builder/templates/AGENTS.md +0 -13
- package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -18
- package/.agents/skills/task-build/AGENTS.md +0 -28
- package/.agents/skills/update/AGENTS.md +0 -37
- package/.agents/skills-archived/AGENTS.md +0 -44
- package/.agents/skills-archived/anthropic-plan/AGENTS.md +0 -33
- package/.agents/skills-archived/anthropic-plan/scripts/AGENTS.md +0 -10
- package/.agents/skills-archived/anthropic-plan/scripts/anthropic_plan_scripts_constants/AGENTS.md +0 -15
- package/.agents/skills-archived/anthropic-plan/templates/AGENTS.md +0 -12
- package/.agents/skills-archived/anthropic-plan/workflow/AGENTS.md +0 -13
- package/.agents/skills-archived/auditing-claude-config/AGENTS.md +0 -20
- package/.agents/skills-archived/bugteam/AGENTS.md +0 -29
- package/.agents/skills-archived/bugteam/reference/AGENTS.md +0 -19
- package/.agents/skills-archived/bugteam/reference/obstacles/AGENTS.md +0 -23
- package/.agents/skills-archived/bugteam/scripts/AGENTS.md +0 -29
- package/.agents/skills-archived/bugteam/scripts/bugteam_scripts_constants/AGENTS.md +0 -17
- package/.agents/skills-archived/codex-review/AGENTS.md +0 -45
- package/.agents/skills-archived/codex-review/reference/AGENTS.md +0 -14
- package/.agents/skills-archived/codex-review/scripts/codex_review_scripts_constants/AGENTS.md +0 -17
- package/.agents/skills-archived/codex-review/test_skill_scaffold.py +13 -3
- package/.agents/skills-archived/copilot-review/AGENTS.md +0 -17
- package/.agents/skills-archived/pr-converge/AGENTS.md +0 -31
- package/.agents/skills-archived/pr-converge/pr_converge_skill_constants/AGENTS.md +0 -25
- package/.agents/skills-archived/pr-converge/reference/AGENTS.md +0 -27
- package/.agents/skills-archived/pr-converge/reference/obstacles/AGENTS.md +0 -22
- package/.agents/skills-archived/pr-converge/scripts/AGENTS.md +0 -45
- package/.agents/skills-archived/pr-converge/scripts/pr_converge_scripts_constants/AGENTS.md +0 -17
- package/.agents/skills-archived/pr-converge/workflows/AGENTS.md +0 -15
- package/.agents/skills-archived/recall/AGENTS.md +0 -29
- package/.agents/skills-archived/remember/AGENTS.md +0 -30
- package/AGENTS.md +0 -112
- package/_shared/AGENTS.md +0 -16
- package/_shared/advisor/AGENTS.md +0 -21
- package/_shared/advisor/advisor-protocol.md +4 -1
- package/_shared/advisor/reference/consult-format.md +4 -2
- package/_shared/pr-loop/AGENTS.md +0 -27
- package/_shared/pr-loop/code-rules-gate.md +1 -1
- package/_shared/pr-loop/scripts/AGENTS.md +0 -49
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -2
- package/_shared/pr-loop/scripts/code_rules_gate_parts/AGENTS.md +0 -41
- package/_shared/pr-loop/scripts/code_rules_gate_parts/enforcer_loading.py +8 -8
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_enforcer_loading.py +2 -2
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_running.py +1 -1
- package/_shared/pr-loop/scripts/codex_review_scripts_constants/AGENTS.md +0 -17
- package/_shared/pr-loop/scripts/pr_converge_scripts_constants/AGENTS.md +0 -17
- package/_shared/pr-loop/scripts/pr_converge_skill_constants/AGENTS.md +0 -25
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/AGENTS.md +0 -25
- package/_shared/pr-loop/scripts/tests/AGENTS.md +0 -43
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +15 -15
- package/_shared/process-tree/AGENTS.md +0 -40
- package/audit-rubrics/AGENTS.md +0 -42
- package/audit-rubrics/category_rubrics/AGENTS.md +0 -36
- package/audit-rubrics/prompts/AGENTS.md +0 -36
- package/bin/AGENTS.md +0 -118
- package/bin/install.test.mjs +1 -1
- package/commands/AGENTS.md +0 -14
- package/docs/AGENTS.md +0 -31
- package/docs/CODE_RULES.md +10 -0
- package/docs/references/AGENTS.md +0 -16
- package/hooks/AGENTS.md +0 -27
- package/hooks/advisory/AGENTS.md +0 -15
- package/hooks/blocking/AGENTS.md +0 -112
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/AGENTS.md +0 -27
- package/hooks/blocking/code_rules_enforcer.py +433 -313
- package/hooks/blocking/config/AGENTS.md +0 -9
- package/hooks/blocking/inventory_intent_records/AGENTS.md +0 -25
- package/hooks/blocking/package_inventory_stale_blocker_parts/AGENTS.md +0 -25
- package/hooks/blocking/pii_prevention_blocker_parts/AGENTS.md +0 -23
- package/hooks/blocking/tdd_enforcer_parts/AGENTS.md +0 -29
- package/hooks/blocking/test_code_rules_enforcer_banned_noun_word.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_class_docstring_methods.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_dispatch_wiring.py +117 -22
- package/hooks/blocking/test_code_rules_enforcer_docstring_args_signature.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_docstring_prose_wall_illustration.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_docstring_runon_sentence.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_docstring_unreferenced_param.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_fstring_scan.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_ignored_must_check_return.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_inline_tuple_string_magic.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_join_separator_magic.py +2 -2
- package/hooks/blocking/test_code_rules_enforcer_js_returns_object.py +3 -3
- package/hooks/blocking/test_code_rules_enforcer_module_docstring_roster.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_naming_pattern.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_narrow_edit.py +117 -38
- package/hooks/blocking/test_code_rules_enforcer_output_snapshot.py +121 -0
- package/hooks/blocking/test_code_rules_enforcer_precheck_forecast.py +17 -15
- package/hooks/blocking/test_code_rules_enforcer_split_entry_1.py +4 -2
- package/hooks/blocking/test_code_rules_enforcer_split_entry_2.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_stage.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_string_magic.py +4 -4
- package/hooks/blocking/test_code_rules_enforcer_thin_wrapper_files.py +2 -2
- package/hooks/blocking/test_code_rules_enforcer_zero_payload_alias.py +2 -2
- package/hooks/blocking/test_code_rules_enforcer_zero_payload_alias_hook_routing.py +2 -2
- package/hooks/blocking/test_code_rules_validation_phase.py +281 -0
- package/hooks/blocking/test_fable_spawn_gate.py +1 -1
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +26 -11
- package/hooks/git-hooks/AGENTS.md +0 -31
- package/hooks/git-hooks/git_hooks_constants/AGENTS.md +0 -20
- package/hooks/hooks_constants/AGENTS.md +0 -99
- package/hooks/hooks_constants/code_rules_enforcer_constants.py +8 -0
- package/hooks/hooks_constants/test_code_rules_enforcer_constants.py +21 -0
- package/hooks/hooks_constants/validation_phase_constants.py +34 -0
- package/hooks/lifecycle/AGENTS.md +0 -17
- package/hooks/observability/AGENTS.md +0 -19
- package/hooks/session/AGENTS.md +0 -37
- package/hooks/validation/AGENTS.md +0 -19
- package/hooks/validators/AGENTS.md +0 -51
- package/hooks/validators/README.md +1 -1
- package/hooks/validators/config/hook_timing_harness_constants.py +16 -0
- package/hooks/validators/hook_timing_harness.py +287 -0
- package/hooks/validators/test_hook_timing_harness.py +251 -0
- package/hooks/workflow/AGENTS.md +0 -15
- package/output-styles/AGENTS.md +0 -14
- package/package.json +1 -1
- package/rules/AGENTS.md +0 -55
- package/scripts/AGENTS.md +0 -55
- package/scripts/dev_env_scripts_constants/AGENTS.md +0 -20
- package/scripts/sync_to_cursor/AGENTS.md +0 -22
- package/scripts/tests/AGENTS.md +0 -34
- package/system-prompts/AGENTS.md +0 -24
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"""Load the code-rules enforcer's ``
|
|
1
|
+
"""Load the code-rules enforcer's ``validate_content_for_full_gate`` for in-process use.
|
|
2
2
|
|
|
3
|
-
The gate runs the
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The gate runs the enforcer's full-gate validation phase, so it locates the
|
|
4
|
+
``hooks/blocking/code_rules_enforcer.py`` module from disk, executes it with
|
|
5
|
+
the hooks directory on ``sys.path``, and hands back its callable.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import importlib.machinery
|
|
@@ -138,11 +138,11 @@ def _exec_enforcer_with_hooks_on_path(
|
|
|
138
138
|
_restore_hooks_constants_modules(all_saved_modules, hooks_root_path)
|
|
139
139
|
|
|
140
140
|
|
|
141
|
-
def
|
|
142
|
-
"""Load ``code_rules_enforcer.
|
|
141
|
+
def load_validate_content_for_full_gate() -> ValidateContentCallable:
|
|
142
|
+
"""Load ``code_rules_enforcer.validate_content_for_full_gate`` for in-process use.
|
|
143
143
|
|
|
144
144
|
Returns:
|
|
145
|
-
The ``
|
|
145
|
+
The ``validate_content_for_full_gate`` callable from the enforcer module.
|
|
146
146
|
|
|
147
147
|
Raises:
|
|
148
148
|
SystemExit: When the package root or the enforcer module cannot load.
|
|
@@ -153,7 +153,7 @@ def load_validate_content() -> ValidateContentCallable:
|
|
|
153
153
|
)
|
|
154
154
|
module = importlib.util.module_from_spec(specification)
|
|
155
155
|
_exec_enforcer_with_hooks_on_path(specification, module)
|
|
156
|
-
return module.
|
|
156
|
+
return module.validate_content_for_full_gate
|
|
157
157
|
|
|
158
158
|
|
|
159
159
|
def _restore_hooks_constants_modules(
|
|
@@ -10,8 +10,8 @@ def test_resolve_claude_dev_env_root_finds_enforcer_bearing_root() -> None:
|
|
|
10
10
|
assert (resolved_root / "hooks" / "blocking" / "code_rules_enforcer.py").is_file()
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
validate_content = enforcer_loading.
|
|
13
|
+
def test_load_validate_content_for_full_gate_returns_callable_passing_a_clean_module() -> None:
|
|
14
|
+
validate_content = enforcer_loading.load_validate_content_for_full_gate()
|
|
15
15
|
clean_module = '"""Clean module."""\n\n\ndef ping() -> str:\n return "pong"\n'
|
|
16
16
|
issues = validate_content(clean_module, "sample.py", "")
|
|
17
17
|
assert issues == []
|
|
@@ -130,7 +130,7 @@ def test_gate_caller_scans_staged_content_with_commit_stage_scope(
|
|
|
130
130
|
|
|
131
131
|
resolved_file_path = file_path.resolve()
|
|
132
132
|
exit_code = gate_running.run_gate(
|
|
133
|
-
validate_content=enforcer_loading.
|
|
133
|
+
validate_content=enforcer_loading.load_validate_content_for_full_gate(),
|
|
134
134
|
all_file_paths=[resolved_file_path],
|
|
135
135
|
repository_root=repository_root,
|
|
136
136
|
all_added_lines_by_path={resolved_file_path: {2, 3}},
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
# codex_review_scripts_constants
|
|
2
1
|
|
|
3
|
-
Python package of named constants imported by Codex review scripts under `_shared/pr-loop/scripts/`. Importing from this package keeps magic values out of script bodies.
|
|
4
|
-
|
|
5
|
-
## Modules
|
|
6
|
-
|
|
7
|
-
| File | Constants for |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `__init__.py` | Package marker and package docstring. |
|
|
10
|
-
| `run_constants.py` | Binary name, flag strings, custom-instructions prompt, version-probe pattern, timeout default, decode/timeout exit sentinels, flag_token_pattern suffix (whole-token shape match), JSONL keys, and capture outcome class labels for `run_codex_review.py`. |
|
|
11
|
-
| `findings_constants.py` | Finding field keys, fenced-JSON and freeform patterns for `parse_codex_findings.py`. |
|
|
12
|
-
| `classifier_constants.py` | Failure class names and stream markers for `codex_down_classifier.py`. |
|
|
13
|
-
| `run_constants.py` | Binary name, flag strings, custom-instructions prompt, version-probe pattern, timeout default, decode/timeout exit sentinels, flag_token_pattern suffix (whole-token shape match), JSONL keys, JSONL capture filename and newline mode, and capture outcome class labels for `run_codex_review.py`. |
|
|
14
|
-
| `codex_usage_probe_constants.py` | The weekly-usage probe CLI: gate threshold, report JSON keys, app-server JSON-RPC surface, rate-limit field keys, weekly-window sizing, text-status parse patterns, source labels, and exit codes. |
|
|
15
|
-
|
|
16
|
-
## Convention
|
|
17
|
-
|
|
18
|
-
Scripts import from this package at module scope. No constant is defined inline in a script body — the hook enforces this at write time.
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
# pr_converge_scripts_constants
|
|
2
1
|
|
|
3
|
-
Constants module for shared PR-loop convergence scripts. Re-exports all runtime/API constants from `pr_converge_skill_constants` and adds script-specific constants for CLI arguments, markdown patterns, and reflow settings.
|
|
4
|
-
|
|
5
|
-
## Key files
|
|
6
|
-
|
|
7
|
-
| File | Purpose |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `__init__.py` | Package marker |
|
|
10
|
-
| `pr_converge_constants.py` | Re-exports all constants from `pr_converge_skill_constants.constants` plus adds script-specific values |
|
|
11
|
-
| `reflow_skill_md_constants.py` | Constants for `reflow_skill_md.py`: line width limit, list item patterns, `TARGET_SKILL_PATH` |
|
|
12
|
-
| `convergence_gate_constants.py` | Constants for `check_convergence_gates.py`: short-SHA length, join separators, and the review-threads GraphQL query |
|
|
13
|
-
|
|
14
|
-
## Conventions
|
|
15
|
-
|
|
16
|
-
- `pr_converge_constants.py` uses `from pr_converge_skill_constants.constants import ...` (with `# noqa: F401`) to re-export everything so script files can import from one location.
|
|
17
|
-
- `reflow_skill_md_constants.py` resolves `TARGET_SKILL_PATH` from its own `__file__` path, pointing to `SKILL.md` three directories up.
|
|
18
|
-
- Script-specific regex patterns (ordered list items, bullet list items, unfinished markdown link targets, markdown reference definitions) live in `reflow_skill_md_constants.py`.
|
|
@@ -1,26 +1 @@
|
|
|
1
|
-
# pr_converge_skill_constants
|
|
2
1
|
|
|
3
|
-
Importable Python constants module for shared PR-loop convergence scripts. Script-specific constants (CLI args, markdown patterns, reflow settings) live in `pr_converge_scripts_constants/` beside this package and import from here.
|
|
4
|
-
|
|
5
|
-
## Key files
|
|
6
|
-
|
|
7
|
-
| File | Purpose |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `__init__.py` | Package marker |
|
|
10
|
-
| `constants.py` | All runtime and API constants: bot logins, review states, GH API path templates, bugbot/bugteam detection patterns, exit codes |
|
|
11
|
-
|
|
12
|
-
## Exported constants (selected)
|
|
13
|
-
|
|
14
|
-
| Constant | Purpose |
|
|
15
|
-
|---|---|
|
|
16
|
-
| `CURSOR_BOT_LOGIN` | Login string for the Cursor bugbot reviewer |
|
|
17
|
-
| `COPILOT_REVIEWER_LOGIN` | Login string for the Copilot reviewer bot |
|
|
18
|
-
| `ALL_COPILOT_CLEAN_REVIEW_STATES` | Tuple of review states that count as clean for Copilot |
|
|
19
|
-
| `BUGBOT_DIRTY_BODY_REGEX` | Regex that matches a bugbot review body reporting findings |
|
|
20
|
-
| `GH_REVIEWS_PATH_TEMPLATE` | `gh api` path template for PR reviews |
|
|
21
|
-
| `GH_INLINE_COMMENTS_PATH_TEMPLATE` | `gh api` path template for PR inline comments |
|
|
22
|
-
|
|
23
|
-
## Conventions
|
|
24
|
-
|
|
25
|
-
- All path templates use `str.format(**kwargs)` with keys `owner`, `repo`, `number`.
|
|
26
|
-
- `packages/claude-dev-env/_shared/pr-loop/scripts/pr_converge_scripts_constants/pr_converge_constants.py` re-exports everything here via `from pr_converge_skill_constants.constants import ...` so scripts can import from either location.
|
|
@@ -1,26 +1 @@
|
|
|
1
|
-
# pr_loop_shared_constants
|
|
2
1
|
|
|
3
|
-
Named constants for every script in `_shared/pr-loop/scripts/`. Each module owns the constants for one script; the module name mirrors the script name with a `_constants` suffix.
|
|
4
|
-
|
|
5
|
-
## Modules
|
|
6
|
-
|
|
7
|
-
| File | Constants for |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `claude_permissions_constants.py` | `grant_project_claude_permissions.py` and `revoke_project_claude_permissions.py` — permission rule strings and settings.json keys |
|
|
10
|
-
| `claude_settings_keys_constants.py` | Top-level `~/.claude/settings.json` key names used across the permission helpers |
|
|
11
|
-
| `stale_worktree_rule_sweep_constants.py` | `stale_worktree_rule_sweep.py` — the worktrees subdirectory name, the worktree path segment count, the rule-string delimiters, the `.claude` home path marker, and `get_claude_worktrees_root` |
|
|
12
|
-
| `code_rules_gate_constants.py` | `code_rules_gate.py` — file extensions, git diff subcommands, test filename patterns |
|
|
13
|
-
| `inline_duplicate_body_span_constants.py` | `code_rules_gate.py` — regex and capture-group indices for the same-file inline-duplicate message, which carries both the helper and the enclosing span the gate reconstructs the union from |
|
|
14
|
-
| `fix_hookspath_constants.py` | `fix_hookspath.py` — verification suffix and related strings |
|
|
15
|
-
| `post_audit_thread_constants.py` | `post_audit_thread.py` — HTTP status codes, retry counts, GitHub API paths |
|
|
16
|
-
| `preflight_constants.py` | `preflight.py` — env-var names, git subcommands, pytest exit codes, test discovery patterns |
|
|
17
|
-
| `preflight_self_heal_constants.py` | `preflight_self_heal.py` — git config keys and local-scope detection strings |
|
|
18
|
-
| `reviews_disabled_constants.py` | `reviews_disabled.py` — `CLAUDE_REVIEWS_DISABLED` and `CLAUDE_REVIEWS_ENABLED` env-var names and token taxonomy |
|
|
19
|
-
| `copilot_quota_constants.py` | `copilot_quota.py` — `COPILOT_QUOTA_ACCOUNT` env-var name, `copilot_internal/user` API path, the `premium_interactions` gating field names, the four skip/run exit codes, and the default `.env` path |
|
|
20
|
-
| `terminology_sweep_constants.py` | `terminology_sweep.py` — identifier and prose-token regexes, diff-parsing prefixes, code-file extensions, test-file detection patterns, and the finding-message template |
|
|
21
|
-
| `reviewer_availability_constants.py` | `reviewer_availability.py` — the available/down exit codes for the unified reviewer-availability pre-check |
|
|
22
|
-
| `__init__.py` | Empty package marker |
|
|
23
|
-
|
|
24
|
-
## Convention
|
|
25
|
-
|
|
26
|
-
Every constant is `UPPER_SNAKE_CASE` with an explicit type annotation. No magic literals appear in the consuming scripts — all values live here. Test coverage for each module lives in `tests/test_<module_name>.py`.
|
|
@@ -1,44 +1 @@
|
|
|
1
|
-
# _shared/pr-loop/scripts/tests
|
|
2
1
|
|
|
3
|
-
pytest suite for the scripts and constants in `_shared/pr-loop/scripts/`. Each test file covers one script or one constants module.
|
|
4
|
-
|
|
5
|
-
## Test files
|
|
6
|
-
|
|
7
|
-
| File | Covers |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `test__claude_permissions_common.py` | Internal helpers in `_claude_permissions_common.py` (legacy underscore prefix) |
|
|
10
|
-
| `test_claude_permissions_common.py` | Public API of `_claude_permissions_common.py` |
|
|
11
|
-
| `test_claude_permissions_constants.py` | `pr_loop_shared_constants/claude_permissions_constants.py` |
|
|
12
|
-
| `test_claude_settings_keys_constants.py` | `pr_loop_shared_constants/claude_settings_keys_constants.py` |
|
|
13
|
-
| `test_code_rules_gate.py` | `code_rules_gate.py` gate logic |
|
|
14
|
-
| `test_terminology_sweep.py` | `terminology_sweep.py` near-miss detection and exit codes |
|
|
15
|
-
| `test_code_rules_gate_constants.py` | `pr_loop_shared_constants/code_rules_gate_constants.py` |
|
|
16
|
-
| `test_fix_hookspath.py` | `fix_hookspath.py` repair logic |
|
|
17
|
-
| `test_fix_hookspath_constants.py` | `pr_loop_shared_constants/fix_hookspath_constants.py` |
|
|
18
|
-
| `test_grant_project_claude_permissions.py` | `grant_project_claude_permissions.py` end-to-end |
|
|
19
|
-
| `test_post_audit_thread.py` | `post_audit_thread.py` review-posting flow |
|
|
20
|
-
| `test_post_audit_thread_constants.py` | `pr_loop_shared_constants/post_audit_thread_constants.py` |
|
|
21
|
-
| `test_preflight.py` | `preflight.py` pre-flight checks |
|
|
22
|
-
| `test_preflight_constants.py` | `pr_loop_shared_constants/preflight_constants.py` |
|
|
23
|
-
| `test_preflight_self_heal.py` | `preflight_self_heal.py` hooks-path repair |
|
|
24
|
-
| `test_reviews_disabled.py` | `reviews_disabled.py` opt-out gate parsing |
|
|
25
|
-
| `test_copilot_quota.py` | `copilot_quota.py` end-to-end: account resolution, premium-quota classification, exit codes, and skip logging |
|
|
26
|
-
| `test_copilot_quota_constants.py` | `pr_loop_shared_constants/copilot_quota_constants.py` |
|
|
27
|
-
| `test_reviewer_availability.py` | `reviewer_availability.py` end-to-end: Copilot and Bugbot availability, opt-out via `CLAUDE_REVIEWS_DISABLED`, and every Copilot quota outcome |
|
|
28
|
-
| `test_reviewer_availability_constants.py` | `pr_loop_shared_constants/reviewer_availability_constants.py` |
|
|
29
|
-
| `test_revoke_project_claude_permissions.py` | `revoke_project_claude_permissions.py` end-to-end |
|
|
30
|
-
| `test_stale_worktree_rule_sweep.py` | `stale_worktree_rule_sweep.py` sweep and deduplication end-to-end |
|
|
31
|
-
| `test_stale_worktree_rule_sweep_constants.py` | `pr_loop_shared_constants/stale_worktree_rule_sweep_constants.py` worktrees-root resolution and rule-format readers |
|
|
32
|
-
| `test_agent_config_carveout.py` | Agent-config deny-rule carve-out logic |
|
|
33
|
-
| `conftest.py` | Shared pytest fixtures |
|
|
34
|
-
|
|
35
|
-
## Fixtures
|
|
36
|
-
|
|
37
|
-
`fixtures/copilot_internal_user_example.json` — a captured `gh api
|
|
38
|
-
copilot_internal/user` response driving `test_copilot_quota.py`.
|
|
39
|
-
|
|
40
|
-
## Running
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
python -m pytest packages/claude-dev-env/_shared/pr-loop/scripts/tests/
|
|
44
|
-
```
|
|
@@ -735,7 +735,7 @@ def test_run_gate_flags_copied_sibling_when_cwd_is_outside_repo_root(
|
|
|
735
735
|
copied_file = package_directory / "copied_helper.py"
|
|
736
736
|
existing_file.write_text(_DUPLICATE_HELPER_SOURCE, encoding="utf-8")
|
|
737
737
|
copied_file.write_text(_DUPLICATE_HELPER_SOURCE, encoding="utf-8")
|
|
738
|
-
validate_content = gate_module.
|
|
738
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
739
739
|
|
|
740
740
|
monkeypatch.chdir(temporary_git_repository.parent)
|
|
741
741
|
blocking_by_file, _advisory_by_file, _skipped = (
|
|
@@ -813,7 +813,7 @@ def test_duplicate_body_span_range_covers_the_definition_through_last_body_line(
|
|
|
813
813
|
assert span == range(definition_line, last_body_line + 1)
|
|
814
814
|
|
|
815
815
|
|
|
816
|
-
def
|
|
816
|
+
def test_split_violations_by_scope_blocks_duplicate_body_when_span_intersects_added_lines(
|
|
817
817
|
tmp_path: Path,
|
|
818
818
|
) -> None:
|
|
819
819
|
"""A duplicate-body issue whose copied-function span overlaps the diff's added
|
|
@@ -829,7 +829,7 @@ def test_split_violations_blocks_duplicate_body_when_span_intersects_added_lines
|
|
|
829
829
|
assert advisory == []
|
|
830
830
|
|
|
831
831
|
|
|
832
|
-
def
|
|
832
|
+
def test_split_violations_by_scope_advises_duplicate_body_when_span_misses_added_lines(
|
|
833
833
|
tmp_path: Path,
|
|
834
834
|
) -> None:
|
|
835
835
|
"""A duplicate-body issue for an untouched pre-existing copy — whose span does
|
|
@@ -1002,7 +1002,7 @@ def test_collect_partitioned_violations_advises_pre_existing_sibling_duplicate(
|
|
|
1002
1002
|
_DUPLICATE_HELPER_SOURCE + "unrelated_constant = 1\n", encoding="utf-8"
|
|
1003
1003
|
)
|
|
1004
1004
|
unrelated_added_line = _DUPLICATE_HELPER_SOURCE.count("\n") + 1
|
|
1005
|
-
validate_content = gate_module.
|
|
1005
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
1006
1006
|
|
|
1007
1007
|
resolved_copied = copied_file.resolve()
|
|
1008
1008
|
blocking_by_file, advisory_by_file, _skipped = (
|
|
@@ -1055,7 +1055,7 @@ def test_collect_partitioned_violations_blocks_sibling_duplicate_in_added_region
|
|
|
1055
1055
|
definition_line = 3
|
|
1056
1056
|
last_body_line = 15
|
|
1057
1057
|
all_copied_function_lines = set(range(definition_line, last_body_line + 1))
|
|
1058
|
-
validate_content = gate_module.
|
|
1058
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
1059
1059
|
|
|
1060
1060
|
resolved_copied = copied_file.resolve()
|
|
1061
1061
|
blocking_by_file, _advisory_by_file, _skipped = (
|
|
@@ -1549,10 +1549,10 @@ def test_main_blocks_when_function_body_grows_past_threshold_with_def_line_untou
|
|
|
1549
1549
|
assert exit_code == 1
|
|
1550
1550
|
|
|
1551
1551
|
|
|
1552
|
-
def
|
|
1552
|
+
def test_split_violations_by_scope_blocks_function_length_when_span_intersects_added_lines() -> None:
|
|
1553
1553
|
"""A function-length issue whose declared span overlaps the diff's added
|
|
1554
1554
|
lines is blocking — the body grew, which is exactly Finding B's intent."""
|
|
1555
|
-
validate_content = gate_module.
|
|
1555
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
1556
1556
|
long_function = _build_function_module(
|
|
1557
1557
|
"oversized", body_line_count=70, leading_lines=3
|
|
1558
1558
|
)
|
|
@@ -1571,12 +1571,12 @@ def test_split_violations_blocks_function_length_when_span_intersects_added_line
|
|
|
1571
1571
|
assert advisory == []
|
|
1572
1572
|
|
|
1573
1573
|
|
|
1574
|
-
def
|
|
1574
|
+
def test_split_violations_by_scope_advises_function_length_when_span_misses_added_lines() -> None:
|
|
1575
1575
|
"""A function-length issue for an untouched pre-existing function — whose
|
|
1576
1576
|
declared span does not overlap any added line — is advisory, not blocking.
|
|
1577
1577
|
This prevents the over-block regression where every pre-existing >=60-line
|
|
1578
1578
|
function in a touched file was forced into the blocking payload."""
|
|
1579
|
-
validate_content = gate_module.
|
|
1579
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
1580
1580
|
long_function = _build_function_module(
|
|
1581
1581
|
"oversized", body_line_count=70, leading_lines=3
|
|
1582
1582
|
)
|
|
@@ -1595,7 +1595,7 @@ def test_split_violations_advises_function_length_when_span_misses_added_lines()
|
|
|
1595
1595
|
|
|
1596
1596
|
|
|
1597
1597
|
def _isolation_issues_for_home_probe_test() -> list[str]:
|
|
1598
|
-
validate_content = gate_module.
|
|
1598
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
1599
1599
|
header = "from pathlib import Path\n"
|
|
1600
1600
|
test_body = (
|
|
1601
1601
|
"def test_reads_home() -> None:\n"
|
|
@@ -1606,7 +1606,7 @@ def _isolation_issues_for_home_probe_test() -> list[str]:
|
|
|
1606
1606
|
return [each_issue for each_issue in issues if "probes" in each_issue]
|
|
1607
1607
|
|
|
1608
1608
|
|
|
1609
|
-
def
|
|
1609
|
+
def test_split_violations_by_scope_blocks_isolation_when_function_span_intersects_added_lines() -> None:
|
|
1610
1610
|
"""An isolation issue whose enclosing test-function span overlaps the diff's
|
|
1611
1611
|
added lines is blocking — a signature-line change that un-isolates an
|
|
1612
1612
|
unchanged-body probe must block, matching the enforcer's terminal path."""
|
|
@@ -1621,7 +1621,7 @@ def test_split_violations_blocks_isolation_when_function_span_intersects_added_l
|
|
|
1621
1621
|
assert advisory == []
|
|
1622
1622
|
|
|
1623
1623
|
|
|
1624
|
-
def
|
|
1624
|
+
def test_split_violations_by_scope_advises_isolation_when_function_span_misses_added_lines() -> None:
|
|
1625
1625
|
"""An isolation issue for an untouched pre-existing probe — whose enclosing
|
|
1626
1626
|
test-function span does not overlap any added line — is advisory, not
|
|
1627
1627
|
blocking, mirroring the function-length scope contract."""
|
|
@@ -1814,7 +1814,7 @@ def test_check_wrapper_plumb_through_stays_under_function_length_threshold() ->
|
|
|
1814
1814
|
|
|
1815
1815
|
|
|
1816
1816
|
def _banned_noun_parameter_issues() -> list[str]:
|
|
1817
|
-
validate_content = gate_module.
|
|
1817
|
+
validate_content = gate_module.load_validate_content_for_full_gate()
|
|
1818
1818
|
source = (
|
|
1819
1819
|
"def aggregate(canned_results: int) -> int:\n"
|
|
1820
1820
|
" doubled = canned_results * 2\n"
|
|
@@ -1824,7 +1824,7 @@ def _banned_noun_parameter_issues() -> list[str]:
|
|
|
1824
1824
|
return [each_issue for each_issue in issues if "banned noun" in each_issue]
|
|
1825
1825
|
|
|
1826
1826
|
|
|
1827
|
-
def
|
|
1827
|
+
def test_split_violations_by_scope_blocks_banned_noun_when_binding_line_is_added() -> None:
|
|
1828
1828
|
"""A banned-noun binding is blocking when its own binding line is among the
|
|
1829
1829
|
added lines. The gate reconstructs the one-line binding span through the
|
|
1830
1830
|
same shared extractor registry it uses for function-length and isolation,
|
|
@@ -1840,7 +1840,7 @@ def test_split_violations_blocks_banned_noun_when_binding_line_is_added() -> Non
|
|
|
1840
1840
|
assert advisory == []
|
|
1841
1841
|
|
|
1842
1842
|
|
|
1843
|
-
def
|
|
1843
|
+
def test_split_violations_by_scope_advises_banned_noun_when_binding_line_untouched() -> None:
|
|
1844
1844
|
"""A banned-noun binding whose own line is not among the added lines is
|
|
1845
1845
|
advisory — editing an unrelated body line does not pull a pre-existing
|
|
1846
1846
|
binding into scope, mirroring the companion exact-match identifier check."""
|
|
@@ -1,41 +1 @@
|
|
|
1
|
-
# _shared/process-tree
|
|
2
1
|
|
|
3
|
-
One home for ending a spawned process together with every descendant it
|
|
4
|
-
started. Callers that capture a CLI's output import it so a grandchild can
|
|
5
|
-
never outlive the run and hold the capture pipe open.
|
|
6
|
-
|
|
7
|
-
## Consumers
|
|
8
|
-
|
|
9
|
-
| Caller | Use |
|
|
10
|
-
|---|---|
|
|
11
|
-
| `scripts/grok_headless_runner.py` | Kills a timed-out worker's tree between drain attempts |
|
|
12
|
-
| `_shared/pr-loop/scripts/run_codex_review.py` | Kills the review tree on timeout, then drains |
|
|
13
|
-
| `_shared/pr-loop/scripts/codex_usage_probe.py` | Tears the app-server tree down after the rate-limits exchange |
|
|
14
|
-
|
|
15
|
-
A PR-loop script reaches this home the way convergence scripts reach
|
|
16
|
-
`_shared/pr-loop/scripts`: it puts the directory on `sys.path` and imports by
|
|
17
|
-
module name. `bin/install.mjs` copies `_shared` and `scripts` together, and
|
|
18
|
-
every install group that carries a consumer carries `_shared`, so the import
|
|
19
|
-
resolves in the repository and under `~/.claude` alike.
|
|
20
|
-
|
|
21
|
-
## Key files
|
|
22
|
-
|
|
23
|
-
| File | Purpose |
|
|
24
|
-
|---|---|
|
|
25
|
-
| `scripts/process_tree_kill.py` | `terminate_process_tree` (poll, platform tree kill, re-poll, `Popen.kill()` fallback), `kill_process_tree_by_identifier`, and `should_start_new_session` for the matching `Popen` flag |
|
|
26
|
-
| `scripts/test_process_tree_kill.py` | Behavioral tests for every public entry point here, each platform branch, each failure the helper swallows, and the `Popen.kill()` fallback |
|
|
27
|
-
| `scripts/config/process_tree_scripts_constants/process_tree_kill_constants.py` | The taskkill command, its `/T`, `/F`, and `/PID` flags, and the bound on the kill command |
|
|
28
|
-
| `scripts/pyproject.toml` | mypy configuration; `check.ps1` runs it under the `mypy-process-tree` label |
|
|
29
|
-
|
|
30
|
-
## Platform guard
|
|
31
|
-
|
|
32
|
-
Both the branch selector and the POSIX helper compare `sys.platform` against
|
|
33
|
-
the literal `"win32"`. That literal is what mypy narrows on: behind a named
|
|
34
|
-
constant, `os.getpgid`, `os.killpg`, and `signal.SIGKILL` fail type checking on
|
|
35
|
-
Windows.
|
|
36
|
-
|
|
37
|
-
## Pairing rule
|
|
38
|
-
|
|
39
|
-
`os.killpg` signals a whole process group, so a child sharing the caller's
|
|
40
|
-
group takes the caller down with it. Every `Popen` whose tree this module ends
|
|
41
|
-
passes `start_new_session=should_start_new_session()`.
|
package/audit-rubrics/AGENTS.md
CHANGED
|
@@ -1,43 +1 @@
|
|
|
1
|
-
# audit-rubrics
|
|
2
1
|
|
|
3
|
-
Audit rubrics for the PR-loop code-review suite. The rubrics define the 17 bug categories (A–Q), their sub-bucket decompositions, and the prompt templates agents use during an audit pass. Installed into `~/.claude/audit-rubrics/` by `bin/install.mjs`.
|
|
4
|
-
|
|
5
|
-
## Key file
|
|
6
|
-
|
|
7
|
-
| File | Purpose |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `audit-categories.json` | Machine-readable A-Q schema: id, title, slug, and sub-bucket id/axis pairs; single source for rubric and prompt skeleton parity |
|
|
10
|
-
| `source-material-section-types.md` | Lookup table for how to chunk an artifact into sections for an audit prompt; covers code PRs, docs, SQL schemas, config files, and more |
|
|
11
|
-
|
|
12
|
-
## Subdirectories
|
|
13
|
-
|
|
14
|
-
| Entry | Description |
|
|
15
|
-
|---|---|
|
|
16
|
-
| `category_rubrics/` | One `.md` per category (A–Q): defines what the category audits, example findings, and a sub-bucket decomposition table |
|
|
17
|
-
| `prompts/` | One `.md` per category: the ready-to-use audit prompt template an agent inlines the artifact into |
|
|
18
|
-
|
|
19
|
-
## Categories
|
|
20
|
-
|
|
21
|
-
| ID | Name |
|
|
22
|
-
|---|---|
|
|
23
|
-
| A | API contract verification |
|
|
24
|
-
| B | Selector engine compatibility |
|
|
25
|
-
| C | Resource cleanup |
|
|
26
|
-
| D | Scoping and ordering |
|
|
27
|
-
| E | Dead code |
|
|
28
|
-
| F | Silent failures |
|
|
29
|
-
| G | Bounds and overflow |
|
|
30
|
-
| H | Security boundaries |
|
|
31
|
-
| I | Concurrency |
|
|
32
|
-
| J | Code-rules compliance |
|
|
33
|
-
| K | Codebase conflicts |
|
|
34
|
-
| L | Behavior equivalence |
|
|
35
|
-
| M | Producer-consumer cardinality |
|
|
36
|
-
| N | Test name / scenario verifier |
|
|
37
|
-
| O | Docstring vs implementation drift |
|
|
38
|
-
| P | Name vs behavior contract |
|
|
39
|
-
| Q | Cross-surface claim consistency |
|
|
40
|
-
|
|
41
|
-
## Breaking-change rule
|
|
42
|
-
|
|
43
|
-
Adding a sub-bucket to a category rubric requires updating `audit-categories.json` and the matching prompt template in `prompts/` in the same commit, then running `audit_category_schema.py --validate`. Skills that reference category IDs (`bugteam`, `findbugs`) rely on stable sub-bucket IDs (A1, A2, … Q-n). Worked examples stay in the rubric markdown only; they are outside the schema.
|
|
@@ -1,37 +1 @@
|
|
|
1
|
-
# audit-rubrics/category_rubrics
|
|
2
1
|
|
|
3
|
-
One rubric file per audit category (A–Q). Each file defines what the category covers, gives concrete examples of findings, and provides the sub-bucket decomposition an audit agent uses to structure its pass.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
| File | Category |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `category-a-api-contracts.md` | A — API contract verification |
|
|
10
|
-
| `category-b-selector-engine-compat.md` | B — Selector engine compatibility |
|
|
11
|
-
| `category-c-resource-cleanup.md` | C — Resource cleanup |
|
|
12
|
-
| `category-d-scoping-and-ordering.md` | D — Scoping and ordering |
|
|
13
|
-
| `category-e-dead-code.md` | E — Dead code |
|
|
14
|
-
| `category-f-silent-failures.md` | F — Silent failures |
|
|
15
|
-
| `category-g-bounds-and-overflow.md` | G — Bounds and overflow |
|
|
16
|
-
| `category-h-security-boundaries.md` | H — Security boundaries |
|
|
17
|
-
| `category-i-concurrency.md` | I — Concurrency |
|
|
18
|
-
| `category-j-code-rules-compliance.md` | J — Code-rules compliance |
|
|
19
|
-
| `category-k-codebase-conflicts.md` | K — Codebase conflicts |
|
|
20
|
-
| `category-l-behavior-equivalence.md` | L — Behavior equivalence |
|
|
21
|
-
| `category-m-producer-consumer-cardinality.md` | M — Producer-consumer cardinality |
|
|
22
|
-
| `category-n-test-name-scenario-verifier.md` | N — Test name / scenario verifier |
|
|
23
|
-
| `category-o-docstring-vs-impl-drift.md` | O — Docstring vs implementation drift |
|
|
24
|
-
| `category-p-name-vs-behavior-contract.md` | P — Name vs behavior contract |
|
|
25
|
-
| `category-q-cross-surface-claims.md` | Q — Cross-surface claim consistency |
|
|
26
|
-
|
|
27
|
-
## Rubric structure
|
|
28
|
-
|
|
29
|
-
Each file has:
|
|
30
|
-
- A plain-language description of what the category audits
|
|
31
|
-
- Concrete finding examples
|
|
32
|
-
- A companion-reference pointer to `../source-material-section-types.md`
|
|
33
|
-
- A sub-bucket decomposition table with stable IDs (A1, A2, …) and the concrete checks each bucket requires
|
|
34
|
-
|
|
35
|
-
## Relationship to prompts/
|
|
36
|
-
|
|
37
|
-
`category_rubrics/` is the human-readable reference. `prompts/` holds the agent-ready prompt templates that inline the same sub-bucket list in a structured prompt format. Keep both in sync when sub-buckets change.
|
|
@@ -1,37 +1 @@
|
|
|
1
|
-
# audit-rubrics/prompts
|
|
2
1
|
|
|
3
|
-
Agent-ready audit prompt templates, one per category (A–Q). An agent inlines the artifact under review into the `[INLINE THE FULL ARTIFACT HERE]` placeholder and runs the prompt as-is.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
| File | Category |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `category-a-api-contracts.md` | A — API contract verification |
|
|
10
|
-
| `category-b-selector-engine-compat.md` | B — Selector engine compatibility |
|
|
11
|
-
| `category-c-resource-cleanup.md` | C — Resource cleanup |
|
|
12
|
-
| `category-d-scoping-and-ordering.md` | D — Scoping and ordering |
|
|
13
|
-
| `category-e-dead-code.md` | E — Dead code |
|
|
14
|
-
| `category-f-silent-failures.md` | F — Silent failures |
|
|
15
|
-
| `category-g-bounds-and-overflow.md` | G — Bounds and overflow |
|
|
16
|
-
| `category-h-security-boundaries.md` | H — Security boundaries |
|
|
17
|
-
| `category-i-concurrency.md` | I — Concurrency |
|
|
18
|
-
| `category-j-code-rules-compliance.md` | J — Code-rules compliance |
|
|
19
|
-
| `category-k-codebase-conflicts.md` | K — Codebase conflicts |
|
|
20
|
-
| `category-l-behavior-equivalence.md` | L — Behavior equivalence |
|
|
21
|
-
| `category-m-producer-consumer-cardinality.md` | M — Producer-consumer cardinality |
|
|
22
|
-
| `category-n-test-name-scenario-verifier.md` | N — Test name / scenario verifier |
|
|
23
|
-
| `category-o-docstring-vs-impl-drift.md` | O — Docstring vs implementation drift |
|
|
24
|
-
| `category-p-name-vs-behavior-contract.md` | P — Name vs behavior contract |
|
|
25
|
-
| `category-q-cross-surface-claims.md` | Q — Cross-surface claim consistency |
|
|
26
|
-
|
|
27
|
-
## Prompt structure
|
|
28
|
-
|
|
29
|
-
Each template:
|
|
30
|
-
- Scopes the audit to one category only (skip the others)
|
|
31
|
-
- Lists all sub-buckets from the matching `category_rubrics/` file
|
|
32
|
-
- Requires each sub-bucket to produce at least one Shape A finding OR one Shape B proof-of-absence with three or more adversarial probes
|
|
33
|
-
- Uses `find` as the finding ID prefix (single-pass audits) rather than `loop<N>-<K>`
|
|
34
|
-
|
|
35
|
-
## Relationship to category_rubrics/
|
|
36
|
-
|
|
37
|
-
`prompts/` is the executable form; `category_rubrics/` is the reference form. When a sub-bucket decomposition changes in a rubric, update the matching prompt in the same commit.
|