Skip to content

plan(confirm-sender): confirm an opencode sender by callback - #117

Merged
androidand merged 2 commits into
devfrom
fix/confirm-sender-by-callback
Oct 13, 2026
Merged

androidand merged 2 commits into
devfrom
fix/confirm-sender-by-callback

Conversation

@androidand

Copy link
Copy Markdown
Owner

Design only — no code. Opens the change so the implementation has a reviewed shape to build against.

The problem

codec.ts documents the correct rule: from/fromName are display only, and provenance must come from the authenticated connection, never these fields. lifecycle.ts:122 passes the envelope field to resolveOpencodeSender. There is no third path, and both branches of route.ts are functions of a string the sender chose.

So a peer writing from = uds:opencode-skein:<another session> is attributed to that session, and verifyLead grants the lead's scopes off that match. Written up in #112 with a failing-test formulation; this change is the fix's design.

Why callback, not credentials

No peer-credential primitive exists in the runtime. Probed on Bun 1.3.14 over a live unix socket: Socket exposes no getPeerName, getPeerCredentials or getPeerCert. The connection exposes nothing to read, so this is a platform constraint rather than a gap in this codebase.

So identity comes from asking the claimed sender, which alone holds the answer. A forger cannot make the real session report a message it never sent.

Decisions

  • D1 Callback, not credentials — as above.
  • D2 Fail to unattributed, never to attributed. No answer means the message arrives with the sender unverified. Delivery is never blocked by a liveness check. The dangerous interaction was checked rather than assumed: verifyLead (lead.ts:222-234) requires sender.sessionID === grant.lead.sessionID, so an unattributed sender cannot match a grant. Fail-open on delivery, fail-closed on authority — that asymmetry is the entire safety property.
  • D3 Bounded in-memory sent-log, short TTL, no message text. Not an audit record.
  • D4 Claude Code senders out of scope — they cannot be asked, so the lead check keeps matching pid and address, and the docs must call that a claim.
  • D5 Replay. The sent-log key is (msg_id, receiver_session_id), where the receiver is the target the sender dialed at send time, not the return path. A confirm on the right socket with the wrong receiver is a miss. This matters because the current frame carries no receiver identity at all (buildMessageFrame has msg_id and from and nothing else), so the binding has to be constructed here — and if it were derived from the return path the lookup would degrade to "did I ever send this msg_id" and D5 would collapse.

Residual, stated not hidden

Against a same-user, shell-capable agent, nothing short of OS separation makes sender identity unforgeable. A process that can replace a registry entry or a socket can still answer for it. This bounds the claim; it does not make it absolute. That is why the surrounding controls are bounded claims — human-granted, scoped, expiring, never-listed.

Tests pinned before implementation

1.1 asserts both halves — verifyLead denies a forged from, and the delivery-attribution caller (lifecycle.ts:122) does not treat the unattributed result as authoritative. resolveOpencodeSender has two callers and only one of them is the lead check.

🤖 Generated with Claude Code

androidand and others added 2 commits October 3, 2026 05:52
…sender identity, does not make it unforgeable

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Hey! Your PR title plan(confirm-sender): confirm an opencode sender by callback doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@androidand
androidand merged commit 282532a into dev Oct 13, 2026
3 of 9 checks passed
@androidand
androidand deleted the fix/confirm-sender-by-callback branch October 13, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant