Skip to content

fix(agent): register CLI channel factory for interactive mode#5802

Merged
singlerider merged 1 commit intozeroclaw-labs:masterfrom
singlerider:fix/agent-cli-channel-panic
Apr 16, 2026
Merged

fix(agent): register CLI channel factory for interactive mode#5802
singlerider merged 1 commit intozeroclaw-labs:masterfrom
singlerider:fix/agent-cli-channel-panic

Conversation

@singlerider
Copy link
Copy Markdown
Collaborator

@singlerider singlerider commented Apr 16, 2026

Summary

  • Base branch target (master for all contributions): master
  • Problem: zeroclaw agent (interactive, no -m) panics at startup with CLI channel factory not registered β€” call register_cli_channel_fn at startup
  • Why it matters: Core CLI command is broken β€” release blocker. The -m one-shot path was unaffected (it never touches CLI_CHANNEL_FN), which is why this wasn't caught earlier β€” that's the path I tested.
  • What changed: Added missing register_cli_channel_fn() call to Commands::Agent handler in src/main.rs, matching the identical call already present in Commands::Daemon
  • What did not change (scope boundary): No API changes, no function signatures modified, no other files touched. A more thorough fix exists (replacing the CLI_CHANNEL_FN OnceLock with a CliChannelFn parameter on run() and dropping the redundant interactive: bool parameter so the compiler enforces correctness) but that changes a public function signature across 5 files and 4 callsites β€” not appropriate for a hotfix. That refactor should be tracked as a follow-up issue.

Label Snapshot (required)

  • Risk label (risk: low|medium|high): risk: low
  • Size label (size: XS|S|M|L|XL, auto-managed/read-only): size: XS
  • Scope labels: runtime
  • Module labels: N/A
  • Contributor tier label: auto-managed
  • If any auto-label is incorrect, note requested correction: N/A

Change Metadata

  • Change type (bug|feature|refactor|docs|security|chore): bug
  • Primary scope (runtime|provider|channel|memory|security|ci|docs|multi): runtime

Linked Issue

  • Closes # N/A
  • Related # N/A β€” follow-up issue to be filed for OnceLockβ†’parameter refactor
  • Depends on # N/A
  • Supersedes # N/A

