Skip to content

feat(progressive): bind handles to host turn scope - #147

Merged
senamakel merged 9 commits into
mainfrom
tinychannels-progressive-host-bridge
Oct 24, 2026
Merged

senamakel merged 9 commits into
mainfrom
tinychannels-progressive-host-bridge

Conversation

@senamakel

Copy link
Copy Markdown
Member

Summary

Adds ProgressiveCommand::OpenScoped while preserving legacy Open, Feed, and FeedOutput. Scoped handles bind the provider channel, turn ID, channel reference, and conversation at open time. FeedOutput rejects any later request whose turn scope differs before replay or callback dispatch. Matching output batches keep the existing ordered host callback path, typed delivery outcomes, receipts, and idempotent replay/close behavior.

This PR is stacked on #145, which provides the canonical typed output path and host callback transport. It must land first. This PR is a draft until #145 is merged and the branch can be retargeted to main.

References OpenHuman #7964; it does not complete OpenHuman integration or close that issue.

Validation

  • cargo fmt --check
  • cargo test -p tinychannels-module scoped_open_rejects_feed_output_from_another_turn
  • cargo test -p tinychannels-module (214 passed)
  • cargo test -p tinychannels-bus (103 passed)
  • cargo test -p tinychannels (1,075 passed; providers off)
  • cargo test (workspace: tinychannels 1,307, bus 106, module 214, runtime 230 passed)
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • git diff --check

The regression test first failed to compile because OpenScoped was not defined. It now verifies turn/channel-ref/conversation mismatch rejection before callbacks, successful delivery-result replay for matching scope, and repeated cancellation without duplicate typed sends.

senamakel and others added 8 commits October 23, 2026 00:18
Update the tinybus and wiki submodule pointers to their latest commits.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the tinybus and wiki submodule pointers to their latest commits.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…er turn

Add a test asserting that feeding output to a scoped handle with a turn id
that differs from the one it was opened with fails and never reaches the
callback.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add an OpenScoped command that opens a progressive handle bound to a
provider target and host-authorized turn, and reject FeedOutput requests
whose scope differs from the bound one. This keeps a handle from being
reused to emit output under a different turn or conversation than the
host authorized.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The scoped open test now supplies matching channel and conversation
references so the bound turn can be exercised end to end. It asserts that
replaying an identical feed output returns the same delivery result and
that closing the handle twice still sends exactly one typed request.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Extend the scoped open rejection test with cases where the channel or
conversation reference does not match the bound turn, asserting both are
rejected so the scoping checks are exercised beyond the turn id alone.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reindent the scoped feed output rejection assertions in the progressive
tests to match rustfmt's preferred wrapping. No behaviour or coverage
changes.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 672d69ae-c363-41f3-9b7f-f8a0e7ef9d5f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@senamakel
senamakel marked this pull request as ready for review October 24, 2026 06:58
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

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

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T07:02:44.703785Z 39313a4 New commits
ℹ️ 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.

@tinysweeper

tinysweeper Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

⚠️ Review of 39313a472ba1 stopped because the pull request closed or changed.
The last completed review (4a3108f0e7db8940c2bc4bd0f1c91fe66875bbf3) is shown below.

Last completed report

Tiny Sweeper review

Reviewed head: 4a3108f0e7db8940c2bc4bd0f1c91fe66875bbf3

Verdict: Ready for maintainer review · Priority: none
Coverage: Reviewed 3 of 3 files.
No actionable findings were reported in the available review results.

Diagnostics and supporting details

Full summary

Pull request purpose (title): feat(progressive): bind handles to host turn scope. This pull request adds `ProgressiveCommand::OpenScoped`, letting a progressive handle be bound at open time to a provider target plus a turn ID, channel reference, and conversation. Later `FeedOutput` requests on a scoped handle whose scope differs are rejected before replay or callback dispatch, while legacy `Open`, `Feed`, and `FeedOutput` stay unchanged. The review notes the code index is behind this head so retrieved context may be stale.

Review snapshot

Change surface Files Review signal Count
Production 2 Active findings 0
Tests 1 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 0 Pending checks/questions 0

Completeness: Complete
Test assessment: Test coverage is assessed from changed tests and lane evidence; execution is not claimed without trusted check data.

What changed

Introduces a scoped open path: `ProgressiveCommand::OpenScoped` carries channel, turn_id, channel_ref, and conversation; `open` accepts an optional scope and stores a constructed `OutputScope` as `bound_scope` on the entry; `FeedOutput` compares the freshly built scope against `bound_scope` and returns an error on mismatch before replay or dispatch. A new regression test exercises rejection on mismatched turn, channel ref, and conversation, then matching-scope delivery with replay, and repeated close without duplicate typed sends. The description states the PR is stacked on #145 and is a draft until that lands.

Features

  • Added — Scoped progressive open command (`OpenScoped`): Callers can bind a progressive handle to one turn/channel/conversation scope at open time instead of opening an unscoped handle; legacy `Open` still passes `None` and keeps prior behavior. (crates/tinychannels-bus/src/module_progressive.rs pub enum ProgressiveCommand {, crates/tinychannels-module/src/progressive.rs impl Replies {)
  • Modified — Scope guard on `FeedOutput`: Output batches whose turn, channel reference, or conversation differ from the bound scope are rejected before replay or callback dispatch, preventing cross-turn projection on a scoped handle. (crates/tinychannels-module/src/progressive.rs impl Replies {)
  • Added — Scoped-open regression test: Covers mismatch rejection on turn, channel ref, and conversation for a scoped handle, the matching-scope path with delivery replay, and idempotent close without duplicate typed sends. (crates/tinychannels-module/src/progressive_tests.rs async fn feed_output_retries_reuse_the_previous_result_without_reapplying_deltas)

Tests

  • unit/integration regression test — Opens a scoped handle, asserts `FeedOutput` fails for a different turn ID, a different channel ref ID, and a different conversation ID; asserts the callback received no requests; then sends a matching-scope final message, checks a single delivery, checks the replayed result equality, and closes twice while verifying only one typed send occurred.: The tests lane was answered with no defects; it states the mismatch branch and matching replay/close path are exercised, and flags only a minor gap: `OpenScoped` has no wire-shape pin despite the module's existing v1 shape tests. Claims are based on lane findings; no independent test execution is asserted here. (crates/tinychannels-module/src/progressive_tests.rs async fn feed_output_retries_reuse_the_previous_result_without_reapplying_deltas)

Findings

No active actionable findings.

Before merge

None.

Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: Critique lane found no defect: comparing the bound `OutputScope` against the freshly built scope in `FeedOutput` is described as sound.
  • Lane summary: The change adds an `OpenScoped` command that binds an opened progressive handle to a turn/channel/conversation scope and rejects `FeedOutput` requests whose scope differs from the bound one. Comparing the bound `OutputScope` (handle, channel, turn_id, channel_ref, conversation — `PartialEq` derived) against the freshly built scope in `FeedOutput` is sound: the handle and channel always match, and the test covers divergence on turn, channel_ref and conversation, plus matching retries and idempotent close. Unscoped opens still pass `None` and behave as before. I found no defect to report. _The code index is behind this pull request (indexed at `377e7f326d2e`), so retrieved context may be out of date._

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: Security lane found no concrete failure, regression, or repository-rule violation in the reviewed files.
  • Lane summary: The change adds an `OpenScoped` progressive command that binds a handle to a turn/channel/conversation scope, and `FeedOutput` now rejects batches whose scope differs from the bound one; existing unscoped `Open` handles keep their prior behaviour. I found no concrete failure, regression, or repository-rule violation in the reviewed files, though I did not independently verify the test fixture's callback/request plumbing. _The code index is behind this pull request (indexed at `377e7f326d2e`), so retrieved context may be out of date._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: Tests lane reports the mismatch branch cannot silently regress and that turn, channel, and conversation mismatches plus matching-scope delivery replay and idempotent close are covered.
  • Lane summary: Adds a scoped progressive open (`OpenScoped`) that binds a handle to a turn/target scope and rejects `FeedOutput` requests whose scope differs, including the files' own tests, which cover mismatched turn, channel and conversation, the matching path with delivery replay, and idempotent close. The change is tested and the mismatch branch cannot silently regress; one weakness is that `ProgressiveCommand::OpenScoped` gets no wire-shape pin despite the module's existing v1 shape tests, but that is not a behavioural defect. _The code index is behind this pull request (indexed at `377e7f326d2e`), so retrieved context may be out of date._

commits

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: No sensitive content in committed files. _The code index is behind this pull request (indexed at `377e7f326d2e`), so retrieved context may be out of date._

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The description matches the diff: it adds `ProgressiveCommand::OpenScoped`, binds the scope at open time, and rejects FeedOutput whose scope differs before replay or dispatch, with a regression test covering the mismatch cases and the matching-scope replay/close path. The flagged cases (conversation mismatch, channel_ref mismatch) are exercised in the test but not visible in the excerpted diff hunks, so I could not verify the guard covers them; nothing in the visible diff contradicts the description. No defects found against the repository rules. _The code index is behind this pull request (indexed at `377e7f326d2e`), so retrieved context may be out of date._
Evidence and run details
  • Models: ladder/vectors-oai3, deepseek-v4.1-flash
  • Spend: $0.000283
  • Tokens: 288662 input · 4231 output · 13312 cached · 230 embedding
  • Updated: 2026-10-24T06:59:43Z
Head State Pass summary
4a3108f0e7db ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-10-24T06:59:43Z)

tinysweeper 0.1.2

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

tinysweeper found nothing blocking. Approving.

Diagnostics

Total spend: $0.0003

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Oct 24, 2026
…ive-host-bridge

# Conflicts:
#	crates/tinychannels-module/src/progressive.rs
@senamakel
senamakel changed the base branch from 7964-tinychannels-progressive-current-main to main October 24, 2026 07:01
@senamakel
senamakel merged commit ad52075 into main Oct 24, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant