Skip to content

fix: remove CLAUDECODE env var detection, centralize stripping#2883

Open
rysweet wants to merge 2 commits intomainfrom
fix/remove-claudecode-guard
Open

fix: remove CLAUDECODE env var detection, centralize stripping#2883
rysweet wants to merge 2 commits intomainfrom
fix/remove-claudecode-guard

Conversation

@rysweet
Copy link
Owner

@rysweet rysweet commented Mar 5, 2026

Summary

  • Removes all usage of the CLAUDECODE environment variable for adapter selection decisions. The Claude Code binary sets this to block nested sessions, but we always want nested sessions to work.
  • Creates a centralized build_child_env() utility in src/amplihack/recipes/adapters/env.py that handles stripping CLAUDECODE from child process environments in one place, replacing scattered implementations across 15 files.
  • Removes unset CLAUDECODE from shell scripts (run_recipe_subprocess.sh, orchestrator-generated run.sh) since the Python adapters now handle this centrally.
  • Updates get_adapter() to no longer check CLAUDECODE for adapter selection -- it now defaults to Claude SDK if available, then CLI subprocess.
  • Updates all tests to verify env stripping behavior without depending on CLAUDECODE detection logic.
  • Updates documentation (STREAMING_OUTPUT.md, RECENT_FIXES_MARCH_2026.md, SKILL.md, reference.md) to remove CLAUDECODE as a user-facing concern.

Follow-up to #2845 quality improvements.

Test plan

  • pytest tests/unit/recipes/test_cli_subprocess_temp_dir.py -- 8/8 pass
  • pytest tests/unit/recipes/test_streaming_adapters.py -- 15/15 pass (2 pre-existing failures excluded)
  • pytest tests/recipes/test_recipe_runner_parse_json.py -- 26/26 pass
  • Verified all 23 pre-existing test failures in tests/unit/recipes/ are identical to main branch (not introduced by this change)
  • CI passes

🤖 Generated with Claude Code

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

🤖 Auto-fixed version bump

The version in pyproject.toml has been automatically bumped to the next patch version.

If you need a minor or major version bump instead, please update pyproject.toml manually and push the change.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Repo Guardian - Action Required

❌ Ephemeral Content Detected

The following file violates the repository's ephemeral content policy:

docs/recipes/RECENT_FIXES_MARCH_2026.md

Why flagged:

  • Filename contains a temporal date ("MARCH_2026") indicating point-in-time content
  • Content explicitly states "This document tracks recent bug fixes" (emphasis mine)
  • Version history section says "All fixes released in amplihack v0.9.0 (March 2026)"
  • This is essentially release notes with a date stamp that will become stale

Problematic content:

# Recent Recipe Runner & Skills Fixes - March 2026

This document tracks recent bug fixes and improvements...

## Version History

All fixes released in **amplihack v0.9.0** (March 2026):
```

**Where this content should go instead:**

1. **CHANGELOG.md** - Add a section for v0.9.0 with these fixes
2. **GitHub Release Notes** - Create a release for v0.9.0 with this content
3. **PR descriptions** - The detailed explanations could be in individual PR descriptions
4. **Permanent reference docs** - The technical details (how features work) could be moved to timeless documentation without the "recent" framing

**Why this matters:**

Files with dates in their names and "recent" framing become outdated immediately. In 6 months, "recent fixes from March 2026" is no longer recent. This creates clutter and confusion about what's current.

---

### ✅ Override Available

To override this check and allow the file, add a PR comment containing:

```
repo-guardian:override (reason)

Where (reason) is a required non-empty justification explaining why this dated content should be permanently stored in the repository (e.g., "This is part of our versioned documentation strategy" or "This will be moved to release notes in a follow-up PR").

AI generated by Repo Guardian

@rysweet
Copy link
Owner Author

rysweet commented Mar 5, 2026

Workflow Retrofit: Outside-in Testing & Review Results

Step 12: Test Suite

  • tests/unit/recipes/ — 393 passed, 23 failed (all 23 pre-existing on main, 0 regressions)
  • tests/recipes/ — 66 passed, 0 failed
  • PR-specific tests (4 test files changed by PR) — 54 passed, 2 failed (both pre-existing on main: test_execute_bash_step_has_timeout)

Verdict: No test regressions introduced by this PR.

Step 17: Code Review

Findings:

  1. env.py is clean, minimal, and follows the brick pattern — single responsibility, extensible _STRIPPED_VARS frozenset.
  2. Both CLISubprocessAdapter and NestedSessionAdapter properly delegate to build_child_env().
  3. get_adapter() correctly removes the CLAUDECODE-based auto-selection of NestedSessionAdapter. SDK adapter is tried first, then CLI fallback. Nested can still be explicitly selected via preference="nested".
  4. All shell scripts (scripts/run_recipe_subprocess.sh, orchestrator run.sh generation) no longer contain unset CLAUDECODE.
  5. Documentation updated consistently across SKILL.md, reference.md, STREAMING_OUTPUT.md, and RECENT_FIXES_MARCH_2026.md.

Minor note (not blocking): tests/e2e/test_hook_startup_e2e.py:55 still does env.pop("CLAUDECODE", None) manually instead of using build_child_env(). This is arguably outside PR scope since it's an e2e test that spawns claude directly (not via an adapter), but could be cleaned up in a follow-up.

