claude-dev-env 8.46.9 → 8.46.11

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.
@@ -121,7 +121,7 @@ Do not write production behavior before RED, skip the red run, or call a green t
121
121
 
122
122
  ## Hook-specific workflow
123
123
 
124
- For a hook change, use the target package's active managed root for installed files, not the current working directory. The default is `~/.claude`; `--target` or `CLAUDE_CONFIG_DIR` selects another managed root. Read `<managed-root>/hooks/AGENTS.md` (default: `~/.claude/hooks/AGENTS.md`; source fallback: `packages/claude-dev-env/hooks/AGENTS.md`), each closer `AGENTS.md` and `CLAUDE.md`, and the registered hook entry before editing. Trace the lifecycle event, stdin JSON, output contract, exit code, and registration. Reuse the target hook area's constants package. Run `<managed-root>/scripts/check.ps1` (default: `~/.claude/scripts/check.ps1`; source fallback: `packages/claude-dev-env/scripts/check.ps1`) and drive the production entry point with event payloads. The RED test covers each allow and deny outcome. Run every applicable test file and suite for the hook, then the full quality gates required by the affected package.
124
+ For a hook change, use the target package's active managed root for installed files. The default is `~/.claude`; `--target` or `CLAUDE_CONFIG_DIR` selects another managed root. Read `<managed-root>/hooks/AGENTS.md` (default: `~/.claude/hooks/AGENTS.md`; source fallback: `packages/claude-dev-env/hooks/AGENTS.md`), each closer `AGENTS.md` and `CLAUDE.md`, and the registered hook entry before editing. Trace the lifecycle event, stdin JSON, output contract, exit code, and registration. Reuse the target hook area's constants package. Run `<managed-root>/scripts/check.ps1` (default: `~/.claude/scripts/check.ps1`; source fallback: `packages/claude-dev-env/scripts/check.ps1`) and drive the production entry point with event payloads. The RED test covers each allow and deny outcome. Run every applicable test file and suite for the hook, then the full quality gates required by the affected package.
125
125
 
126
126
  ## Session advisor
127
127
 
@@ -41,8 +41,8 @@ Treat scoped `AGENTS.md` files as the canonical repository and path rules. Treat
41
41
  For Category J, keep these sources separate:
42
42
 
43
43
  - Use the target repository's full review contract as the primary policy when available.
44
- - `docs/CODE_RULES.md` is a compact projection, not the full contract. Use it as a checklist.
45
- - `hooks/blocking/code_rules_enforcer.py` is hand-maintained write-time coverage. It shows what the hook checks, not whether other contract rules are absent.
44
+ - `docs/CODE_RULES.md` is a compact projection of the contract. Use it as a checklist.
45
+ - `hooks/blocking/code_rules_enforcer.py` is hand-maintained write-time coverage. It shows only what the hook checks.
46
46
 
47
47
  Record each Category J conclusion's policy source and hook coverage. Compact rules and hook results do not replace the canonical contract or scoped `AGENTS.md` rules.
48
48
 
@@ -199,7 +199,7 @@ When the primary and adversarial passes flag the same file:line:
199
199
  - Concatenate the `failure_mode` strings (separator: " // adversarial: ") so both pass narratives survive.
200
200
  - For Shape B entries on the same category, keep every distinct `adversarial_probe` from both passes — collapsing them would drop information that was found.
201
201
 
202
- The merge runs at the end of the adversarial pass, before constructing the output. The output preamble's `Total: N` counts merged findings, not pre-merge total.
202
+ The merge runs at the end of the adversarial pass, before constructing the output. The output preamble's `Total: N` counts merged findings.
203
203
 
204
204
  ## file:line Evidence Requirement
205
205
 
@@ -46,7 +46,7 @@ extract_javascript_comment_occurrences = (
46
46
  def check_comments_python(content: str) -> list[str]:
47
47
  """Check for comments in Python code.
48
48
 
49
- Uses ``tokenize.generate_tokens`` to find true ``COMMENT`` tokens.
49
+ Uses ``tokenize.generate_tokens`` to find ``COMMENT`` tokens.
50
50
  Hash characters that appear inside string literals (hex color codes,
51
51
  URL fragments, and the hash inside an f-string interpolation pattern)
52
52
  are correctly skipped because the tokenizer recognizes them as parts
package/hooks/conftest.py CHANGED
@@ -18,10 +18,28 @@ _is_ephemeral_script_path = importlib.import_module("code_rules_shared").is_ephe
18
18
  _EPHEMERAL_EXEMPT_DISABLE_ENVIRONMENT_VARIABLE_NAME = importlib.import_module(
19
19
  "hooks_constants.code_rules_enforcer_constants"
20
20
  ).EPHEMERAL_EXEMPT_DISABLE_ENVIRONMENT_VARIABLE_NAME
21
+ _CLAUDE_SESSION_ID_ENVIRONMENT_VARIABLE_NAME = importlib.import_module(
22
+ "hooks_constants.harness_scratchpad_constants"
23
+ ).CLAUDE_SESSION_ID_ENVIRONMENT_VARIABLE_NAME
21
24
 
22
25
  _ROOT_ANCHORED_PROBE_PATH = "/tmp/scratch.py"
23
26
 
24
27
 
28
+ @pytest.fixture(autouse=True)
29
+ def isolate_from_live_session_scratchpad(monkeypatch: pytest.MonkeyPatch) -> None:
30
+ """Remove the live harness session id before each hooks test.
31
+
32
+ A Claude Code session exports ``CLAUDE_CODE_SESSION_ID``. When this checkout
33
+ sits inside that session's scratchpad, the scratchpad predicate classifies
34
+ every repository file as throwaway scratch, and the gates under test step
35
+ aside. Tests that exercise the scratchpad match set their own session id.
36
+
37
+ Args:
38
+ monkeypatch: Pytest's environment-variable patcher, torn down after the test.
39
+ """
40
+ monkeypatch.delenv(_CLAUDE_SESSION_ID_ENVIRONMENT_VARIABLE_NAME, raising=False)
41
+
42
+
25
43
  @pytest.fixture
26
44
  def ephemeral_exempt_off(monkeypatch: pytest.MonkeyPatch) -> None:
27
45
  """Turn off the ephemeral scratch-path exemption for the current test.
@@ -0,0 +1,29 @@
1
+ """Tests for the shared fixtures in hooks/conftest.py."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import subprocess
7
+ import sys
8
+
9
+ from hooks_constants.harness_scratchpad_constants import (
10
+ CLAUDE_SESSION_ID_ENVIRONMENT_VARIABLE_NAME,
11
+ )
12
+
13
+
14
+ def test_live_session_id_is_absent_inside_each_test() -> None:
15
+ assert CLAUDE_SESSION_ID_ENVIRONMENT_VARIABLE_NAME not in os.environ
16
+
17
+
18
+ def test_hook_subprocess_inherits_no_live_session_id() -> None:
19
+ completed = subprocess.run(
20
+ [
21
+ sys.executable,
22
+ "-c",
23
+ f"import os; print(os.environ.get('{CLAUDE_SESSION_ID_ENVIRONMENT_VARIABLE_NAME}', ''))",
24
+ ],
25
+ capture_output=True,
26
+ text=True,
27
+ check=True,
28
+ )
29
+ assert completed.stdout.strip() == ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.46.9",
3
+ "version": "8.46.11",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {