Revert "feat(mcp): a Cloud customer can't hand a task to a caller seat"

This reverts commit 78f426ba76.

The caller-seat create refusal waits on a product decision, so it stays
out of this merge. It comes back by reverting this commit. A customer's
task can go to any seat of its rigs on this instance, as with the first
commit; the read rule that ignores items from caller-shaped seats is
unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
review50-r3andClaude Opus 5.5 committed 2026-10-26 11:59:05 +00:00
1 parent 692d6b2b8d
commit 0f93cfed9b
2 files changed
+6 -8

No files matched your search

+5 -7
View File
@@ -264,14 +264,13 @@ function scopeFor(access: McpAccess, seatOf: () => string | undefined): Scope {
}
/** Cloud names a customer's caller seat cus-<id>-caller@<rig>. v1 marks no seat as a caller, so an item from a seat of
* this shape is never the team's question to a customer, and a customer can't hand a task to one. The shape never
* grants anything. */
* this shape is never the team's question to a customer. The shape never grants anything. */
const CALLER_SHAPED = /^cus-.+-caller@[^@]+$/;
/** A Cloud customer grant (openrig.cloud.grant/v1): a requester, narrower than a work grant. The grant's own seat is the
* only caller. It may hand tasks to its rigs' team seats (never a caller-shaped seat, a person or another host's
* seat), read the items it sent and the team's questions to it (never team-internal or another caller's items), follow
* a handed-on item only where it came back to it, and read the artifacts of its own items under its named roots. */
* only caller. It may hand tasks to its rigs' seats (never a person or another host's seat), read the items it sent and
* the team's questions to it (never team-internal or another caller's items), follow a handed-on item only where it
* came back to it, and read the artifacts of its own items under its named roots. */
function customerScope(access: McpAccess, seatOf: () => string | undefined): Scope {
const rigs = new Set(access.rigs);
const caller = (value: unknown): boolean => typeof value === "string" && value !== "" && value === seatOf();
@@ -291,8 +290,7 @@ function customerScope(access: McpAccess, seatOf: () => string | undefined): Sco
owner: () => false,
rig: (name) => typeof name === "string" && rigs.has(name),
root: (name) => typeof name === "string" && access.roots.includes(name),
// A task goes to the team: never to the caller itself or to another caller-shaped seat, which v1 can't tell apart.
destination: team,
destination: member,
successor: caller,
artifact: (row) => caller(field(row, "sourceSession")),
paths: false,
@@ -199,7 +199,7 @@ describe("rig mcp serve --http --cloud-grants on the daemon's routes", () => {
const served = await listen();
const asCustomer = await connect(served.url);
const before = rows();
for (const destination of ["cus-otherone01-caller@team-a", CALLER, "lead@team-b", "alex@external", "lead@team-a@elsewhere"]) {
for (const destination of ["lead@team-b", "alex@external", "lead@team-a@elsewhere"]) {
expect((await asCustomer("rig_queue_create", { destination, body: "not allowed" })).structured).toMatchObject({ ok: false, code: "out_of_scope" });
}
expect(rows()).toBe(before);