claude-dev-env 2.4.0 → 2.7.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/CLAUDE.md +26 -59
- package/_shared/pr-loop/scripts/_claude_permissions_common.py +84 -0
- package/_shared/pr-loop/scripts/code_rules_gate.py +6 -3
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +12 -2
- package/_shared/pr-loop/scripts/code_rules_gate_parts/baseline_import_isolation.py +309 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_regression.py +540 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +206 -70
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/__init__.py +1 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/_repo_test_helpers.py +76 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_baseline_import_isolation.py +248 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_regression.py +309 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +91 -58
- package/_shared/pr-loop/scripts/grant_project_claude_permissions.py +306 -306
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/claude_permissions_constants.py +44 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +202 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/copilot_quota_constants.py +24 -24
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/stale_worktree_rule_sweep_constants.py +107 -107
- package/_shared/pr-loop/scripts/revoke_project_claude_permissions.py +290 -48
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +42 -2
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_constants.py +36 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +100 -1
- package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -497
- package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +311 -2
- package/_shared/pr-loop/scripts/tests/test_stale_worktree_rule_sweep.py +301 -301
- package/_shared/pr-loop/scripts/tests/test_stale_worktree_rule_sweep_constants.py +85 -85
- package/_shared/pr-loop/worker-spawn.md +1 -1
- package/agents/CLAUDE.md +3 -2
- package/agents/caveman.md +0 -1
- package/agents/clasp-deployment-orchestrator.md +0 -1
- package/agents/clean-coder.md +0 -1
- package/agents/code-advisor.md +0 -1
- package/agents/code-quality-agent.md +1 -2
- package/agents/code-verifier.md +36 -8
- package/agents/deep-research.md +0 -1
- package/agents/docs-agent.md +0 -1
- package/agents/git-commit-crafter.md +0 -1
- package/agents/issue-tracker.md +42 -0
- package/agents/plan-packet-validator.md +0 -1
- package/agents/pr-description-writer.md +0 -1
- package/agents/test_agent_frontmatter.py +67 -18
- package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +143 -141
- package/bin/CLAUDE.md +68 -5
- package/bin/codex-compat.mjs +104 -0
- package/bin/codex-compat.test.mjs +51 -0
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/install-constants.mjs +88 -0
- package/bin/install.mjs +1138 -114
- package/bin/install.prune.test.mjs +869 -19
- package/bin/install.test.mjs +906 -2
- package/codex-capability-map.json +13 -0
- package/commands/implement.md +1 -1
- package/commands/right-size.md +1 -1
- package/docs/CLAUDE.md +1 -0
- package/docs/CODE_RULES.md +2 -0
- package/docs/codex-compatibility.md +25 -0
- package/docs/host-pool-health-monitor.md +102 -0
- package/docs/nas-ssh-invocation.md +96 -12
- package/docs/references/CLAUDE.md +4 -2
- package/docs/references/advisor-tool.md +13 -0
- package/docs/references/code-review-enforcement.md +35 -0
- package/docs/references/team-advisor-skill.md +14 -0
- package/hooks/blocking/CLAUDE.md +4 -0
- package/hooks/blocking/code_review_pr_create_gate.py +7 -3
- package/hooks/blocking/code_review_push_gate.py +9 -4
- package/hooks/blocking/code_review_stamp_directory_write_blocker.py +8 -0
- package/hooks/blocking/config/__init__.py +5 -5
- package/hooks/blocking/config/code_review_enforcement_constants.py +40 -7
- package/hooks/blocking/config/test_code_review_enforcement_constants.py +58 -0
- package/hooks/blocking/config/verified_commit_constants.py +160 -159
- package/hooks/blocking/eli11_reply_enforcer.py +479 -0
- package/hooks/blocking/gh_body_arg_blocker.py +1 -1
- package/hooks/blocking/nas_ssh_binary_enforcer.py +8 -46
- package/hooks/blocking/orchestrator_refresh_reschedule_gate.py +256 -0
- package/hooks/blocking/pre_tool_use_dispatcher.py +24 -24
- package/hooks/blocking/shell_substitution_blocker.py +129 -0
- package/hooks/blocking/state_description_blocker.py +1 -1
- package/hooks/blocking/stop_dispatcher.py +1 -1
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +2 -3
- package/hooks/blocking/test_code_review_pr_create_gate.py +14 -0
- package/hooks/blocking/test_code_review_push_gate.py +16 -0
- package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +19 -0
- package/hooks/blocking/test_eli11_reply_enforcer.py +457 -0
- package/hooks/blocking/test_orchestrator_refresh_reschedule_gate.py +231 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +10 -1
- package/hooks/blocking/test_shell_substitution_blocker.py +124 -0
- package/hooks/blocking/test_stop_dispatcher.py +23 -0
- package/hooks/blocking/test_unscoped_search_blocker.py +102 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +804 -808
- package/hooks/blocking/test_verification_verdict_store.py +54 -0
- package/hooks/blocking/test_verified_commit_gate.py +581 -581
- package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +131 -131
- package/hooks/blocking/unscoped_search_blocker.py +391 -0
- package/hooks/blocking/verdict_directory_write_blocker.py +687 -687
- package/hooks/blocking/verification_verdict_store.py +1039 -1036
- package/hooks/blocking/verified_commit_message_accuracy_blocker.py +167 -167
- package/hooks/blocking/verifier_verdict_minter.py +280 -280
- package/hooks/git-hooks/CLAUDE.md +3 -0
- package/hooks/git-hooks/conftest.py +30 -0
- package/hooks/git-hooks/gate_utils.py +2 -2
- package/hooks/git-hooks/git_hooks_constants/__init__.py +41 -2
- package/hooks/git-hooks/pre_push.py +75 -4
- package/hooks/git-hooks/pre_push_base_reference.py +166 -0
- package/hooks/git-hooks/test_config.py +0 -15
- package/hooks/git-hooks/test_gate_utils.py +3 -15
- package/hooks/git-hooks/test_pre_commit.py +1 -15
- package/hooks/git-hooks/test_pre_push.py +257 -23
- package/hooks/git-hooks/test_pre_push_base_reference.py +339 -0
- package/hooks/hooks.json +10 -12
- package/hooks/hooks_constants/CLAUDE.md +7 -2
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +4 -4
- package/hooks/hooks_constants/eli11_reply_enforcer_constants.py +101 -0
- package/hooks/hooks_constants/enter_worktree_prefetch_constants.py +18 -18
- package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +2 -8
- package/hooks/hooks_constants/orchestrator_refresh_reschedule_gate_constants.py +48 -0
- package/hooks/hooks_constants/ruff_integration_constants.py +16 -0
- package/hooks/hooks_constants/shell_command_segments.py +82 -0
- package/hooks/hooks_constants/shell_substitution_blocker_constants.py +67 -0
- package/hooks/hooks_constants/stop_dispatcher_constants.py +1 -0
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +5 -6
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +1 -0
- package/hooks/hooks_constants/unscoped_search_blocker_constants.py +153 -0
- package/hooks/lifecycle/enter_worktree_origin_prefetch.py +163 -146
- package/hooks/lifecycle/test_enter_worktree_origin_prefetch.py +185 -178
- package/hooks/pyproject.toml +1 -0
- package/hooks/validators/CLAUDE.md +1 -0
- package/hooks/validators/config/__init__.py +0 -0
- package/hooks/validators/config/directory_exemption_constants.py +183 -0
- package/hooks/validators/config/test_directory_exemption_constants.py +21 -0
- package/hooks/validators/conftest.py +4 -0
- package/hooks/validators/ruff_integration.py +49 -5
- package/hooks/validators/run_all_validators.py +206 -9
- package/hooks/validators/test_directory_exemption_constants.py +185 -0
- package/hooks/validators/test_python_antipattern_checks.py +110 -5
- package/hooks/validators/test_ruff_integration.py +92 -1
- package/hooks/validators/test_run_all_validators.py +115 -68
- package/hooks/validators/test_run_all_validators_pretooluse.py +159 -1
- package/package.json +13 -3
- package/rules/CLAUDE.md +17 -22
- package/rules/agent-spawn-protocol.md +6 -6
- package/rules/anti-corollary-tests.md +1 -1
- package/rules/bdd.md +1 -1
- package/rules/cleanup-temp-files.md +10 -4
- package/rules/code-standards.md +7 -0
- package/rules/conservative-action.md +1 -5
- package/rules/context7.md +0 -4
- package/rules/destructive-commands.md +47 -0
- package/rules/doc-inventory-integrity.md +48 -0
- package/rules/doc-prose-cuts.md +58 -0
- package/rules/docstring-prose-matches-implementation.md +53 -44
- package/rules/durable-post-artifacts.md +0 -4
- package/rules/eli11-replies.md +31 -0
- package/rules/explore-thoroughly.md +4 -4
- package/rules/falsify-before-green.md +68 -0
- package/rules/file-global-constants.md +1 -1
- package/rules/filesystem-search.md +51 -0
- package/rules/gh-cli-conventions.md +27 -0
- package/rules/git-workflow.md +26 -0
- package/rules/hedging-claims.md +9 -0
- package/rules/long-horizon-autonomy.md +0 -4
- package/rules/measurement-denominators.md +48 -0
- package/rules/nas-ssh-invocation.md +23 -5
- package/rules/parallel-tools.md +2 -2
- package/rules/plain-illustrative-docstrings.md +3 -7
- package/rules/plain-language.md +2 -0
- package/rules/proof-of-work-pr-comments.md +0 -4
- package/rules/re-stage-before-commit.md +2 -0
- package/rules/research-mode.md +10 -0
- package/rules/shell-invocation.md +21 -0
- package/rules/testing.md +4 -0
- package/rules/verified-commit-gate-skip.md +3 -27
- package/rules/verify-before-asking.md +5 -0
- package/rules/windows-filesystem-safe.md +1 -1
- package/rules/workers-done-before-complete.md +4 -0
- package/scripts/CLAUDE.md +1 -0
- package/scripts/Capture-PoolHealth.ps1 +410 -0
- package/scripts/Migrate-ShellPolicy.ps1 +1 -1
- package/scripts/_code_review_test_support.py +404 -0
- package/scripts/claude_chain_runner.py +141 -1
- package/scripts/codex_capability_bridge.py +171 -0
- package/scripts/codex_compat_materializer.py +1087 -0
- package/scripts/codex_compat_watcher.py +502 -0
- package/scripts/conftest.py +16 -1
- package/scripts/dev_env_scripts_constants/CLAUDE.md +1 -1
- package/scripts/dev_env_scripts_constants/claude_chain_constants.py +9 -0
- package/scripts/dev_env_scripts_constants/code_review_constants.py +37 -0
- package/scripts/invoke_code_review.py +11 -4
- package/scripts/resolve_worker_spawn.py +626 -626
- package/scripts/spawn_grok_batch.py +672 -672
- package/scripts/sync_to_cursor/rules.py +0 -10
- package/scripts/test_claude_chain_runner.py +131 -0
- package/scripts/test_invoke_code_review.py +85 -908
- package/scripts/test_invoke_code_review_chain.py +70 -0
- package/scripts/test_invoke_code_review_cli.py +192 -0
- package/scripts/test_invoke_code_review_contract.py +256 -0
- package/scripts/test_invoke_code_review_git.py +123 -0
- package/scripts/test_invoke_code_review_mode.py +99 -0
- package/scripts/test_resolve_worker_spawn.py +1014 -1014
- package/scripts/tests/test_code_review_constants.py +80 -0
- package/scripts/tests/test_codex_capability_bridge.py +91 -0
- package/scripts/tests/test_codex_compat_materializer.py +632 -0
- package/scripts/tests/test_codex_compat_watcher.py +599 -0
- package/scripts/tests/test_sync_to_cursor.py +0 -1
- package/skills/CLAUDE.md +2 -0
- package/skills/auditing-claude-config/SKILL.md +114 -114
- package/skills/autoconverge/SKILL.md +427 -427
- package/skills/autoconverge/reference/convergence.md +24 -3
- package/skills/autoconverge/workflow/CLAUDE.md +1 -0
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +3 -3
- package/skills/autoconverge/workflow/converge.contract.test.mjs +1263 -1263
- package/skills/autoconverge/workflow/converge.mjs +168 -1
- package/skills/autoconverge/workflow/converge.p2-advance.test.mjs +202 -0
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +265 -265
- package/skills/bugteam/reference/copilot-gap-analysis.md +1 -1
- package/skills/closeout/SKILL.md +33 -50
- package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +8 -0
- package/skills/codex-review/scripts/run_codex_review.py +233 -1
- package/skills/codex-review/scripts/test_run_codex_review.py +189 -0
- package/skills/condensing-instructions/SKILL.md +72 -0
- package/skills/copilot-review/SKILL.md +119 -119
- package/skills/e-code-review/SKILL.md +52 -0
- package/skills/e-code-review/reference/fix.md +54 -0
- package/skills/e-code-review/reference/loop.md +43 -0
- package/skills/e-code-review/reference/low.md +57 -0
- package/skills/e-code-review/reference/medium.md +153 -0
- package/skills/e-code-review/reference/xhigh.md +182 -0
- package/skills/e-simplify/SKILL.md +97 -0
- package/skills/fresh-branch/CLAUDE.md +1 -1
- package/skills/fresh-branch/SKILL.md +5 -6
- package/skills/fresh-branch/scripts/create_fresh_branch.py +42 -24
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +1 -3
- package/skills/fresh-branch/scripts/test_create_fresh_branch.py +30 -126
- package/skills/issue-tracker/SKILL.md +92 -0
- package/skills/issue-tracker/reference/epic-and-sub-issue-model.md +55 -0
- package/skills/issue-tracker/reference/handoff-schema.md +64 -0
- package/skills/issue-tracker/reference/operation-matrix.md +41 -0
- package/skills/orchestrator/SKILL.md +177 -22
- package/skills/orchestrator/scripts/status_gate.py +625 -0
- package/skills/orchestrator/scripts/status_gate_constants/__init__.py +1 -0
- package/skills/orchestrator/scripts/status_gate_constants/config/__init__.py +1 -0
- package/skills/orchestrator/scripts/status_gate_constants/config/constants.py +47 -0
- package/skills/orchestrator/scripts/test_status_gate.py +439 -0
- package/skills/orchestrator-refresh/SKILL.md +129 -35
- package/skills/plan-to-pr/SKILL.md +155 -0
- package/skills/plan-to-pr/reference/final-validation-tasks.md +15 -0
- package/skills/plan-to-pr/reference/model-routing.md +36 -0
- package/skills/plan-to-pr/reference/packet-contract.md +43 -0
- package/skills/plan-to-pr/reference/packet-schema.json +57 -0
- package/skills/plan-to-pr/reference/process-inventory.md +22 -0
- package/skills/plan-to-pr/reference/review-loop.md +33 -0
- package/skills/plan-to-pr/reference/run-record.schema.json +27 -0
- package/skills/plan-to-pr/reference/self-audit-tasks.md +15 -0
- package/skills/plan-to-pr/reference/task-seeds.md +14 -0
- package/skills/plan-to-pr/reference/task-ticket.md +38 -0
- package/skills/plan-to-pr/scripts/config/__init__.py +1 -0
- package/skills/plan-to-pr/scripts/config/constants.py +193 -0
- package/skills/plan-to-pr/scripts/create_packet.py +173 -0
- package/skills/plan-to-pr/scripts/test_create_packet.py +102 -0
- package/skills/plan-to-pr/scripts/test_validate_packet.py +256 -0
- package/skills/plan-to-pr/scripts/test_validate_protocol.py +135 -0
- package/skills/plan-to-pr/scripts/test_validate_run.py +158 -0
- package/skills/plan-to-pr/scripts/validate_packet.py +655 -0
- package/skills/plan-to-pr/scripts/validate_protocol.py +622 -0
- package/skills/plan-to-pr/scripts/validate_run.py +173 -0
- package/skills/plan-to-pr/test_skill_contract.py +207 -0
- package/skills/plan-to-pr/test_task_ticket_contract.py +151 -0
- package/skills/pr-converge/SKILL.md +472 -469
- package/skills/pr-converge/reference/examples.md +3 -3
- package/skills/pr-converge/reference/fix-protocol.md +1 -1
- package/skills/pr-converge/reference/ground-rules.md +7 -4
- package/skills/pr-converge/reference/multi-pr-orchestration.md +4 -1
- package/skills/pr-converge/reference/per-tick.md +5 -5
- package/skills/pr-converge/reference/progress-checklist.md +1 -1
- package/skills/pr-converge/scripts/check_convergence_gates.py +279 -279
- package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -507
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -84
- package/skills/pr-converge/test_step5_host_branch.py +1 -1
- package/skills/pr-fix-protocol/SKILL.md +1 -1
- package/skills/privacy-hygiene/SKILL.md +68 -68
- package/skills/privacy-hygiene/reference/sweep-procedure.md +1 -1
- package/skills/prototype/workflows/promotion.md +1 -1
- package/skills/release-notes-html/SKILL.md +164 -0
- package/skills/session-log/SKILL.md +1 -1
- package/skills/task-build/CLAUDE.md +8 -7
- package/skills/task-build/SKILL.md +16 -8
- package/skills/task-build/reference/tool-routing.md +19 -0
- package/rules/claude-md-orphan-file.md +0 -28
- package/rules/cleanup-command-forms.md +0 -23
- package/rules/code-reviews.md +0 -11
- package/rules/env-var-table-code-drift.md +0 -10
- package/rules/gh-body-file.md +0 -5
- package/rules/gh-paginate.md +0 -3
- package/rules/hook-prose-matches-detector.md +0 -15
- package/rules/no-historical-clutter.md +0 -26
- package/rules/no-inline-destructive-literals.md +0 -9
- package/rules/no-justification-noise.md +0 -61
- package/rules/package-inventory-stale-entry.md +0 -25
- package/rules/right-sized-engineering.md +0 -28
- package/rules/self-contained-docs.md +0 -17
- package/rules/shell-invocation-policy.md +0 -5
- package/rules/tdd.md +0 -7
- package/skills/closeout/reference/issue-body-templates.md +0 -108
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/CLAUDE.md"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Orphan File Reference in a Per-Directory CLAUDE.md
|
|
7
|
-
|
|
8
|
-
**When this applies:** Any Write, Edit, or MultiEdit to a file named `CLAUDE.md` that lists files in a markdown table whose first column names each file in backticks, or that shows run commands invoking those files inside fenced code blocks.
|
|
9
|
-
|
|
10
|
-
## Rule
|
|
11
|
-
|
|
12
|
-
Every bare filename a per-directory `CLAUDE.md` names points at a file that exists in the directory subtree the `CLAUDE.md` describes — both the filenames its table cells list and the scripts its fenced run commands invoke (`python script.py`). A table cell or a run command naming a file that exists nowhere in that subtree points a reader at something that is not there: the doc claims a file the directory does not hold.
|
|
13
|
-
|
|
14
|
-
When you add a table row or a run command, the file it names already exists in this directory or a subdirectory of it. When you remove a file, drop the row and the run command that named it.
|
|
15
|
-
|
|
16
|
-
## What the gate checks
|
|
17
|
-
|
|
18
|
-
The `claude_md_orphan_file_blocker.py` hook runs on every Write, Edit, and MultiEdit whose target basename is `CLAUDE.md`. It:
|
|
19
|
-
|
|
20
|
-
1. Reads the content the tool would leave on disk. For a Write that is the full `content`. For an Edit or MultiEdit it reconstructs the post-edit file — the existing on-disk file with the replacements applied — and also notes which orphans the file already held before the edit, so a pre-existing orphan on an untouched line is excluded and only an orphan the edit introduces is reported; when the existing file cannot be read, it scans the raw `new_string` fragment(s) instead.
|
|
21
|
-
2. Collects two kinds of referenced filename. Table cells: the first column of each markdown table row **outside** a fenced code block, keeping cells that name a bare filename wrapped in backticks, no path separator, not a slash-command, ending in a known file extension (`.py`, `.md`, `.json`, `.mjs`, `.js`, `.ts`, `.ps1`, `.cmd`, `.ahk`, `.yml`, `.yaml`, `.sh`, `.txt`, `.cfg`, `.toml`, `.ini`). Run commands: each line **inside** a fenced code block (between a ``` or `~~~` fence pair) that invokes an interpreter (`python`, `python.exe`, `python3`, `node`, `pwsh`, `powershell`, `bash`, `sh`, `ruby`, `perl`) on a script, taking that script's basename when it ends in `.py`, `.mjs`, `.js`, `.ts`, `.ps1`, `.sh`, `.rb`, or `.pl`. A fenced *table row* is an example, not a live listing, so it contributes no table-cell filename; a fenced *run command* is the contract a reader runs, so its script filename is checked.
|
|
22
|
-
3. Blocks the write when a referenced filename — from a table cell or a fenced run command — exists nowhere under the scan root — the `CLAUDE.md` directory's parent, which covers the directory, its subdirectories, and its siblings. A filesystem error that halts the whole subtree walk fails open (the write proceeds), so an unreadable tree never blocks a write.
|
|
23
|
-
|
|
24
|
-
The check stays quiet for a target that is not a `CLAUDE.md`, for a table cell that holds a path, a subdirectory ending in `/`, or a slash-command, for a table row inside a fenced code block, for an inline `python x.py` mention outside a fence (prose, not a runnable contract), and for a table whose content names an explicit relative-path source (a `../` token), since that table documents files that sit outside the subtree by design.
|
|
25
|
-
|
|
26
|
-
## Why this is a hook, not a lint pass
|
|
27
|
-
|
|
28
|
-
A table row or a run command that names an absent file reads as a contract: a reader trusts the listing to map the directory and trusts the shown command to run. A wrong row sends the reader looking for a file that is not there; a stale run command fails the moment the reader runs it. Both erode trust in every other entry. Catching them as each line is written keeps the doc and the directory in step.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Cleanup Command Forms
|
|
2
|
-
|
|
3
|
-
Never use bash `rm` in any form to clean up. The `destructive_command_blocker` hook watches every Bash-tool command and matches `rm -rf` (and the rest of the destructive patterns) as raw text. It allows an `rm` without a prompt only for a narrow set of shapes it can prove safe: an `rm` whose every target is an absolute path under the OS temp root, `/tmp`, `/temp`, or a worktrees directory — standalone, or in a chain whose other segments are plain reporting commands such as `echo` or `cat`; an `rm` run from an ephemeral working directory; and an `rm` whose every target sits inside `~/.claude`. It falls through to a permission prompt on anything outside that set: a `$`, `$(...)`, or backtick expansion whose value it cannot resolve, a target it cannot place in a safe directory, a glob basename, or a string-executing wrapper (`bash -c 'rm -rf …'`). In a background or auto-mode run no human can answer that prompt, so the call stalls.
|
|
4
|
-
|
|
5
|
-
Remove files with these forms, which the hook never prompts on:
|
|
6
|
-
|
|
7
|
-
- **Scratch and probe files:** the PowerShell tool — `Remove-Item -Recurse -Force -Confirm:$false <absolute path>`. The hook watches only the Bash tool, so a PowerShell removal never reaches it. A file left in the OS temp dir or `$CLAUDE_JOB_DIR/tmp` is ephemeral and needs no explicit removal.
|
|
8
|
-
- **Worktrees:** `git worktree remove --force <path>`. This matches no destructive pattern.
|
|
9
|
-
- **When bash `rm` is unavoidable:** one standalone `rm` command, an absolute literal path under the OS temp root or a worktrees directory, no chaining, no variables, no globs. The hook auto-allows this shape without a prompt.
|
|
10
|
-
|
|
11
|
-
## Every subagent prompt carries the rule
|
|
12
|
-
|
|
13
|
-
A prompt-delivered directive reaches only the agent that gets it. An agent that spawns its own workers — review lenses, fix agents, verifiers — copies this line into every subagent prompt it issues, so a grandchild cleaning up its own probe file uses an allowed form:
|
|
14
|
-
|
|
15
|
-
> Never use bash rm in any form. Delete scratch/probe files with the PowerShell tool (Remove-Item -Recurse -Force -Confirm:$false <absolute path>), or leave them in the OS temp dir; remove worktrees only via git worktree remove --force.
|
|
16
|
-
|
|
17
|
-
Prefer that a child leaves its scratch files in place for the parent to remove at teardown with `Remove-Item`.
|
|
18
|
-
|
|
19
|
-
## Sibling rules
|
|
20
|
-
|
|
21
|
-
- [`no-inline-destructive-literals`](no-inline-destructive-literals.md) — keep a destructive literal out of the Bash command string even when it rides only as data.
|
|
22
|
-
- [`cleanup-temp-files`](cleanup-temp-files.md) — remove the scratch files a task created once the task is done.
|
|
23
|
-
- [`windows-filesystem-safe`](windows-filesystem-safe.md) — the safe `rmtree` / `force_rmtree` patterns for read-only Windows files.
|
package/rules/code-reviews.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Responding to Code Reviews
|
|
2
|
-
|
|
3
|
-
**When this applies:** GitHub PR review feedback on a branch you are fixing.
|
|
4
|
-
|
|
5
|
-
**MANDATORY PROTOCOL:**
|
|
6
|
-
|
|
7
|
-
1. Fetch ALL reviewer comments BEFORE any fixes
|
|
8
|
-
2. Create TodoWrite checklist - One item per comment
|
|
9
|
-
3. Fix systematically - Mark each todo complete
|
|
10
|
-
4. Reply to EACH comment inline
|
|
11
|
-
5. Create ONE review fix commit - DO NOT squash with original
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/*.md"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Env-Var Summary Table Names a Code File That Reads the Variable
|
|
7
|
-
|
|
8
|
-
Every row in an env-var summary table pairs an UPPER_SNAKE variable with a code-file path that reads it — written as `` | `GOOGLE_APPLICATION_CREDENTIALS` | `auth/google_auth.py` | ... | ``. When a code change removes the last read of a variable from a file, the same change drops or corrects the table row that names that file.
|
|
9
|
-
|
|
10
|
-
`env_var_table_code_drift_blocker.py` (PreToolUse on Write|Edit|MultiEdit of `.md`) blocks a row whose named code file exists yet never references the variable, and names the fix. For an Edit, drift a file already held on an untouched row is excluded; a row whose code file resolves nowhere stays quiet (the hook cannot prove the drift).
|
package/rules/gh-body-file.md
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# gh --body-file Rule
|
|
2
|
-
|
|
3
|
-
Every `gh` command carrying markdown body content (`gh pr create/edit/comment/review`, `gh issue create/edit/comment`) uses `--body-file <path>` with a temp file — never a `--body`/`-b` string, where backticks land on GitHub as literal `\``. Write the temp file BOM-free: `[IO.File]::WriteAllText($bodyPath, $body, [Text.UTF8Encoding]::new($false))`. MCP GitHub tools take `body` as a structured parameter and are unaffected.
|
|
4
|
-
|
|
5
|
-
`gh_body_arg_blocker.py` (PreToolUse on Bash) blocks `--body <arg>` and returns the corrective message.
|
package/rules/gh-paginate.md
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
# gh API Pagination
|
|
2
|
-
|
|
3
|
-
Every `gh api` read of a paginated GitHub list endpoint (PR `reviews`/`comments`/`files`, issue `comments`, `pulls`, `issues`) uses `--paginate --slurp` piped to **external** `jq` — `gh`'s built-in `--jq` runs per page, so cross-page operations like `sort_by | last` give wrong-but-confident results. Single-object endpoints (`pulls/<n>`, `issues/<n>`) skip pagination and may use `--jq` directly. For a newest-first walk, sort the slurped array and take the last element; for single-page bounds, cap with a `per_page` query parameter.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths: **/hooks/**/*.py
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Hook Prose Matches Its Detector
|
|
6
|
-
|
|
7
|
-
A hook's docstring lead narrative and its `CORRECTIVE_MESSAGE` describe exactly the shapes the detector flags — no broader trigger surface than the regex enforces.
|
|
8
|
-
|
|
9
|
-
`hook_prose_detector_consistency` (PreToolUse on Write|Edit of hook modules and `*_constants.py` companions) blocks prose that claims a trigger the detector never fires on, and names the fix.
|
|
10
|
-
|
|
11
|
-
## Judgment
|
|
12
|
-
|
|
13
|
-
After writing a hook, ask: would a token that matches every word of this message actually trip the detector? When the message names a shape the regex skips, rewrite the message to name only what the regex catches.
|
|
14
|
-
|
|
15
|
-
The path-shape case is the common overstatement: a detector that keys off a path separator must not claim it blocks an "output-key segment". The corrective message spells the rewrite.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/*.md"
|
|
4
|
-
- "**/*.py"
|
|
5
|
-
- "**/*.mjs"
|
|
6
|
-
- "**/*.js"
|
|
7
|
-
- "**/*.ts"
|
|
8
|
-
- "**/*.ps1"
|
|
9
|
-
- "**/*.sh"
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# No Historical Clutter in Documentation or Comments
|
|
13
|
-
|
|
14
|
-
Never reference removed implementations, old defaults, prior behaviors, or earlier contracts when updating documentation or comments. The current state is all that matters. A module or function docstring carries the same describe-current-state-only contract as a `.md` file.
|
|
15
|
-
|
|
16
|
-
`state_description_blocker` (PreToolUse on Write|Edit) blocks historical and comparative phrases in `.md` prose, code comments, and Python docstrings; a phrase wrapped in double quotes or backticks inside a docstring counts as a mention and is skipped. The denial names the matched phrases and shows a rewrite example.
|
|
17
|
-
|
|
18
|
-
## What stays allowed
|
|
19
|
-
|
|
20
|
-
- Comparisons to alternatives that still exist (for example, "use `--paginate --slurp | jq`, not `--jq` alone")
|
|
21
|
-
- Rationale that explains why a pattern is wrong in terms of present behavior (for example, "`--jq` runs per-page, so cross-page operations produce wrong results")
|
|
22
|
-
- References to external sources for defects that still exist (for example, gh CLI #10459)
|
|
23
|
-
|
|
24
|
-
## The test
|
|
25
|
-
|
|
26
|
-
After writing, ask: if someone reads this a year from now with no knowledge of earlier states, does every sentence still make sense and add value? If a sentence only helps someone who knew an earlier state, delete it.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# No Inline Destructive-Command Literals in Bash
|
|
2
|
-
|
|
3
|
-
The `destructive_command_blocker` PreToolUse hook matches destructive patterns (`rm -rf`, `git reset --hard`, `dd`, `mkfs`, `chmod -R`, fork bombs) as raw text anywhere in a Bash-tool command, with no quote-awareness — so a destructive literal carried only as data (a commit message, a PR/issue body, an echoed string, a `python -c` / `node -e` / `awk` argument, a heredoc) trips the confirmation prompt even though the shell never executes it. In a background or auto-mode run no human can answer that prompt, so the call stalls.
|
|
4
|
-
|
|
5
|
-
Keep destructive literals out of the Bash command string:
|
|
6
|
-
|
|
7
|
-
- Bodies that describe destructive-command behavior go in a file passed by path — `git commit -F <file>`, `gh ... --body-file <file>` (see [`gh-body-file`](gh-body-file.md)) — never `git commit -m` / `gh ... -b`.
|
|
8
|
-
- To exercise or verify the blocker (or any hook), run the committed test suite (`python -m pytest <test_file>`), which passes the command strings as in-language data — never an inline `python -c` harness.
|
|
9
|
-
- Genuine cleanup targets the OS temp dir or `$CLAUDE_JOB_DIR/tmp` (auto-allowed as ephemeral), never a repository or worktree path.
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/*.md"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# No Justification Noise in Documentation
|
|
7
|
-
|
|
8
|
-
**When this applies:** Any Write or Edit to a `.md` file.
|
|
9
|
-
|
|
10
|
-
## Rule
|
|
11
|
-
|
|
12
|
-
Markdown states what the system is and does, in facts a reader can act on. Cut any sentence whose only job is to say why a choice is good, or to restate a gain the reader already works out from the stated behavior or from a rule a hook or another file enforces. A sentence like that carries no new fact — it repeats one the reader already holds, so it earns no space.
|
|
13
|
-
|
|
14
|
-
## The test
|
|
15
|
-
|
|
16
|
-
For each sentence, ask: **does it state a fact the reader can act on that they could not already work out from the behavior around it or from a rule enforced elsewhere?** If no, cut the sentence.
|
|
17
|
-
|
|
18
|
-
## Two shapes to catch
|
|
19
|
-
|
|
20
|
-
### Pure noise — cut the whole sentence
|
|
21
|
-
|
|
22
|
-
A sentence whose only job is to point out a result that follows from a fact the doc already states.
|
|
23
|
-
|
|
24
|
-
> Autoconverge's bug-audit and self-review lenses and pr-converge's CODE_REVIEW step point at this file and read it when they run; they do not carry its text in their spawn prompts, so the checklist stays out of the per-round token budget.
|
|
25
|
-
|
|
26
|
-
The doc already states the lenses read the file. The "so it stays out of the token budget" tail is a result the reader works out alone, so it carries nothing. Cut the sentence.
|
|
27
|
-
|
|
28
|
-
### Load-bearing first, noise after — keep the fact, cut the rest
|
|
29
|
-
|
|
30
|
-
A sentence that states a real fact, trailed by prose that only re-argues it or restates its payoff.
|
|
31
|
-
|
|
32
|
-
> The pre-catch stage drives the code to clean against these five lanes before any external reviewer sees it. External reviewers (Cursor Bugbot, GitHub Copilot) are terminal confirmation gates that run only after every lane below is clean, and they are expected to return zero findings.
|
|
33
|
-
|
|
34
|
-
Keep the first sentence — it states what the stage does. Cut the second: "run only after every lane below is clean" repeats the first sentence's claim, and "expected to return zero findings" is a hoped-for result, not a fact the reader acts on.
|
|
35
|
-
|
|
36
|
-
## What stays
|
|
37
|
-
|
|
38
|
-
- A fact the reader acts on: an input a piece of code takes, an order a producer emits, a path a script writes.
|
|
39
|
-
- A rule's one-line reason stated in terms of present behavior — `--jq` runs per page, so cross-page sorts give wrong results — because that reason names a fact the reader needs to pick the right call.
|
|
40
|
-
- A tradeoff or a constraint the reader weighs before choosing a path.
|
|
41
|
-
|
|
42
|
-
## Sibling rules
|
|
43
|
-
|
|
44
|
-
This rule sits beside three others; each cuts a different kind of dead prose.
|
|
45
|
-
|
|
46
|
-
| Rule | Cuts |
|
|
47
|
-
|---|---|
|
|
48
|
-
| `no-historical-clutter.md` | references to old state (`previously`, `migrated from`) |
|
|
49
|
-
| `self-contained-docs.md` | references to the chat that produced the doc |
|
|
50
|
-
| `plain-language.md` | heavy words with an everyday swap |
|
|
51
|
-
| `no-justification-noise.md` | a present-tense sentence that only justifies or restates a fact the reader already holds |
|
|
52
|
-
|
|
53
|
-
`no-historical-clutter.md` keeps a rule's reason when the reason names present behavior; this rule keeps the same reason for the same test. The two agree: a reason that names a fact the reader acts on stays, and a sentence that only re-argues a stated fact goes.
|
|
54
|
-
|
|
55
|
-
## Enforcement
|
|
56
|
-
|
|
57
|
-
The AI review lane carries this rule: `AGENTS.md` names it as a finding an agent applies to the `.md` lines a PR changes. No hook backs it, because telling a justification sentence from a load-bearing one needs meaning a regex cannot read.
|
|
58
|
-
|
|
59
|
-
## Why
|
|
60
|
-
|
|
61
|
-
A sentence that repeats a fact the reader already holds costs reading time and pays back nothing.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/*.py"
|
|
4
|
-
- "**/*.mjs"
|
|
5
|
-
- "**/*.js"
|
|
6
|
-
- "**/*.ts"
|
|
7
|
-
- "**/*.ps1"
|
|
8
|
-
- "**/*.sh"
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# New Production File Absent From Its Package Inventory
|
|
12
|
-
|
|
13
|
-
A package directory that documents its own files in a `README.md` Layout table, a `CLAUDE.md` "Key files" list, or a skill `SKILL.md` Layout table keeps that inventory in step with the directory. When you create a new production file in such a directory, add an entry naming it — a row in the table or a bullet in the list — in the same change. The entry names the file in backticks and says what it does.
|
|
14
|
-
|
|
15
|
-
`package_inventory_stale_blocker.py` (PreToolUse on Write) blocks a new production file whose basename appears in no present inventory and names the fix. A skill `SKILL.md` Layout table that maps `scripts/` counts as the inventory for files in that subdirectory.
|
|
16
|
-
|
|
17
|
-
## Judgment the gate cannot derive
|
|
18
|
-
|
|
19
|
-
The file-list entry is the slice the gate checks by name. Two free-prose slices stay with judgment and belong in the same change:
|
|
20
|
-
|
|
21
|
-
1. **Purpose / scope sentence.** When the new module adds a responsibility the package `## Purpose` (or the parent inventory's one-line summary of this subdirectory) omits, broaden that sentence to name it. A hook cannot derive a module's responsibility from its filename.
|
|
22
|
-
|
|
23
|
-
2. **Per-file description clause.** When a file gains a responsibility the inventory's em-dash description omits — a new public function, a new module-level constant — broaden the description clause to name it. The gate only checks that the basename appears once; it never reads the description. Constants modules (`*_constants.py`, or any `.py` directly inside `config/`) are the common shape: the constant's other home is the module docstring, so the clause that lands in the docstring lands in the inventory description in the same change. The gate fires on Write of a new file and skips files directly inside `config/`, so an Edit that adds a constant to an existing config module matches neither path.
|
|
24
|
-
|
|
25
|
-
This is the `category-o-docstring-vs-impl-drift` (O8) orphaned-doc-claim shape applied to a package inventory.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Right-Sized Engineering
|
|
2
|
-
|
|
3
|
-
**Build it right, but build it simple.** Good engineering principles at the appropriate scale.
|
|
4
|
-
|
|
5
|
-
## Always Do
|
|
6
|
-
- Extract constants and configuration (no hardcoding)
|
|
7
|
-
- Create reusable functions (no copy-paste)
|
|
8
|
-
- Use proper error handling
|
|
9
|
-
- Follow DRY from the start
|
|
10
|
-
- Single responsibility per function
|
|
11
|
-
|
|
12
|
-
## Never Do (Solo Scale)
|
|
13
|
-
- Abstract base classes for single implementations
|
|
14
|
-
- Dependency injection frameworks
|
|
15
|
-
- Complex patterns (CQRS, microservices)
|
|
16
|
-
- Multiple inheritance hierarchies
|
|
17
|
-
- Over-abstracted interfaces
|
|
18
|
-
|
|
19
|
-
## Complexity Budget
|
|
20
|
-
|
|
21
|
-
**State BEFORE implementation:** Files (target 1-2, max 3), Lines (~50-300), Checkpoints ("Is this MINIMUM?", "Fewer files?", "Functions vs classes?")
|
|
22
|
-
|
|
23
|
-
## YAGNI for API Surface
|
|
24
|
-
|
|
25
|
-
**Don't expose optional parameters until they're actually used.**
|
|
26
|
-
|
|
27
|
-
If a value will always be a constant for now, use the constant internally.
|
|
28
|
-
Only add the parameter when callers actually need to vary it.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Self-Contained Documentation
|
|
2
|
-
|
|
3
|
-
**When this applies:** All generated artifacts — gists, decision docs, PR descriptions, issue bodies, plans, SKILL.md content. Exception: Obsidian session logs (intentionally conversation-scoped).
|
|
4
|
-
|
|
5
|
-
## Rule
|
|
6
|
-
|
|
7
|
-
Every document must be fully self-contained. A reader with zero prior context must understand every statement without needing access to the conversation that produced it.
|
|
8
|
-
|
|
9
|
-
## Patterns to Catch and Replace
|
|
10
|
-
|
|
11
|
-
| Pattern | Example | Fix |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| References to options/choices discussed in conversation | "This is not Option A from the original framing" | Delete the sentence, or restate the decision on its own terms |
|
|
14
|
-
| "As discussed" / "as we decided" / "from the prior session" | "As discussed, we'll use embeddings" | "Sref matching uses sentence-transformer embeddings" |
|
|
15
|
-
| Pronouns pointing to conversation context | "This approach addresses the concerns raised earlier" | State what the concerns were inline, or delete |
|
|
16
|
-
| Relative framing ("instead of X") where X was only discussed verbally | "Instead of the three options considered" | State the chosen approach directly without referencing alternatives the reader can't see |
|
|
17
|
-
| Session-specific sequencing | "After Round 3 we decided..." | State the decision as a fact |
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# Shell Invocation Policy (pwsh-only)
|
|
2
|
-
|
|
3
|
-
Every Bash-tool shell command on Windows uses `pwsh`: `pwsh -NoProfile -File '<script>.ps1' <args>` for scripts, `pwsh -NoProfile -Command "..."` (or a literal `@'...'@` here-string) for inline work, or the built-in `PowerShell` tool for pure-PowerShell workflows (it supports `run_in_background`). Never wrap a script path in `-Command "& '...'"` — `-File` keeps `permissions.allow` matching. The `&` call operator is fine for invoking an executable at a path (`& '<venv>\Scripts\python.exe' script.py`).
|
|
4
|
-
|
|
5
|
-
Keep `powershell`, `powershell.exe`, `cmd /c`, and `bash -c` out of the `settings.json` permission rules. `Audit-ShellPolicy.ps1` reports those forms and `Migrate-ShellPolicy.ps1` rewrites them to `pwsh`, both in `packages/claude-dev-env/scripts/` and run on demand, not as a live gate.
|
package/rules/tdd.md
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# TDD Process: Red-Green-Refactor
|
|
2
|
-
|
|
3
|
-
**TEST-DRIVEN DEVELOPMENT IS NON-NEGOTIABLE.** Every single line of production code must be written in response to a failing test. No exceptions.
|
|
4
|
-
|
|
5
|
-
1. **Red**: Write failing test. NO PRODUCTION CODE.
|
|
6
|
-
2. **Green**: MINIMUM code to pass. Resist urge for more.
|
|
7
|
-
3. **Refactor**: Assess improvements. Only if valuable.
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# Issue body templates
|
|
2
|
-
|
|
3
|
-
Body shapes for the parent tracking issue and its child issues, plus a worked example. Every body is self-contained: a reader with zero session context understands it. Every body carries a quoted line of evidence captured this session. Write each body to a temp file and pass it with `gh issue create --body-file <path>`.
|
|
4
|
-
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- [Child issue body](#child-issue-body)
|
|
8
|
-
- [Parent tracking issue body](#parent-tracking-issue-body)
|
|
9
|
-
- [Worked example — child](#worked-example--child)
|
|
10
|
-
- [Worked example — parent](#worked-example--parent)
|
|
11
|
-
- [Body rules](#body-rules)
|
|
12
|
-
|
|
13
|
-
## Child issue body
|
|
14
|
-
|
|
15
|
-
One obstacle per child. Fill every section:
|
|
16
|
-
|
|
17
|
-
```markdown
|
|
18
|
-
## What happened
|
|
19
|
-
|
|
20
|
-
<One sentence: the failure mode, in plain terms.>
|
|
21
|
-
|
|
22
|
-
## Evidence
|
|
23
|
-
|
|
24
|
-
<The verbatim line captured this session — error text, command, or log line — in a fenced block.>
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
<exact quoted text>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Where
|
|
31
|
-
|
|
32
|
-
<The file, hook, gate, or tool the evidence names. Path relative to the repo root.>
|
|
33
|
-
|
|
34
|
-
## Impact
|
|
35
|
-
|
|
36
|
-
<What the obstacle cost: work blocked, count of times hit, workaround forced.>
|
|
37
|
-
|
|
38
|
-
## Proposed fix
|
|
39
|
-
|
|
40
|
-
<The specific change. Name the failure mode and the condition, not "improve error handling".>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Parent tracking issue body
|
|
44
|
-
|
|
45
|
-
The parent gathers the children. Its body is a checklist, one line per child created:
|
|
46
|
-
|
|
47
|
-
```markdown
|
|
48
|
-
## Session closeout — <short session label>
|
|
49
|
-
|
|
50
|
-
Obstacles this session, filed as child issues:
|
|
51
|
-
|
|
52
|
-
- [ ] owner/repo#<N> — <child title>
|
|
53
|
-
- [ ] owner/repo#<N> — <child title>
|
|
54
|
-
- [ ] owner/repo#<N> — <child title>
|
|
55
|
-
|
|
56
|
-
## Handoff
|
|
57
|
-
|
|
58
|
-
A cloud handoff prompt for these issues was printed in the closing session. It carries the safety boundaries, base branch, per-package verification commands, and the dependency order among the children.
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Worked example — child
|
|
62
|
-
|
|
63
|
-
```markdown
|
|
64
|
-
## What happened
|
|
65
|
-
|
|
66
|
-
The code_rules_enforcer hook blocked a valid list literal in a test file, where test files are exempt from the magic-value gate.
|
|
67
|
-
|
|
68
|
-
## Evidence
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
BLOCKED: [MAGIC_VALUE] Inline list literal [200, 404, 500] in a function body -- extract to a named constant in config/.
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Where
|
|
75
|
-
|
|
76
|
-
packages/claude-dev-env/hooks/blocking/code_rules_enforcer.py — the inline-collection check.
|
|
77
|
-
|
|
78
|
-
## Impact
|
|
79
|
-
|
|
80
|
-
Hit 3 times in one session on three test files. Forced a workaround: moving each literal to a module constant the test did not need.
|
|
81
|
-
|
|
82
|
-
## Proposed fix
|
|
83
|
-
|
|
84
|
-
Extend the test-file exemption that already covers the magic-value gate to also cover the inline-collection check, so list and set literals in test bodies pass.
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Worked example — parent
|
|
88
|
-
|
|
89
|
-
```markdown
|
|
90
|
-
## Session closeout — hook exemptions for test files
|
|
91
|
-
|
|
92
|
-
Obstacles this session, filed as child issues:
|
|
93
|
-
|
|
94
|
-
- [ ] jl-cmd/claude-dev-env#101 — inline-collection gate fires in exempt test files
|
|
95
|
-
- [ ] jl-cmd/claude-dev-env#102 — boolean-naming gate flags a fixture variable
|
|
96
|
-
|
|
97
|
-
## Handoff
|
|
98
|
-
|
|
99
|
-
A cloud handoff prompt for these issues was printed in the closing session. It carries the safety boundaries, base branch, per-package verification commands, and the dependency order among the children.
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Body rules
|
|
103
|
-
|
|
104
|
-
- **Quoted evidence is required.** No child ships without a fenced block holding a line captured this session.
|
|
105
|
-
- **No volatile paths.** No temp dirs, worktrees, `$CLAUDE_JOB_DIR`, `.claude-editor/jobs`, or `.claude/worktrees` paths in any body. Paste text inline; for a binary artifact, upload it to a durable release and link that URL.
|
|
106
|
-
- **No chat references.** Drop "as discussed" and "the choice we picked". State each fact on its own.
|
|
107
|
-
- **Specific over vague.** "The gate fires on `[200, 404, 500]` in a test body" beats "the gate is too strict".
|
|
108
|
-
- **PII stripped.** Run the PII pass (see the PII redaction checklist) over every body before it reaches the confirmation gate.
|