Skip to content

fix(claude): reject mismatched self and scope ids - #260

Open
bniladridas wants to merge 1 commit into
Vycari:mainfrom
bniladridas:issue-254-self-scope-check
Open

bniladridas wants to merge 1 commit into
Vycari:mainfrom
bniladridas:issue-254-self-scope-check

Conversation

@bniladridas

@bniladridas bniladridas commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Human overview

A scoped agents claude-channel run now refuses a --self that disagrees with the scope frame's agent_person_id. The mismatch exits 2 and is rejected before the scope is bound or any subsequent message event is handled, so a wrong id cannot drop another member's posts or push the agent's own. Unscoped runs retain their existing --self and is_you behavior. Fixes #254, item 3 of 4 follow-ups from #122.

AI reviewer

Details for agents: what the diff does, invariants, verification, checklist

What it does

  • ChannelWorker._accept_scope now compares a supplied --self with seen.agent_person_id using _same_id (UUID case-insensitive) before setting self.bound or handling events.
  • A mismatch raises _Ended(2) with a message naming both ids. The channel emits its standard ended control event, but no message is fetched or pushed after the mismatch.
  • The discovery path is unchanged: when --self is absent, self_id still comes from the scope frame, and unscoped streams still use --self or the is_you fallback.

Invariants

  • The scope frame remains the source of truth for a scoped run; --self can only confirm it.
  • The check is before self.bound = seen, so a mismatch does not bind the channel to the scope.
  • No API, cursor-file, or contract changes.

Where to look hardest

  • The check is inside the first-scope branch only. Reconnects still compare the whole scope against self.bound, so a changed agent_person_id still ends the channel.
  • _same_id canonicalizes UUIDs, so case differences are not treated as a mismatch.

Verification

  • uv run --extra dev pytest tests/test_claude_channel.py -q: 135 passed in 21.16s.
  • uv run --extra dev pytest -q: 3344 passed, 2 skipped in 578.78s.
  • uv run --extra dev ruff format --check: 150 files already formatted.
  • uv run --extra dev ruff check: All checks passed.
  • uv run --extra dev ty check src/pepper_cli/: All checks passed.
  • Coverage was not run locally; CI measures it.

Checklist (repo-specific)

  • uv run ruff format --check and uv run ruff check clean (no new lint ignores)
  • uv run ty check src/pepper_cli/ clean
  • uv run pytest passes; coverage floor in .claude/maintainerd.json not lowered (pytest passed; coverage not run locally, CI measures it)
  • Server-contract changes: N/A, no /api/v1 or # MIRROR: changes
  • No token or credential is logged, printed, or put in a fixture
  • README and the bundled SKILL.md updated if commands or output changed (N/A: no command or output change)
  • Help: help/cli.md updated for a new or changed command, or not user-facing because N/A, no new or changed command and the flag syntax is unchanged

Refs #254.

A scoped channel accepted --self without comparing it to the scope frame's agent_person_id, so a wrong value could drop another member's posts and push the agent's own. Fail with exit 2 before binding or handling events when the ids differ; an unscoped stream still uses --self alone.

Add regression tests for a matching id that drops the agent's own post and a mismatching id that ends the channel without fetching a message.

Refs Vycari#254.

Signed-off-by: Niladri Das <125604915+bniladridas@users.noreply.github.com>
@vycari-review

vycari-review Bot commented Nov 14, 2026 •

Copy link
Copy Markdown

Vycari Review

Round 1 on 832befa. The verdict is the Vycari Review check run, and each open finding is an inline thread. Reply on every P0 and P1 thread: Fixed in <sha>, or Disputed: with a reason. P2s are the author's call: fix one, or reply Deferred: #<issue> (the PR's one follow-up issue) or Declined: with a reason, and VR stops re-raising it. From round 2 on, VR raises no new P2s: it checks the fixes and looks for P0s and P1s.

Open: P0 0 · P1 0 · P2 0 · disputed 0 · confirmed fixed 0 · withdrawn 0

Hand-off: Greptile requested on 832befa.

No open findings this round.

P2s, judge's notes and closed findings

Judge's notes

No candidate findings were raised.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-14T06:23:01.601091Z 832befa PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@vycari-review

vycari-review Bot commented Nov 14, 2026

Copy link
Copy Markdown

@greptileai review

This branch has not been deployed

No deployments
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.

agents claude-channel: validate --self against the scope frame agent_person_id

1 participant