Neuromodulators Contract
This reference describes the target Neuromodulators runtime boundary: the mediation layer where RAS sends signals and receives replies, plus the later runtime collection where synthesized modulator instances are stored for retrieval.
The currently implemented work in this area is the orchestrator mediation flow. The registry and direct artifact lookup API are documented here as the future boundary they are meant to support.
Neuromodulators is the domain name of the registry. Avoid technical alternatives such as service-oriented naming.
Implementation invariant: ModulatorRelay is a boundary wrapper around a dedicated NeuralRelay instance. The wrapper defines neuromodulator-specific interfaces, while transport behavior remains standard NeuralRelay routing.
Purpose
Section titled “Purpose”Neuromodulators exists to separate two concerns:
- Mediation boundary between
RASand synthesizers overNeuralRelay. - In-process runtime object handoff using
artifact-refpointers.
A ModulatorResult carries the outcome of synthesis transmissions, and a successful child result carries an artifact-ref pointer rather than the object instance itself. RAS dereferences that pointer in Neuromodulators.
Communication defaults
Section titled “Communication defaults”These defaults are normative unless a future contract explicitly overrides them.
- All communication across this boundary MUST traverse
NeuralRelaychannels. - Modulation traffic is asynchronous and transmission-driven; the boundary delegates and reacts instead of synchronous waiting.
- Broadcast fanout has a null default outcome per receiver unless that receiver takes explicit action.
- Silent synthesizers are expected by default and MUST NOT be treated as errors.
- A result is emitted only when an explicit action produces a transmission.
Artifact reference format
Section titled “Artifact reference format”Canonical format:
neuromodulators/{artifact-key}
Rules:
artifact-keyMUST be unique within the active runtime scope.- Producers MAY choose deterministic or random keys.
- Consumers MUST treat
artifact-refas opaque and MUST NOT infer subtype semantics from key fragments.
Artifact lifecycle states
Section titled “Artifact lifecycle states”Each stored modulator artifact SHOULD be modeled with an explicit lifecycle state:
published: artifact was added and is resolvable.consumed: artifact was resolved at least once byRAS.expired: artifact retention window elapsed and it is no longer resolvable.removed: artifact was explicitly deleted by policy or cleanup.
State invariants:
publishedmust transition only toconsumed,expired, orremoved.consumedmay remain resolvable or transition toexpiredorremovedbased on retention policy.expiredandremovedare terminal for resolution purposes.
Interface: RAS-facing
Section titled “Interface: RAS-facing”These methods describe the future public boundary around the orchestrator flow.
RAS uses this interface to submit a single modulator signal, consume explicit synthesis outcomes when they are emitted, and resolve the resulting artifact.
from typing import Protocol
class NeuromodulatorsForRAS(Protocol): def signal(self, signal: "ModulatorSignal") -> None: """ Accept a single modulator signal from RAS, fan out to registered synthesizers, and delegate on asynchronous relay channels. """
def subscribe_results(self, handler: "ModulatorResultHandler") -> None: """ Subscribe to explicit modulation outcome transmissions emitted by Neuromodulators. """
def get(self, artifact_ref: str) -> "Modulator": """ Resolve an artifact-ref to a concrete modulator instance.
Raises: KeyError (or domain equivalent) when the artifact-ref cannot be resolved. """
def remove(self, artifact_ref: str) -> None: """ Remove a previously published modulator instance when retention policy requires cleanup. """Behavior requirements:
signalMUST preserve link correlation across the originating signal and subsequent synthesis outcomes.- Emitted results MUST be resolvable through
getwhen the synthesizer succeeds. signalMUST ignore silent synthesizers and MUST NOT require every registered synthesizer to reply.signalMUST treat null broadcast outcomes as default and MUST react only to explicit reply transmissions.getMUST return the same concrete object instance published by synthesizeradd.getMUST fail clearly for missing, malformed, or expired references.removeSHOULD be idempotent.
Optional policy extension:
getMAY support a consume-on-read policy that transitionspublishedtoconsumedatomically.
Interface: synthesizer-facing
Section titled “Interface: synthesizer-facing”These methods describe the future synthesizer-side registry boundary.
Synthesizers use this interface to publish produced modulators.
from typing import Protocol
class NeuromodulatorsForSynthesizer(Protocol): def add(self, artifact_key: str, modulator: "Modulator") -> str: """ Store a concrete modulator instance and return its artifact-ref.
Returns: A stable pointer in the form "neuromodulators/{artifact_key}". """
def register_synthesizer(self, synthesizer: "Synthesizer") -> None: """ Register a synthesizer for signal fanout. """Behavior requirements:
addMUST store the exact runtime instance passed by the synthesizer.addMUST return anartifact-refthatRAScan resolve later in the same runtime scope.- On key collision, implementations MUST either fail fast or replace atomically based on package policy; behavior MUST be documented per runtime.
register_synthesizerMUST include the synthesizer in subsequent signal fanout.
Messaging split
Section titled “Messaging split”The broker boundary has two distinct naming layers:
| Scope | Canonical names | Meaning |
|---|---|---|
| External (RAS ↔ Neuromodulators) | ModulatorSignal, ModulatorSuccess, ModulatorFailure |
Signal/reply vocabulary seen by callers and runtime boundary consumers. |
| Internal (Neuromodulators ↔ Synthesizer) | SynthesisBroadcast, SynthesisReply |
Broadcast delegation and explicit reply reporting on relay channels. |
External names describe the modulator signal being delegated. Internal names describe the synthesis work being performed.
Flow contract
Section titled “Flow contract”RASsubmits a singleModulatorSignaltransmission toNeuromodulatorsviasignal.Neuromodulatorsbroadcasts aSynthesisBroadcastto all registered synthesizers.- Synthesizers that cannot satisfy the signal remain silent.
- Eligible synthesizers return explicit
SynthesisReplytransmissions with produced artifact metadata or explicit failure diagnostics. Neuromodulatorsconverts explicit synthesis outcomes into externalModulatorSuccessorModulatorFailuretransmissions on the relay channel.RASresolves the returnedartifact-refviaget, receives the resolved instance through a terminal registered toNeuralRelay, and injects it intoModulatorCocktail.- Any later responses from other synthesizers are processed according to explicit result policy on the relay channel; silence remains a null default.
Broadcast and reply clarification:
SynthesisBroadcastdoes not require receivers to respond.- The default outcome of a
SynthesisBroadcastfor non-responsible receivers is null (silence). SynthesisReplyis emitted only by components that take explicit action on the relay channel.
Error model
Section titled “Error model”Minimum expected failures:
- Invalid reference format.
- Missing artifact.
- Expired artifact due to cleanup policy.
- Cross-runtime reference leak.
- Fanout dispatch failure.
- Reply emission failure.
Canonical error codes:
NM_INVALID_REF_FORMATNM_NOT_FOUNDNM_EXPIREDNM_REMOVEDNM_RUNTIME_SCOPE_MISMATCHNM_KEY_COLLISIONNM_FANOUT_DISPATCH_FAILEDNM_RESPONSE_EMIT_FAILEDNM_NO_MATCHING_SYNTHESIZER
Prefix convention:
- The
NM_prefix is the canonical namespace for Neuromodulators error codes. NM_is an explicitly approved abbreviation in this context and MUST be used consistently.- New Neuromodulators error codes MUST use upper-snake-case with the
NM_prefix.
When resolution fails, RAS SHOULD emit diagnostics tied to link and fail the affected modulation path explicitly.
Recommended diagnostic shape:
code: one of the canonical error codes.artifact-ref: failing reference.link: signal-reply correlation id.synthesizer-id: origin synthesizer when known.message: human-readable summary.
Pydantic validation readiness
Section titled “Pydantic validation readiness”The contract is ready for strict Pydantic validation with the following minimum DTOs:
ArtifactRefDTOwith regex validation forneuromodulators/{artifact-key}.NeuromodulatorRecordDTOwith lifecycle state enum and timestamps.NeuromodulatorResolutionErrorDTOwith canonical error code enum.
Example DTO sketch:
from datetime import datetimefrom typing import Literal
from pydantic import BaseModel, ConfigDict, Field
class ArtifactRefDTO(BaseModel): model_config = ConfigDict(extra="forbid") artifact_ref: str = Field(alias="artifact-ref", pattern=r"^neuromodulators/[A-Za-z0-9._:-]+$")
class NeuromodulatorRecordDTO(BaseModel): model_config = ConfigDict(extra="forbid") artifact_ref: str = Field(alias="artifact-ref", pattern=r"^neuromodulators/[A-Za-z0-9._:-]+$") state: Literal["published", "consumed", "expired", "removed"] published_at: datetime = Field(alias="published-at") consumed_at: datetime | None = Field(default=None, alias="consumed-at") expired_at: datetime | None = Field(default=None, alias="expired-at")Observability
Section titled “Observability”Implementations SHOULD log:
- inbound signal envelope metadata (
link,message-id, source). - fanout dispatch and synthesizer selection outcomes.
- reply emission events back to
RAS. artifact-refissuance and resolution events.- Producer synthesizer identity.
- Signal chain correlation ids.
- Cleanup and expiration events.
This enables deterministic tracing from ModulatorSignal ingress through reply mediation and runtime injection.
Relationship to other contracts
Section titled “Relationship to other contracts”- NeuralRelay Modulator Messages: message envelope and payload fields for RAS-to-Neuromodulators signals and mediated replies.
- RAS Bridge Contract: launch handoff boundary where modulation is orchestrated.
- Substrate Package Requirements: package-level obligations for modulation behavior.