Example: Relationship Context¶
A ContextRecord is an assertion by a requester that they want to invoke a
specific capability under an existing AgreementRecord. A BoundaryDecision
is the operator’s signed answer to that assertion — evaluated against ordered
gates, bounded in time, and auditable independent of the agreement.
An AgreementRecord proves: two parties agreed to terms.
A BoundaryDecision proves: this specific invocation is authorised right now.
These are different claims. The agreement is permanent (until revoked or expired). The decision is ephemeral — valid for seconds or minutes, not months.
The invariant¶
BoundaryDecision.authorized == True
⟹ requested_capability ∈ agreed_terms.capabilities
∧ requested_at ∈ [valid_from, valid_until]
∧ context_freshness_seq ≥ freshness_commitment
∧ all custom operator gates passed
∧ decision_valid_until > now
A party holding an AgreementRecord cannot self-authorize execution.
Authorization requires a BoundaryDecision signed by a third party (the
operator running the BoundaryEngine).
Built-in gates (evaluated in order)¶
Gate |
Checks |
|---|---|
|
|
|
|
|
|
The first gate that fails short-circuits evaluation — later gates are not run.
Custom gates can be added to the engine via BoundaryEngine.add_gate().
Prerequisites¶
A dual-signed
AgreementRecord(fromtrust agree).An operator Ed25519 key.
Full flow¶
1. Requester creates a ContextRecord¶
genesis-mesh trust context request \
--agreement agreement.json \
--capability transactions.read \
--requester org-a \
--provider bank-a \
--freshness-seq 12 \
--output context.json
The ContextRecord is unsigned. It is an assertion — the boundary engine
decides whether it is valid.
2. Operator evaluates and produces a BoundaryDecision¶
genesis-mesh trust context evaluate \
--context context.json \
--agreement agreement.json \
--operator bank-a \
--signing-key bank.key --key-id bank-2026 \
--decision-valid-seconds 300 \
--output decision.json
Expected output when authorized:
[AUTHORIZED]
Decision : <uuid>
Context : <uuid>
Operator : bank-a
Valid until: 2026-06-27T12:05:00Z
✓ capability_check: capability 'transactions.read' is in agreed scope
✓ validity_window: request at ... is within [...]
✓ freshness_check: freshness seq 12 >= commitment 0
Exit code 0.
3. Either party verifies the decision¶
genesis-mesh trust context verify \
--decision decision.json \
--operator-public-key <bank-pub-b64>
Expected output:
[OK] authorized
Decision : <uuid>
Content : authorized
Exit code 0.
Failure cases¶
Capability not in agreed scope:
[DENIED]
✗ capability_check: capability 'admin.write' not in agreed scope [...]
Exit code 1. Only the capability gate ran — subsequent gates were not evaluated.
Request outside validity window:
[DENIED]
✓ capability_check: ...
✗ validity_window: request at ... is after valid_until ...
Exit code 1.
Insufficient freshness:
[DENIED]
✓ capability_check: ...
✓ validity_window: ...
✗ freshness_check: freshness seq 3 < commitment 10
Exit code 1.
Decision expired (verify after decision_valid_until):
[FAIL] decision_expired
Exit code 1.
BoundaryDecision structure¶
BoundaryDecision
decision_id — unique to this decision
context_id — links to the ContextRecord
agreement_id — underlying AgreementRecord
authorized — true if all gates passed
denial_reason — populated when authorized=False
gate_results
- gate_name — "capability_check", "validity_window", "freshness_check"
- passed — bool
- detail — human-readable explanation
decision_made_at — UTC timestamp
decision_valid_until — authorization ceiling (typically now + 300s)
operator_sovereign_id — who evaluated and signed
signature — Ed25519 signature by the operator
Extending the engine with custom gates¶
from genesis_mesh.trust.context import BoundaryEngine
from genesis_mesh.models.context import ContextRecord, GateResult
from genesis_mesh.models.agreement import AgreementTerms
engine = BoundaryEngine("bank-a", decision_valid_seconds=300)
def business_hours_gate(ctx: ContextRecord, terms: AgreementTerms) -> GateResult:
from datetime import timezone
hour = ctx.requested_at.astimezone(timezone.utc).hour
if 9 <= hour < 17:
return GateResult(gate_name="business_hours", passed=True, detail="within business hours")
return GateResult(gate_name="business_hours", passed=False, detail=f"outside business hours (UTC hour {hour})")
engine.add_gate(business_hours_gate)
Custom gates are appended after the built-in gates and evaluated in order.
What a BoundaryDecision does NOT prove¶
That the AgreementRecord is still current. Verify the agreement separately (
trust agree verify) before trusting the decision chain.That the delegation chain is valid. If the request comes through a delegation, verify the full chain (
trust delegate verify) first.That execution succeeded. The decision authorises execution; it does not record what happened. That is the Execution Evidence layer (v0.29).
That the agreement terms cannot change. A new
BoundaryDecisionis always required — the 5-minute window is deliberately short.
See also¶
Example: Relationship Agreement — produce the
AgreementRecordthat governs the contextExample: Attenuable Delegation Chain — delegate rights before requesting context
Example: Trust Evidence — the signed evidence embedded in the agreement