Why Role Resolution Must Stay Unique

Use a role-resolution scenario to show why resolve cannot allow several powers to answer at once

Scenario

The host wants to answer one question:

  • what is this user's final role

So it calls:

const role = await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).resolve<{ userId: string }, string>(
  "auth.resolve_role",
  { userId: "owner" },
);

Why two resolvers would be a problem

If two powers can both answer:

  • power A says admin
  • power B says member

then the host has to add another layer of arbitration.

But the whole point of resolve is to avoid that extra arbitration layer.

Its design means:

  • this point must decide its single authority ahead of time

That is why the implementation behaves this way

  • duplicate registration for the same resolve point: throw
  • no resolver registered: throw
  • resolver power disabled: throw

All three rules protect the same invariant:

  • the final answer must stay unambiguous

If you really want several participants

Then you probably should not use resolve for that part.

A healthier structure is often:

  • first use pipeline to collect and enrich context
  • then let one resolve point produce the final answer