pub struct ActionContext<'i> { /* private fields */ }Expand description
Per-Action compute context.
The 'i lifetime is currently a phantom on the public API surface.
Kernel v0.13 keeps Effect<'i, _> private, so the forge-side 'i
brand cannot be wired to a kernel-side brand cross-call; the
position is preserved so a future L0 expansion can switch to a
real-brand binding without breaking the forge signature.
Implementations§
Source§impl<'i> ActionContext<'i>
impl<'i> ActionContext<'i>
Sourcepub fn new(
world_seed: [u8; 32],
instance_id: InstanceId,
tick: Tick,
principal: Principal,
caps: CapabilityMask,
) -> Self
pub fn new( world_seed: [u8; 32], instance_id: InstanceId, tick: Tick, principal: Principal, caps: CapabilityMask, ) -> Self
Construct a fresh context. The world_seed is a non-exportable
L0 configuration secret; tests may pass any fixed
32-byte value.
Sourcepub fn with_view(self, view: &'i InstanceView<'i>) -> Self
pub fn with_view(self, view: &'i InstanceView<'i>) -> Self
Attach an L0 InstanceView snapshot — enables
ActionContext::read lookups. Method-chain builder style so
callers can write ActionContext::new(...).with_view(&view).
Sourcepub fn with_idempotency_index(self, index: &'i dyn IdempotencyIndex) -> Self
pub fn with_idempotency_index(self, index: &'i dyn IdempotencyIndex) -> Self
Attach an IdempotencyIndex backend — enables
ActionContext::idempotency_lookup to consult the L2 PG UNIQUE
INDEX (or equivalent). Without this call the lookup always returns
None (forward-compat stub).
Sourcepub fn with_actor_handle_index(self, index: &'i dyn ActorHandleIndex) -> Self
pub fn with_actor_handle_index(self, index: &'i dyn ActorHandleIndex) -> Self
Attach an ActorHandleIndex backend — enables
ActionContext::actor_by_handle to enforce E-actor-3 uniqueness
Without this call actor_by_handle always returns
None, so handle-collision rejection only fires when an L2
implementation is bound.
Sourcepub fn caps(&self) -> CapabilityMask
pub fn caps(&self) -> CapabilityMask
Caller capability mask (L2-granted authority set).
Sourcepub fn instance_id(&self) -> InstanceId
pub fn instance_id(&self) -> InstanceId
Instance identifier.
Sourcepub fn next_id(&mut self, type_code: u32) -> Result<EntityId, ActionError>
pub fn next_id(&mut self, type_code: u32) -> Result<EntityId, ActionError>
Derive the next EntityId for a given type_code. Increments the
internal per-context sequence so repeated calls within the same
tick produce distinct entities.
Sourcepub fn emit_event<E>(&mut self, event: &E) -> Result<(), ActionError>where
E: Serialize + ArkheEvent,
pub fn emit_event<E>(&mut self, event: &E) -> Result<(), ActionError>where
E: Serialize + ArkheEvent,
Emit an event. Dual-path — the payload is appended to the
EventRecord buffer (drained by drain_events,
the L1 pipeline::process_action
surface) and pushed onto the L0 Op::EmitEvent accumulator
(drained via ActionContext::drain_ops by the L2 service
layer’s bridge into the kernel).
Sourcepub fn spawn_entity_for<C: ArkheComponent>(
&mut self,
) -> Result<EntityId, ActionError>
pub fn spawn_entity_for<C: ArkheComponent>( &mut self, ) -> Result<EntityId, ActionError>
Spawn a fresh entity in the namespace of C. Allocates an
EntityId via ActionContext::next_id using C::TYPE_CODE as
the id-derivation namespace, and pushes a matching
Op::SpawnEntity into the accumulator.
The component itself is not attached here — follow with
ActionContext::set_component to attach the payload.
Sourcepub fn set_component<C: ArkheComponent>(
&mut self,
entity: EntityId,
component: &C,
) -> Result<(), ActionError>
pub fn set_component<C: ArkheComponent>( &mut self, entity: EntityId, component: &C, ) -> Result<(), ActionError>
Attach (or replace) component component on entity. Serializes
the payload via postcard and pushes a Op::SetComponent. The
runtime ledger uses the encoded size for quota accounting (L0
memory budget enforcement).
Sourcepub fn remove_component<C: ArkheComponent>(
&mut self,
entity: EntityId,
prior_size: u64,
) -> Result<(), ActionError>
pub fn remove_component<C: ArkheComponent>( &mut self, entity: EntityId, prior_size: u64, ) -> Result<(), ActionError>
Detach component C from entity. prior_size must match the
size the matching SetComponent reported — the ledger uses it to
balance the memory budget (L0 quota discipline). The kernel does
not currently expose a back-channel for the runtime to look up
the prior size; callers pass it explicitly so the size delta in
the emitted Op::RemoveComponent is balanced against the
preceding Op::SetComponent.
Sourcepub fn drain_ops(&mut self) -> Vec<Op>
pub fn drain_ops(&mut self) -> Vec<Op>
Drain accumulated L0 Ops. The L2 service layer calls this after
compute() returns, wraps each Op in Effect<'i, Unverified>,
and submits through the authorize → dispatch path.
Sourcepub fn ops(&self) -> &[Op]
pub fn ops(&self) -> &[Op]
Borrow the accumulated Op buffer without draining — for tests
and debug tooling.
Sourcepub fn idempotency_lookup(&self, key: &[u8; 16]) -> Option<(EntityId, Tick)>
pub fn idempotency_lookup(&self, key: &[u8; 16]) -> Option<(EntityId, Tick)>
Idempotency-key lookup. Consults the attached IdempotencyIndex
(see ActionContext::with_idempotency_index) if one is bound;
otherwise returns None for forward-compat.
The production path uses PG UNIQUE INDEX; the L0 kernel may layer a WAL-scan fallback beneath the same interface.
Sourcepub fn read<C: ArkheComponent>(
&self,
entity: EntityId,
) -> Result<Option<C>, ActionError>
pub fn read<C: ArkheComponent>( &self, entity: EntityId, ) -> Result<Option<C>, ActionError>
Read a component from the attached InstanceView (NC2 contract).
Returns:
Ok(Some(component))— the view is bound and the component was decoded successfully.Ok(None)— no view bound, or the component is not attached toentityin the view.Err(ActionError::InvalidInput)— the view returned bytes but postcard decoding failed (version drift or corrupt state).
Sourcepub fn staged_read<C: ArkheComponent>(
&self,
entity: EntityId,
) -> Result<Option<C>, ActionError>
pub fn staged_read<C: ArkheComponent>( &self, entity: EntityId, ) -> Result<Option<C>, ActionError>
Read a component, taking into account Op mutations staged so far in
the current compute() call. This is the staging-aware sibling of
ActionContext::read — same return shape, but a same-tick
set_component (or remove_component) earlier in the compute body
shadows the view’s bytes.
The Op accumulator is scanned in reverse, so the most-recent mutation
wins. A RemoveComponent makes the staged read return Ok(None)
even if the view still holds the prior value.
Used by E-act-7 reassign rejection: a compute that issues a
set_component::<EntityShellId> for an entity already shadowed by a
staged op must still see the staged shell, not the stale view.
Sourcepub fn actor_by_handle(
&self,
shell: ShellId,
handle: &BoundedString<32>,
) -> Option<ActorId>
pub fn actor_by_handle( &self, shell: ShellId, handle: &BoundedString<32>, ) -> Option<ActorId>
Resolve (ShellId, BoundedString<32>) → ActorId via the bound
ActorHandleIndex. Returns None if no index is attached or
the handle is unused.
The compute path uses this to enforce E-actor-3 uniqueness before
spawning a fresh ActorProfile.
Sourcepub fn authenticated_actor_user(
&self,
actor: ActorId,
) -> Result<Option<UserId>, ActionError>
pub fn authenticated_actor_user( &self, actor: ActorId, ) -> Result<Option<UserId>, ActionError>
Resolve the backing UserId for an authenticated ActorId via
the staged-aware UserBinding read. Returns:
Ok(Some(user_id))— actor has an authenticatedUserBinding.Ok(None)— no view or no binding (anonymous / pre-bind).Err(...)— view bytes failed to decode (state corruption).
Sourcepub fn user_gdpr_status(
&self,
user: UserId,
) -> Result<Option<GdprStatus>, ActionError>
pub fn user_gdpr_status( &self, user: UserId, ) -> Result<Option<GdprStatus>, ActionError>
Resolve the GDPR status of user via the staged-aware
UserProfile read. Returns Ok(None) when no profile is
reachable; the compute caller decides whether that is a soft
pass (Tier-0 / pre-Bootstrap dev) or a hard reject.
Sourcepub fn ensure_actor_eligible(
&self,
actor: ActorId,
scheduled_tick: Tick,
) -> Result<(), ActionError>
pub fn ensure_actor_eligible( &self, actor: ActorId, scheduled_tick: Tick, ) -> Result<(), ActionError>
E-user-3 C3 helper — fail an actor-originated compute when the
actor’s backing user is in GdprStatus::ErasurePending. Ok(None)
from the underlying reads (no view bound, anonymous actor, etc.)
is treated as a soft pass — the L2 service layer guarantees the
view is bound for production paths.
Sourcepub fn preview_next_id_for<C: ArkheComponent>(
&self,
) -> Result<EntityId, ActionError>
pub fn preview_next_id_for<C: ArkheComponent>( &self, ) -> Result<EntityId, ActionError>
Preview the EntityId that the next ActionContext::next_id /
ActionContext::spawn_entity_for call would produce, without
bumping the internal sequence counter.
Useful for pre-spawn validation (e.g. E-act-5 Activity self-loop rejection): compute the predicted id, compare against the target, then commit the actual spawn.
Sourcepub fn drain_events(&mut self) -> Vec<EventRecord>
pub fn drain_events(&mut self) -> Vec<EventRecord>
Drain accumulated events. Called by the pipeline after compute()
returns so the WAL append path can stream them in sequence order.
Sourcepub fn events(&self) -> &[EventRecord]
pub fn events(&self) -> &[EventRecord]
Borrow the accumulated event buffer without draining — for tests and debug tooling.