Shared & Exclusive context and guardrails
Added in 0.8.0. Configure context/intent only, guardrails only, or both.
Shared layers apply to a declared system/task; Exclusive layers apply to named
agents. The trusted harness creates ScopedSystem, binds each agent identity,
then gives that agent only its context payload and supervised tools.
from agentic_sidecar import ContextSpec, GuardrailSpec, ScopedSystem, ScopeLayer
from agentic_sidecar.gate.policy import PolicyRule
system = ScopedSystem(
system_id="support", task_id="ticket-42", agents=["research", "refund"],
shared=ScopeLayer(
context=ContextSpec(goal="Resolve billing", values={"customer": "A100"}),
guardrails=GuardrailSpec(rules=[PolicyRule(tool="delete_*", effect="deny")]),
),
exclusive={"refund": ScopeLayer(
context=ContextSpec(goal="Prepare refund", values={"transaction": "T100"}),
guardrails=GuardrailSpec(rules=[PolicyRule(tool="export_*", effect="deny")]),
)},
)
refund = system.bind("refund", on_sidecar_failure="fail_closed")
payload = refund.context()
# Explicit transport: host writes the payload into this agent's instructions.
refund.deliver(lambda context: print(context["goals"]))
# Pass refund.sidecar to the selected framework adapter's attach().
ContextSpec carries goal text and structured values; text is not a deterministic
guardrail. Shared and exclusive goals are preserved in order. Equal duplicate
context keys are accepted; conflicting values are rejected during configuration.
Unknown/duplicate agent identities and unknown exclusive targets are rejected.
A single exclusive layer may be assigned to several agent IDs by the host.
GuardrailSpec carries ordered tool policies plus optional constraint values and
ConstraintBinding entries. Each layer is evaluated independently: an exclusive
allow cannot override a shared deny, or a weaker local limit override a shared
limit. Missing bound arguments and unknown constraint references cannot silently
pass. All mandatory checks precede custom decision hooks; warnings cannot hide a
later denial. The same checks cover full-plan evaluation. Within each policy
layer, first matching rule wins, as in PolicyAdvisor.
Each bound agent has a separate Sidecar/history/runtime. Configuration and returned
payloads are copied. Harness-bound IDs overwrite spoofed reserved decision metadata
(sidecar.scope, sidecar.context); tool arguments never select an identity.
Audit policy fingerprints include shared and exclusive guardrail configuration.
Limits and responsibilities
This is explicit host integration, not automatic prompt/memory rewriting. SDK adapters cover returned tool objects, not every framework action, handoff or retained raw function. Observe mode records without enforcement; fail_open can permit calls after evaluation failures. Use Govern/fail_closed for containment.
The configuration object and Sidecar belong to the trusted host. In-process Python wrappers are not process isolation. Run protected tools and credentials in an enforcing service under a separate identity; restrict agent access to that service. The MCP gateway example demonstrates a separate-process boundary, server-side checks and an unavailable raw tool; it does not sandbox a hostile OS user who can inspect gateway memory/files or change its launch environment.
Only assigned exclusive context is returned through explicit host delivery. In 0.9, private goals/values are not evaluator/audit metadata. Reader access, context updates/expiry/revocation, redacted evidence and operator readers are documented in v0.9. Framework memory, prompt, result and output transport remain host responsibilities; there is no process isolation or automatic secret scrubbing.