Supersede Attribution (required when Supersedes # is used)

N/A

Validation Evidence (required)

cargo fmt --all -- --check   # pass
cargo clippy --workspace --all-targets -- -D warnings   # pass, 0 warnings
cargo test --workspace   # pass, 42 test suites, 0 failures
  • Evidence provided: CLI tested β€” zeroclaw agent enters interactive mode without panic, zeroclaw agent -m "hi" still works, zeroclaw daemon unaffected
  • If any command is intentionally skipped, explain why: N/A

Security Impact (required)

  • New permissions/capabilities? No
  • New external network calls? No
  • Secrets/tokens handling changed? No
  • File system access scope changed? No

Privacy and Data Hygiene (required)

  • Data-hygiene status: pass
  • Redaction/anonymization notes: N/A
  • Neutral wording confirmation: N/A

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

i18n Follow-Through (required when docs or user-facing wording changes)

  • i18n follow-through triggered? No

Human Verification (required)

  • Verified scenarios: zeroclaw agent interactive mode starts without panic, zeroclaw agent -m "hi" one-shot works, zeroclaw daemon unaffected
  • Edge cases checked: One-shot mode (-m) never touches CLI_CHANNEL_FN β€” it takes the early return before the interactive loop. This is why the bug wasn't caught: -m was the path previously tested.
  • What was not verified: N/A

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: Commands::Agent startup path only
  • Potential unintended effects: None β€” identical pattern already exists in Commands::Daemon
  • Guardrails/monitoring for early detection: The panic was the detection; this eliminates it

Agent Collaboration Notes (recommended)

  • Agent tools used: Claude Code
  • Workflow/plan summary: git blame traced regression to 182bec1e (CliChannel OnceLock refactor), which wired registration in Commands::Daemon but missed Commands::Agent
  • Verification focus: Minimal fix (5 lines, 1 file) with zero API surface change for safe hotfix landing. The proper fix (OnceLockβ†’parameter, drop interactive: bool) is deferred to a follow-up PR.
  • Confirmation: naming + architecture boundaries followed

Rollback Plan (required)

  • Fast rollback command/path: git revert <sha>
  • Feature flags or config toggles: None
  • Observable failure symptoms: zeroclaw agent panics at startup β€” immediate, obvious

Risks and Mitigations

  • Risk: None β€” adds a registration call identical to the one already present in the Daemon path
    • Mitigation: N/A

182bec1 moved CliChannel behind a OnceLock factory but only wired
the registration in Commands::Daemon, not Commands::Agent. Running
`zeroclaw agent` (interactive, no -m) panicked at startup.
@singlerider singlerider added bug Something isn't working priority:p0 Blocker labels Apr 16, 2026
@github-actions github-actions bot added the core Auto scope: root src/*.rs files changed. label Apr 16, 2026
@singlerider singlerider self-assigned this Apr 16, 2026
@singlerider
Copy link
Copy Markdown
Collaborator Author

TLDR: This fixes a panic when running zeroclaw agent (no args). zeroclaw agent -m "hi" worked fine previously.

Copy link
Copy Markdown
Collaborator

@WareWolf-MoonWall WareWolf-MoonWall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Status: Approving. The fix is correct and safe to land. One conditional item below β€” please act on it before or immediately after merge.


βœ… The fix is right

git blame correctly traced the regression to 182bec1e (CliChannel OnceLock refactor), which wired registration in Commands::Daemon but missed Commands::Agent. The 5-line patch mirrors the identical pattern already in Commands::Daemon and sits inside the existing #[cfg(feature = "agent-runtime")] match block at line 1198, so no additional feature guard is needed β€” the symmetry with Daemon's internal guard is a pre-existing (harmless) detail, not something this PR introduced.

The diagnosis of why -m masked the bug is exactly right: one-shot mode returns before run_interactive() is called, so CLI_CHANNEL_FN is never read and the OnceLock miss is invisible on that path. That's the kind of root-cause analysis that makes a hotfix trustworthy.

OnceLock::set is idempotent here (let _ = CLI_CHANNEL_FN.set(f)), so there's no risk from a hypothetical double-registration, and the blast radius is confirmed to the Commands::Agent startup path only.


🟑 Conditional β€” file the follow-up issue before this lands (or immediately after)

The PR description correctly identifies the structural fix: replace CLI_CHANNEL_FN: OnceLock<…> with a CliChannelFn parameter on run(), and drop the now-redundant interactive: bool so the compiler enforces what the OnceLock currently relies on discipline to enforce. That's the right call to defer for a hotfix. But per FND-006 Β§4.4 and FND-005's conditional taxonomy, a deferral needs a tracked issue with an assignee β€” "follow-up issue to be filed" in the PR body is a wish, not a commitment.

Resolution path: File an issue titled something like refactor(agent): replace CLI_CHANNEL_FN OnceLock with CliChannelFn parameter on run(), drop interactive: bool and add the issue number to the "Related #" field. Five minutes of work that prevents this from becoming one of the 5,630 deferred decisions FND-006 Β§2.1 is already counting.

The fix itself does not need to wait for that issue. The commitment to file it does need to be on record before this is closed.


Checked: #[cfg(feature = "agent-runtime")] coverage (outer match at line 1198 covers the addition), OnceLock::set idempotency, daemon-path symmetry, -m early-return path, all CI green. Nothing new to block on.

@singlerider singlerider merged commit 1077e4d into zeroclaw-labs:master Apr 16, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working core Auto scope: root src/*.rs files changed. priority:p0 Blocker

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants