assume / yield role, Semantic Addressing

A role declaration claims (or relinquishes) a named responsibility, so that other twins' membranes can address "whoever holds this role" instead of a person by name. Roles are the language's answer to forwarding chains, to stale org charts, and to the "who owns this now?" email thread: the pipe rebinds, and nobody gets notified, because nobody needs to be.

Syntax

From spec §5:

roledecl    = ( "assume" | "yield" ) "role" rolename ;
rolename    = ident "(" [ arg { "," arg } ] ")" ;

For example (spec §4.9):

assume role decision-owner(atlas.budget)

Semantics

Spec §4.9: a twin claims a role with assume and relinquishes it with yield. Roles matter because membranes may target role parties rather than named twins; the party production includes @role(rolename), as in the example rule of spec §4.7:

status(atlas.*) -> @role(lead, atlas):  exact

read as: anyone currently attested as lead of atlas may receive my atlas status facts at exact granularity, whoever that is at flow time.

The deeper design comes from the Osmosis Protocol spec §7. The mesh maintains a role registry binding attested roles ("decision-owner: Atlas budget") to membranes, with bindings signed by the parties entitled to confer them. A flow directed at a role resolves against the registry at the moment the flow fires, not at the moment the rule was written. Handoffs, reorganizations, and delegation therefore require no notification to any counterparty: the binding changes, and every membrane rule that targets the role follows it silently.

Honesty: v0.1 does not implement roles

Roles are specified language, not implemented language. Be precise about this if you are building on v0.1:

  • The reference interpreter parses no roledecl. A line like assume role reviewer(atlas) is an unrecognized declaration and fails the parse. This is why dinner.osmol deliberately omits the assume role reviewer(atlas) line that appears in the spec §8 program. The shipped example is the §8 mesh minus the one construct v0.1 cannot read.
  • @role(...) parties do parse inside membrane rules (the rule grammar accepts them), but they never match any audience: the interpreter's audience check knows family, team, others, all, and literal twin names, and an @role(...) party falls through to a literal name comparison that no receiver satisfies. A role-targeted rule is, in v0.1, a rule that grants nothing.

What roles wait on is the role registry, specified as one of OMP's four control message types (role-registry queries); this puts full role support on the wire roadmap rather than in the single-process interpreter. See The Wire Ahead. An implementation may parse and store role declarations today (that much is pure front-end work, and osmol check should accept them), but honest resolution of @role(...) requires an attested registry to resolve against.

Why this construct exists at all

It would have been simpler to leave addressing to names and groups. But endpoint addressing is one of the original pathologies, present already since 1971: mail goes to a mailbox identifier, not to the party who actually holds the decision, and humans spend their lives forwarding around the difference. Semantic addressing moves that resolution into the mesh, where it can be attested, signed, and current. assume/yield is the twin-side half of that promise; the registry is the mesh-side half.

  • membrane, where @role(...) parties appear as flow-rule targets
  • stake, the other §4.9 posture construct
  • The Wire Ahead, OMP control messages, including role-registry queries