Step 17b: Security Review

  • build_child_env() copies ALL env vars except CLAUDECODE — PATH, HOME, USER, LANG, etc. are all preserved.
  • Only CLAUDECODE is stripped — no other vars are accidentally removed.
  • CLAUDE_PLUGIN_ROOT and CLAUDE_CODE_ENTRYPOINT are preserved (they are NOT blocking vars).
  • _STRIPPED_VARS is a frozenset, easily extensible if other vars need stripping in the future.
  • No information leakage or security concerns.

Step 13: Outside-in Testing (16/16 PASS)

All tests run with CLAUDECODE=1 set in the parent environment to simulate being inside Claude Code:

# Test Result
1 claude -p "What is 2+2?" without CLAUDECODE PASS
3 get_adapter() returns adapter without CLAUDECODE check PASS
4 build_child_env() strips CLAUDECODE, preserves PATH/HOME PASS
5 orchestrator.py no longer contains unset CLAUDECODE PASS
6 run_recipe_subprocess.sh no longer contains unset CLAUDECODE PASS
7 Session tree context propagated (depth incremented, tree ID preserved) PASS
8 Defaults generated when no session tree exists (depth 0->1, 8-char hex ID) PASS
9 NestedSessionAdapter delegates to build_child_env() PASS
10 CLISubprocessAdapter delegates to build_child_env() PASS
11 get_adapter(preference="nested") returns NestedSessionAdapter PASS
12 get_adapter(preference="cli") returns CLISubprocessAdapter PASS
13 build_child_env properly exported from adapters package PASS
14 claude -p runs successfully with build_child_env() cleaned env (CLAUDECODE=1 in parent) PASS
15 CLISubprocessAdapter.execute_agent_step works with CLAUDECODE=1 set PASS
16 NestedSessionAdapter.execute_agent_step works with CLAUDECODE=1 set PASS

Critical tests 14-16 verify the actual fix end-to-end: with CLAUDECODE=1 set in the parent process (simulating running inside Claude Code), both adapters successfully spawn nested claude -p sessions via build_child_env().

Summary

PR is clean. No regressions, no missed CLAUDECODE references in source code, security review passed, and all 16 outside-in tests pass including real nested Claude session execution.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Triage Report - FAST TRACK CANDIDATE

Risk Level: LOW
Priority: HIGH
Status: Ready for fast-track merge

Analysis

Net reduction: -28 LOC (simplification)
Centralization: Replaces scattered env var checks with single utility
Clean scope: 16 files but focused changes
Fresh: Created 9.5 hours ago

Rationale

This PR removes duplication and centralizes CLAUDECODE environment variable handling. The centralized build_child_env() utility replaces 15 scattered implementations - classic refactoring win.

Next Steps

  1. Wait for CI to pass
  2. Quick code review of centralized utility
  3. Merge if tests green - good candidate for fast-track

Recommendation: FAST_TRACK after CI validation.

AI generated by PR Triage Agent

The Claude Code binary sets CLAUDECODE to block nested sessions, but we
always want nested sessions to work. This change:

- Removes CLAUDECODE-based adapter selection logic from get_adapter()
- Creates centralized build_child_env() in adapters/env.py that strips
  CLAUDECODE from all child processes in one place
- Removes `unset CLAUDECODE` from shell scripts (Python adapters handle it)
- Updates tests to verify env stripping without depending on detection
- Updates documentation to remove CLAUDECODE as a user-facing concern

Follow-up to #2845 quality improvements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rysweet rysweet force-pushed the fix/remove-claudecode-guard branch from fb1ff86 to 2aec9ea Compare March 5, 2026 15:11
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

🤖 Auto-fixed version bump

The version in pyproject.toml has been automatically bumped to the next patch version.

If you need a minor or major version bump instead, please update pyproject.toml manually and push the change.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Repo Guardian - Action Required

❌ Ephemeral Content Detected

The following file violates the repository's ephemeral content policy:

docs/recipes/RECENT_FIXES_MARCH_2026.md

Why flagged:

  • Filename contains temporal date: "MARCH_2026" indicates point-in-time snapshot content
  • Explicitly describes itself as tracking "recent" fixes: Line 3 states "This document tracks recent bug fixes and improvements"
  • Version-specific content: States "All fixes released in amplihack v0.9.0 (March 2026)" suggesting this is a moment-in-time snapshot
  • Will become stale: As development continues, this document will become outdated historical notes rather than current reference material

Problematic content quotes:

Line 1: "Recent Recipe Runner & Skills Fixes - March 2026"
Line 3: "This document tracks recent bug fixes..."
Line 142: "All fixes released in amplihack v0.9.0 (March 2026)"
```

**Where this content should go instead:**
- **CHANGELOG.md** or **docs/CHANGELOG.md** — This is exactly what changelogs are for (date-stamped release notes)
- **Release notes** — GitHub Releases for v0.9.0
- **PR descriptions** — Individual PR #2813, #2807, #2804, #2811 already document these fixes
- **Permanent reference docs** — If specific fixes need long-term documentation, integrate them into the main docs without date stamps

**Recommendation:**
Move this content to `CHANGELOG.md` under a `## [0.9.0] - 2026-03` section, or integrate specific technical details (like YAML frontmatter requirements) into permanent reference documentation without the date stamp.

---

**To override this check**, add a comment containing:
```
repo-guardian:override (reason)

where (reason) is a required non-empty justification for allowing this file.

AI generated by Repo Guardian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant