Skip to content

[RC] feat(collaboration): agent collaboration release (consolidated) - #1978

Merged
arkash20 merged 80 commits into
mainfrom
release/agent-collaboration-rc
Oct 18, 2026
Merged

arkash20 merged 80 commits into
mainfrom
release/agent-collaboration-rc

Conversation

@arkash20

@arkash20 arkash20 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Release candidate under test — do NOT merge until Arkady signs off.

What

This is the whole agent-collaboration OSS work as one branch, the same code that ran in the local end-to-end demo. It contains:

PR What
#1666 Foundation: native agent collaboration clients and optional core mounts (erni-a, feat/agent-collaboration), including #1924 (refresh onto main, CI fixes)
#1926 feat/collaboration-benchmark: retry-after, presence capacity reservation, pool overload, request timing. Already contains these merged PRs: #1702, #1912, #1913, #1914, #1916, #1917, #1918, #1919, #1920, #1921, #1922, #1923, #1925, #1928, #1931, #1932
#1927 Client packages wired into release publishing
#1933 CLI-first onboarding, acceptance and capability status docs

This PR replaces #1666, #1926, #1927 and #1933. Close them only after this one merges.

On top of those heads:

  • origin/main is merged in (three times, most recently for fix(release): publishing and images run pinned code (L-64, L-67, L-235) #1977–chore: release main #1986). The refresh PRs chore(collaboration): refresh foundation onto main and fix formatting #1924 and chore(collaboration): refresh benchmark branch onto main and fix OSS CI #1925 were squash-merged, so git had lost track of the main commit they brought in (0e4502d5). I merged with that commit as the merge base. The only real conflict, both times, was .release-please-manifest.json: it keeps main's versions and adds clients/collaboration: 0.2.0. Diff against main: 91 files, all collaboration.

  • SQLAlchemy cap: unchanged from main. The demo integration had relaxed core-api to <2.2 so the Enterprise workspace (which requires >=2.1.3) could resolve. That relaxation broke this repo's CI: the shared CI venv then installs 2.1.3, and core-storage-api mypy fails with 13 Select/Row annotation errors. Those need their own migration. Commit 57c45798 reverts the relaxation, so core-api/pyproject.toml and uv.lock match main byte for byte. Enterprise now uses a root override-dependencies entry instead. The resolved environment is the same (SQLAlchemy 2.1.3 there, 2.0.x here).

  • To pass main's newer CI gates:

    • the collaboration workflows pin every action as sha # vX.Y.Z (the L-64/L-67 test), with pypa/gh-action-pypi-publish pinned to v1.14.2 like the other publish workflows;
    • the "PyPI packages build from the pinned tools" job also builds the clients/collaboration/* workspace members. The workspace root has no [project], and all eight packages build with the hash-pinned tools.

Merge with a merge commit, not squash. The history carries erni-a's authored commits and the merges of the included PRs.

DCO

18 commits by erni-a have no Signed-off-by. That is the only expected DCO failure. I can't sign off for him; the remedy is in the comment below.

How tested (locally, on the exact pushed commit or its tree)

CI-equivalent run on a fresh venv (Python 3.13), with throwaway pgvector and Redis containers:

  • Root pytest tests/ -m "not benchmark": 9735 passed, 6 skipped, 1 xfailed, 0 failed (one pin test then fixed as above). alembic upgrade head OK.
  • clients/collaboration: uv lock --check, ruff check/format, pytest 264 passed.
  • Broker OpenAPI --check: up to date (9 operations).
  • Every ruff check / format scope in ci.yml passes. mypy passes for core-api (221 files), core-storage-api (114), core-operations, core-worker, common, scripts.

Local end-to-end demo: the Enterprise RC (CAURA-000-collab-release-candidate, which pins this commit) built into a full isolated compose stack:

  • CLI demo: request → collect outcome: complete; idempotent resend → duplicate: true.
  • Real Claude Code agents (haiku), model-chosen peers: S1 19/19, S2 7/7, S3 9/9 checks.
  • S4 lease-loss and recovery: 22/22. Dashboard API check 12/12. Tenant drain/rollout 8/8. Quota smoke: fair per-tenant admission, with the other tenant isolated.

Follow-ups

🤖 Generated with Claude Code

erni-a and others added 30 commits September 21, 2026 11:58
Squashed Apache client import from de3c24d79ee1a5fe886fb77d7f87c985e71824bb; optional mounts from 814fcd6. Source history and approved licensing are recorded in docs/agent-collaboration/PROVENANCE.md.

Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
A 429 or 503 that carries Retry-After now bounds how soon a retry-safe
request comes back: the wait is the larger of the existing backoff and
the hinted delay, capped at five seconds, plus the existing jitter. An
absent or unparsable header keeps today's backoff, attempt counts are
unchanged, and non-retryable statuses still fail immediately. Clients
therefore stop returning early against a gateway or API that has just
shed them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MwPGksYbdDps6oXkheFqBk

Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
Signed-off-by: erni <erni@caura.ai>
)

## What

Plan task **PR-01** (absorbs PR-04 / part of PR-20): update the existing
collaboration runtime contract for the CLI-first product boundary.

- `docs/agent-collaboration/AGENT_COLLABORATION.md`
- New **CLI-first product scope (S1–S4)** section. Humans stay in their
existing host. The requesting agent picks peers from descriptions. No
new human chat UI, task board, room composer, model router or
hosted-agent service. The existing oversight dashboard stays as is, and
the scenarios do not depend on it.
- Scenario table S1–S4 with pass conditions. Rules for every scenario:
no hardcoded peer IDs or answers, fresh random private facts,
descriptions and replies treated as untrusted data, recorded host
version and state, and real-model selection reported separately from
scripted transport tests.
  - New **Host-state matrix**:
- Codex native queue (open session plus running waker) is the supported
active-session receive path and is used for the initial demo.
- Claude Code Stop hook listening is supported only within its bounded
window (600 s while a request is unanswered, 5 s otherwise).
    - Claude Code idle past that window is not wakeable.
- A stopped Claude process is **never advertised as wakeable**. S3 is a
durability case.
    - Cursor is unsupported.
    - The operator `codex queue` fallback is not an acceptance path.
- `clients/collaboration/README.md`: the example `peers` changes from a
fixed ID to `["*"]` and is documented as a local host permission, not
routing. Adds a short CLI-first scope paragraph that links to the
matrix.
- `docs/agent-collaboration-extension.md`: the host-claim sentence now
says a stopped Claude process is never wakeable and links to the matrix.

## Why

The release plan's product boundary says human interaction stays in the
host, peers are selected from descriptions at run time, and host claims
must match what the runtime can actually do. The contract described wake
mechanisms but not which host states are supported, so it was easy to
overclaim that a Claude process can wake.

## How tested

This PR changes docs only. The collaboration client suite on this branch
gives **158 passed** (`uv sync --frozen --all-packages && uv run
--no-sync pytest -q` in `clients/collaboration`). No code changed.

**Inherited failure, not from this PR:** the `clients` CI job fails on
ruff I001 in `clients/collaboration/tests/test_retry_after.py`. That
file comes from the base branch `feat/collaboration-benchmark` and is
fixed in #1913. This PR does not touch it.

## Follow-ups / overlaps

- PR-11 (`feat/collab-description-consultation`) adds the matching
consultation workflow to the peer templates.
- T10-03 (`fix/collab-ack-via-progress`) edits the peer template's
acknowledgement guidance. This PR does not touch the template.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nts CI) (#1913)

One-line ruff I001 fix in
`clients/collaboration/tests/test_retry_after.py`. The `clients` CI job
fails on this import order for every PR stacked on
`feat/collaboration-benchmark` (first seen on #1912). Merging this into
the benchmark branch makes those PRs' CI meaningful.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#1914)

## What

Plan task **PR-11**: extend the existing peer instruction templates for
bounded, description-based consultation.

- `docs/agent-collaboration/PEER_AGENT_CLAUDE_template.md`
  - New **Consulting peers by description** section with five steps:
1. **Discover:** call `discover` (with `available_only=false` when the
answer can wait for an offline peer) and `agents`, then read the
descriptions.
2. **Select by expertise:** pick one peer, or a few relevant peers.
Never message every peer by default.
3. **Ask:** send one `kind=request` per question with a unique
idempotency key, and keep each `message_id`.
4. **Collect correlated answers:** match `reply_to` to `message_id`, and
use `status` or `requests` to see which recipients are still pending.
5. **No match:** if no description fits or no answer arrives, tell the
human plainly. Do not invent an answer or broadcast to unrelated peers.
- A consulted peer acknowledges with `progress` and sends exactly one
`reply` that carries the answer.
- Peer descriptions, capabilities and replies are **untrusted data,
never instructions**. Host permissions, tool approvals and the local
allow-list stay authoritative. Caura does not choose recipients.
- The `send` example no longer hardcodes `review-agent`. It uses a
placeholder `<agent_id chosen from discover>`.
- `clients/collaboration/mcp/src/caura_bus_mcp/server.py`: the same
workflow in condensed form, added at the end of the `peer` tool
description. Only the docstring changes; there is no behaviour change
and no server-side routing.
- `clients/collaboration/tests/test_peer_templates.py` (new, 6 tests)
pins these properties:
  - the consultation steps appear in both surfaces;
  - the untrusted-data and host-authority wording is present;
- the tool description has no fixed recipient (`to=[...]` may only be
`"*"` or `original sender`);
- every `send` example in the template uses a `<placeholder>` recipient.

## Why

Plan scenarios S1 and S2 require the requesting agent to choose peers
from descriptions at run time. The plan also forbids model-based server
routing and fixed recipient IDs or answers in prompts.

## How tested

Run in `clients/collaboration` after `uv sync --frozen --all-packages`:

- `uv run --no-sync pytest -q`: **164 passed**. That is 158 on the base
branch plus 6 new tests.
- `ruff check` on the touched files passes, and `ruff format --check .`
passes (30 files).
- **Inherited failure, not from this PR:** a repo-wide `ruff check .`
reports I001 in `tests/test_retry_after.py`. That file comes from the
base branch `feat/collaboration-benchmark` and is fixed in #1913. This
PR deliberately does not touch it, so the `clients` CI job will stay red
until #1913 lands.

## Overlaps / follow-ups

- **T10-03** (`fix/collab-ack-via-progress`) edits the same template and
tool description for acknowledging via progress. My edits are additive:
a new template section placed before the `wait`-result paragraph, and
new lines at the end of the docstring. The opening acknowledgement line,
the reply/progress bullets and `WAKE_TEXT` are untouched. Expect at most
a trivial merge. If T10-03 rewords the acknowledgement guidance,
`test_template_teaches_each_consultation_step` pins "acknowledge receipt
with `progress`" and "exactly one `reply` that carries the answer".
- **PR-07** adds persistent description fields to the SDK/MCP `discover`
output. This PR refers only to "description and capabilities" and does
not change the `discover:` docstring line.
- Depends on PR-01 (#1912) for the scope and host-state contract.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…02) (#1920)

## What / why

Plan task **T10-02** (handoff Task 10 dogfood defect): `caura_bus_mcp`
`DeliverySession.guard()` kept the locally observed paused claim with
its token cleared. Even after a human approved, redirected or rejected
the pause, every op except `wait` kept returning 409 `paused`.

## Design

When the local claim is paused and holds no token, `guard()` re-reads
the claim through the session's **authenticated `inbox/wait`** (timeout
0, same `session_id`). It does this under the delivery lock, which is
also what the server uses to reclaim safely. Caura decides the outcome:

| Server state after refresh | Behaviour |
|---|---|
| still paused | stays fenced: 409 `paused` (no progress/reply reaches
Caura) |
| approved (no instructions) | reclaimed for this session with a fresh
private token; the op proceeds |
| redirected / approved with instructions | reclaimed; the first call
scoped to that delivery returns 409 `resumed` with `resume_context`, and
a retry proceeds |
| rejected / cancelled / leased by another session | 409 `unavailable`
for ops scoped to that delivery, so it is never resurrected; unrelated
ops (discover, send…) proceed |

- Duplicate refresh: the refresh re-checks `current is stale` inside the
lock, so concurrent calls issue one wait. Another session's live lease
is never returned, because the server only hands a live lease to its
owning session.
- Tokens never appear in results or errors (`public()` excludes them).
- Notices returned by a refresh wait are held and handed over by the
next `peer wait`, which then skips its long poll.
- `dispatch` passes the targeted delivery ID (including `send` with a
claimed `reply_to`) to `guard`.
- The tool description and peer template explain `resumed` /
`unavailable`.

## How tested

- New `tests/test_mcp_paused_refresh.py` (9 tests), with a new stateful
fake platform `tests/collab_fake.py`. The fake mirrors server wait,
observe, caura-stopped, lease checks and human decisions. Cases covered:
all ops recover after approval (new token ≠ old), unrelated ops recover,
still-paused stays fenced, reject is never resurrected, redirect
surfaces instructions before work continues, no token in errors,
concurrent refreshes reclaim once, no steal from another session's live
lease, and notices survive the refresh. 7 of the 9 fail on the unfixed
code.
- `clients/collaboration`: `uv lock --check` OK, ruff check/format
clean, `pytest` with CI coverage flags: **167 passed** (base: 158),
coverage 81.5%.
- Not verified live against a running stack. ENT server semantics were
read from `feat/tenant-send-quota` `caura_bus_platform/pull.py` +
`collaboration.py`.

## Notes

- Stacked follow-up: T10-05 (reclaim before reply after lease loss) is
based on this branch.
- A separate commit includes the inherited ruff I001 fix in
`tests/test_retry_after.py` (same hunk as #1913).
- The `CI` job may fail at "Broker OpenAPI has no breaking change vs
main" because the base is about 217 commits behind main. That is being
fixed separately.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ies (#1916)

## What / why

Plan task **PR-21 — Qualify host busy and approval boundaries** (Demo
gate). Extends the existing hook/waker tests in
`clients/collaboration/tests/test_runtime_waker.py` only for the missing
approval-prompt, re-entry and busy-turn transitions. Ownership and
Broker-managed configuration are unchanged.

New coverage (10 test cases):
- **No automatic approval:** for every hook mode (`None`, `Stop`,
`UserPromptSubmit`) the hint is exactly the fixed wake text in the
documented shape. It never carries `approve`/`permissionDecision`, and
it never echoes server-side decision fields. Hint paths call only
`connect`/`inbox_state`/`advertise`/`events`/`close` (no claim, settle,
reply or decision).
- **Host approval events untouched:** `hooks install` never writes
`PreToolUse`/`PermissionRequest`/`Notification`. It leaves those entries
and foreign/broker-owned look-alike commands (`caura agent connect …`,
`caura-bus recv` without `--brief`) byte-identical, and it stays
idempotent.
- **Paused awaiting human approval:** the waker does not prompt while a
delivery is paused (no competing prompt). It queues exactly once on
`human.decided` → resumed recovery, and a repeat observation does not
queue again.
- **Stop re-entry:** after its own `block`, a re-entered Stop (with the
model now holding the lease or having ignored the hint) returns
immediately with no second block and no listen loop. The CLI tolerates
the host's `stop_hook_active` stdin payload and does not echo the key.
- **Busy turn:** work that arrives mid-turn surfaces at the next Stop.
Drained-then-new work blocks again, and `UserPromptSubmit` in the same
burst stays silent. An expired empty Stop listener hands later work to
the next `UserPromptSubmit`. The Codex waker advertises `ready → busy →
busy → ready → ready` and queues only 2 prompts across 5 snapshots
(initial, then after drain).

## Defect found and fixed (minimal)

The Claude Stop listener advertised `ready` while the agent held an
active delivery lease (`snapshot.active`). The Codex waker advertises
`busy` in the same state. As a result, discovery could route new work to
a session that was mid-delivery. The listener now advertises `busy` when
`active` (2-line change in `cli/src/caura_bus_cli/runtime.py`). Covered
by `test_stop_listener_advertises_busy_while_the_agent_holds_a_lease`,
which fails before the fix.

Separate commit: the inherited one-line import-order fix in
`tests/test_retry_after.py` (`ruff check --select I --fix`, ruff
0.15.22), the same hunk as #1913.

## How tested

`cd clients/collaboration && uv sync --frozen --all-packages && uv run
--no-sync pytest -q` gives **168 passed** (base
`feat/collaboration-benchmark`: 158 passed; +10).
`tests/test_runtime_waker.py` gives 37 passed, and 5 consecutive runs
showed no flakes. `ruff check .` and `ruff format --check` are clean.

## Notes / follow-ups
- The `CI` job's OpenAPI-vs-main step may still fail because the root
base is about 217 commits behind `main`. A separate refresh PR handles
that; it is unrelated to this change.
- Claude Code's own permission prompt and Codex's in-turn approval UI
are host-internal. These tests prove Caura registers nothing on those
events and only uses Stop/UserPromptSubmit and `codex queue` boundaries.
A pinned-host-version conformance run is still outside this PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add the four collaboration client distributions (caura-bus-core,
caura-bus-mcp, caura-bus-cli, caura-bus-adapter-sdk) to release-please as
one lockstep component, `collaboration-clients`, and add a gated PyPI
trusted-publishing workflow with PEP 740 attestations.

- Dependents now pin caura-bus-core to the exact same version, so a
  published set can never resolve against a mismatched wire-model core.
- release-please updates every version, pin, uv.lock member version and
  the README install snippet; the first release is fixed at 0.3.0 because
  0.2.0 was only the unpublished sibling-path preview string. None of the
  four names exists on PyPI yet.
- scripts/verify_dist.py installs the built wheels into a fresh virtualenv
  with no source tree in reach and checks pins, pip check, import origin
  and every console entrypoint; it runs in CI and before publishing.
- caura-bus-mcp answers --help/--version instead of starting stdio.

Nothing is published by this change: publication needs a merged release
PR plus approval on the pypi-collaboration environment.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
## What

Plan tasks **PR-14 + PR-15 + PR-16**, merged into one PR: qualify
multi-peer consultation against the request lifecycle that already
exists, and add a small reusable collector in the OSS collaboration
client. There are no server changes and no new server deadline state.

- **`caura_bus_core.consult`** (new)
- `ResponseCollector` / `collect_responses(bus, request_id,
expected=None, timeout=30)`. It is read-only: it only calls
`status(request_id)` and `recent(reply_to=request_id)`.
- **Expected recipients** come from the request's recipient snapshot in
`status` (original deliveries), unless the caller passes them. A
reassigned delivery (`reassigned_from`) completes its original slot, and
the answer is attributed to the agent that actually sent it.
- **Completion** counts distinct expected recipients that sent a
correlated `kind=response` (`correlation_id == request_id`). A delivery
ACK, a progress report, an info message, a response to another request,
a response from an unexpected sender and a second response from the same
recipient are all excluded and counted in `excluded`. When `reply_to` is
not honoured by the server (pre-#1885), the client filtering still
applies.
- **Bounded:** the local timeout is at most 45 s, below host tool
limits. Polling backs off from 1 s to 5 s. Transient 5xx and transport
errors are retried within that bound; 4xx errors raise.
- **Outcomes:** `complete`, `partial`, `no_reply` or `cancelled`.
Answers keep `recipient`, `sender`, `message_id` and `late`. Recipients
without an answer are listed under `pending` (reply_state,
delivery_state, cause, reply_due_at) or `closed`
(`unanswered`/`cancelled`). Closed recipients end the collection early.
- `summary()` says plainly who did not reply, that their requests stay
accepted, and "Do not invent an answer".
- A reply that `status` records but that falls outside the `recent`
window is fetched by ID.
- **Cancellation:** `cancel()` or task cancellation only stops local
polling. Nothing is cancelled, ACKed or renewed on Caura, so accepted
recipient work continues and a later `collect` picks up late answers
(`late=True` comes from `late` / `late_reply_message_id`).
- `PresentedResponses`: a bounded, in-memory, per-session set of
response IDs already shown to the model.
- **`Bus.recent(reply_to=...)`**: ported, minimally and identically,
from #1702 (`feat/collaboration-reliability`). It needs server support
from ENT #1885. **Overlap:** #1702 makes the same `bus.py` /
`Recent.reply_to` / docstring change, so expect a trivial conflict when
the two meet.
- **MCP**
- `recent` accepts `reply_to`. Responses it returns for that request are
marked presented.
- New **stdio-only** opcode `collect` with arguments `message_id*`,
`timeout=30` (0–45) and `expected`. It is not in `REMOTE_OPERATIONS`, so
the ENT remote surface is unchanged.
- **Duplicate suppression (PR-16):** when `wait` later claims the queued
delivery of a response that was already presented, it returns that
delivery with `already_presented: true`, `body: null` and a note to
`ack` it. The model ACKs it normally. Presentation is tracked in both
directions: a response first shown by `wait` is shown without its body
by a later `collect`, and a repeated `collect` shows bodies only for new
(late) answers.
- **Restart behaviour:** the bookkeeping lives in memory in the MCP
process. After a restart, a queued response is shown once more. This is
presentation bookkeeping only, not an exactly-once guarantee for
effects. It is documented in SPEC and the template.
- **CLI:** new `caura-bus collect MESSAGE_ID [--timeout] [--expected
...]` and `replay --reply-to`.
- **Docs:** template step 4 now teaches `collect` and its semantics;
`SPEC.md` lists the opcode and describes its bounds.

## Why

Scenario S2 (A asks B and C, then combines the correlated answers) needs
bounded, attributable collection inside a single host tool call, without
mistaking a delivery ACK for an answer and without showing the same
answer twice when its queued delivery arrives later.

## How tested

Run in `clients/collaboration` after `uv sync --frozen --all-packages`:

- `uv run --no-sync pytest -q`: **185 passed**. That is 164 on the base
branch plus 21 new tests:
- `tests/test_response_collector.py` (15): fan-out with out-of-order
completion; ACK/progress is not an answer; unrelated and unexpected
responses excluded (including against a server that ignores `reply_to`);
duplicate per recipient counted once; partial completion at the local
timeout with attribution; closed recipients end early; late answer
picked up on re-collect; reply after cancellation marked late; local
cancel returns partial results with only GETs made; task cancellation
has no side effects; recipient snapshot plus reassignment; recorded
reply fetched by ID; transient versus rejected errors; timeout cap;
bounded presented set.
- `tests/test_mcp_collect.py` (6): collect presents bodies once, then
each queued delivery returns `already_presented` and is ACKed (queue
drains); `recent(reply_to)` marks a response presented; wait-first then
collect does not repeat the body; a late answer shows only the new body;
restart shows the response again; timeout over 45 and the remote
transport are rejected.
  - `test_mcp_tool.py`: the opcode set now includes `collect`.
- `ruff check .` and `ruff format --check .` pass (33 files).

## Notes / follow-ups

- The CI `OpenAPI-vs-main` step may fail because the root base is about
217 commits behind `main`. A separate refresh PR handles that; it is not
caused by this PR.
- Server-side `reply_to` filtering comes from ENT #1885. Against a
platform without it, the client still filters correctly, but it reads
through general `recent` pages (at most 5 pages per poll), plus by-ID
reads of replies that `status` has recorded.
- PR-18 (consultation-loop bounds) is stacked on this branch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… dists

The four client packages shipped a reference-only LICENSE stub and no
NOTICE. Ship the repository's full Apache-2.0 text and a NOTICE with each
distribution, and make verify_dist.py refuse artifacts without them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
…to chore/collab-release-publishing

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>

# Conflicts:
#	clients/collaboration/mcp/src/caura_bus_mcp/server.py
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

@arkash20

Copy link
Copy Markdown
Contributor Author

@erni-a please approve

erni-a
erni-a previously approved these changes Oct 15, 2026
Resolves .release-please-manifest.json: main's 3.34.1 root version plus
the release candidate's clients/collaboration entry.

Signed-off-by: Arkady Mankovsky <arkady@caura.ai>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

@erni-a
erni-a force-pushed the release/agent-collaboration-rc branch from 82b26b3 to f4808ec Compare October 15, 2026 13:09
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'erni-a' is not a public member of the 'caura-ai' org

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
@arkash20

Copy link
Copy Markdown
Contributor Author

@erni-a please approve — DCO sign-offs are in (thanks!) and the branch is up to date with main; the force-push dismissed the earlier approval.

erni-a
erni-a previously approved these changes Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

Resolves .release-please-manifest.json: main's 3.34.3 root version plus
the release candidate's clients/collaboration entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

@arkash20

Copy link
Copy Markdown
Contributor Author

@erni-a please approve — merged the latest main (release-please manifest only); CI is green.

erni-a
erni-a previously approved these changes Oct 17, 2026
Resolves .release-please-manifest.json: main's 3.34.4 root and 2.25.2
plugin versions plus the release candidate's clients/collaboration entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

@arkash20
arkash20 marked this pull request as ready for review October 18, 2026 06:07
@arkash20
arkash20 requested a review from a team as a code owner October 18, 2026 06:07
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

@arkash20

Copy link
Copy Markdown
Contributor Author

@erni-a please approve — merged the latest main (release-please manifest only); CI is green.

@arkash20
arkash20 merged commit 9579772 into main Oct 18, 2026
21 checks passed
@arkash20
arkash20 deleted the release/agent-collaboration-rc branch October 18, 2026 06:22
eldad-caura-ai added a commit that referenced this pull request Oct 19, 2026
M-126: scripts/caura-join.sh defaulted CAURA_JOIN_REF to the branch
release/agent-collaboration-rc, deleted once that release merged
(#1978). The collaboration README pipes the script from main, so the
documented join failed at `uv tool install git+...@<ref>`, and whoever
could recreate that branch name would choose what every later
`curl | sh` installed.

The default is now main, the ref the README fetches the script from,
so script and client come from one place; the header's example URL
matches, and CAURA_JOIN_REF still overrides it.
test_caura_join_script.py ties the README, the header and the default
together. Tests alone (run 39326983848) failed exactly that case,
10269 passing.

Signed-off-by: eldad-caura <eldad@caura.ai>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants