ask.
When a driver parks a run, the platform keeps only the interaction id; the driver reverses it
to its own run through this index. One consumer namespace holds, on one Redis:
- an ENTRY per resume key (an interaction id, or any key the consumer resumes by), carrying the consumer’s own opaque rebuild payload;
- a BARRIER per parked super-step (a thread’s set of asks resolved together): the consumer’s
opaque
expectedmap, keyed by member id, the answers buffered so far, and any opaque consumer fields; - a DRIVE LEASE per super-step, so exactly one worker drives a completed barrier, with a heartbeat and a token-checked release;
- a RESOLUTION RECORD per resolved super-step and a TOMBSTONE in place of every member entry, so a lapped redelivery replays what the first drive returned;
- a RUN-RESOLUTION INDEX per thread (every resolved super-step and its members), so a kill can reach every stored outcome of a run;
- a LIVE SET per thread (its super-steps whose barrier is live), so a checkpoint sweep can tell a parked thread from an abandoned one.
BARRIER_TTL_MARGIN_SECONDS
tai42_kit.interactions.park_index.BARRIER_TTL_MARGIN_SECONDS
DRIVE_LEASE_HEARTBEAT_SECONDS
tai42_kit.interactions.park_index.DRIVE_LEASE_HEARTBEAT_SECONDS
DRIVE_LEASE_SECONDS
tai42_kit.interactions.park_index.DRIVE_LEASE_SECONDS
ENTRY_TTL_FLOOR_SECONDS
tai42_kit.interactions.park_index.ENTRY_TTL_FLOOR_SECONDS
RESOLVED_FIELD
tai42_kit.interactions.park_index.RESOLVED_FIELD
Barrier
tai42_kit.interactions._park_types.Barrier
expected map, the answers buffered so far, its own fields.
Attributes
BarrierNotFoundError
tai42_kit.interactions._park_types.BarrierNotFoundError
BufferResult
tai42_kit.interactions._park_types.BufferResult
DriveInProgressError
tai42_kit.interactions._park_types.DriveInProgressError
DriveLease
tai42_kit.interactions.park_index.DriveLease
SET NX EX to win it, a heartbeat while held, a token-checked release.
Win it by entering (async with) or acquire; leave it by exiting or close,
which stops the heartbeat and releases it unless ParkIndex.finalize consumed it.
Attributes
Members
acquire
tai42_kit.interactions.park_index.DriveLease.acquire
holds
tai42_kit.interactions.park_index.DriveLease.holds
release
tai42_kit.interactions.park_index.DriveLease.release
close
tai42_kit.interactions.park_index.DriveLease.close
mark_consumed
tai42_kit.interactions.park_index.DriveLease.mark_consumed
LeaseLostError
tai42_kit.interactions._park_types.LeaseLostError
ParkIndex
tai42_kit.interactions.park_index.ParkIndex
Members
entry_key
tai42_kit.interactions.park_index.ParkIndex.entry_key
entry_id.
Parameters
barrier_key
tai42_kit.interactions.park_index.ParkIndex.barrier_key
lease_key
tai42_kit.interactions.park_index.ParkIndex.lease_key
resolution_key
tai42_kit.interactions.park_index.ParkIndex.resolution_key
run_resolutions_key
tai42_kit.interactions.park_index.ParkIndex.run_resolutions_key
live_set_key
tai42_kit.interactions.park_index.ParkIndex.live_set_key
persist
tai42_kit.interactions.park_index.ParkIndex.persist
expected (keyed by
member id) and barrier_fields; the thread’s live set lasts as long as its longest-lived
barrier.
Parameters
threads_with_live_barriers
tai42_kit.interactions.park_index.ParkIndex.threads_with_live_barriers
thread_ids with at least one live barrier.
Parameters
read_entry
tai42_kit.interactions.park_index.ParkIndex.read_entry
entry_id, or None when there is none.
Parameters
tombstone_kind
tai42_kit.interactions.park_index.ParkIndex.tombstone_kind
tombstone_coordinates
tai42_kit.interactions.park_index.ParkIndex.tombstone_coordinates
(thread_id, superstep) a resolved tombstone points at.
Parameters
read_tombstone_resolution
tai42_kit.interactions.park_index.ParkIndex.read_tombstone_resolution
None for a detached one.
Parameters
read_barrier
tai42_kit.interactions.park_index.ParkIndex.read_barrier
None when it is gone; buffered answers are decoded.
Parameters
set_barrier_fields
tai42_kit.interactions.park_index.ParkIndex.set_barrier_fields
False (nothing written) when the barrier is gone.
Parameters
buffer
tai42_kit.interactions.park_index.ParkIndex.buffer
claim
tai42_kit.interactions.park_index.ParkIndex.claim
async with or DriveLease.acquire).
Parameters
finalize
tai42_kit.interactions.park_index.ParkIndex.finalize
lease: tombstone its members, store its record, drop its barrier and lease.
One guarded step: it lands only while lease still holds the super-step, and it also
records the super-step in its thread’s run-resolution index and leaves the thread’s live
set. On success the lease is consumed and its heartbeat stopped.
Parameters
read_resolution
tai42_kit.interactions.park_index.ParkIndex.read_resolution
None when it has none.
Parameters
run_resolutions
tai42_kit.interactions.park_index.ParkIndex.run_resolutions
{} when none.
Parameters
drop_run_resolutions
tai42_kit.interactions.park_index.ParkIndex.drop_run_resolutions
keep (member tombstones and record), then its index.
Parameters
drop_resolution
tai42_kit.interactions.park_index.ParkIndex.drop_resolution
member_ids), its index member.
Parameters
detach
tai42_kit.interactions.park_index.ParkIndex.detach
extend_horizon
tai42_kit.interactions.park_index.ParkIndex.extend_horizon
expiry_at; never shrink one.
Returns False when no live entry backs entry_id (absent or a tombstone).
Parameters
ParkIndexCorruptError
tai42_kit.interactions._park_types.ParkIndexCorruptError
ParkIndexError
tai42_kit.interactions._park_types.ParkIndexError
ParkValueCodecError
tai42_kit.interactions._park_types.ParkValueCodecError
Resolution
tai42_kit.interactions._park_types.Resolution
ResolutionMissingError
tai42_kit.interactions._park_types.ResolutionMissingError
ResolutionRecord
tai42_kit.interactions._park_types.ResolutionRecord
SuperstepAlreadyResolvedError
tai42_kit.interactions._park_types.SuperstepAlreadyResolvedError
TombstoneKind
tai42_kit.interactions.park_index.TombstoneKind
barrier_ttl_seconds
tai42_kit.interactions.park_index.barrier_ttl_seconds
decode_value
tai42_kit.interactions._park_types.decode_value
encode_value’s inverse).
Parameters
encode_value
tai42_kit.interactions._park_types.encode_value
entry_ttl_seconds
tai42_kit.interactions.park_index.entry_ttl_seconds
resolution_ttl_seconds
tai42_kit.interactions.park_index.resolution_ttl_seconds
superstep_id
tai42_kit.interactions.park_index.superstep_id
Park adoption and the chained-call notices: which park a run records for a returned sentinel, and what it fires.
A park belongs to exactly ONE resume continuation — the one bound when it was raised — and
carries that owner BOTH on its sentinel and on its wire-form marker.
assert_park_adoptable
is the guard every seam that turns a park into the CALLER’s own suspended state applies: the
object seams that adopt a returned sentinel, and the CLAIM point where a driver records resume
state against a marker read off a serialized tool result. So a nested run’s park is never adopted
by its caller (which would then wait for a resume fired only at the nested run).
The owner is the continuation NAME, not a per-run token, because that is the whole of what the
platform dispatches: the name is what the interaction stores and what a later answer invokes, so
a scoped owner would have to be unscoped again before dispatch and would fork the meaning of the
resume binding. Name equality alone is not what makes the guard sound — two runs of the same
driver share a name — the None rule is: a park crossing a nested RUN’s face carries no owner
at all, so a same-named sibling is refused on that, never on a name comparison happening to
differ.
Refusing is not the only answer to a park this caller does not own. resolve_park_adoption
is the OBJECT seams’ form of the guard, and it answers adopt-your-own or CHAIN: a nested dispatch
a CHAIN routing (ChainedResume) was bound around parks on
the nested CALL — a key of its own, owned by its own resume continuation — while the nested run
keeps its park and its resume, and its terminal re-enters the caller through the routing’s
delivery tool. A dispatch nothing chained still gets the loud refusal. The CLAIM point cannot
chain: a park reaching it as content belongs to no dispatch it could attribute the call to, so
there it is adopt-or-refuse.
Every driver builds the chain fires here too — repark_notice when a chained run re-parks,
terminal_chain_notice at its terminal — so each payload has one shape.
assert_park_adoptable
tai42_kit.interactions.park_adoption.assert_park_adoptable
resume_owner is the park’s SuspendedInteraction.resume_owner, and the guard’s
role is a NESTING DISCRIMINATOR, not an authenticity token: it separates a park a run raised
UNDER ITS OWN resume binding (adoptable) from one that crossed a NESTED run’s face on the way
up (not — that nested run is resumed on its own path, so adopting it would wait for a resume
fired elsewhere and hang forever). A park a run raises for itself carries the continuation it
was raised under; a park crossing a nested RUN’s face carries no owner at all. So the guard is
sound on the None rule, not on name equality: a same-named sibling run is refused because
its park reaches here ownerless, never because two names happened to differ.
None is never adoptable, by ANY caller: it is the signal a park crossed a nested run’s
face (or is content shaped to look like a park), neither of which this caller may turn into
its own suspended state. An unbound caller is refused too — it has no continuation the
platform could fire, so a park it claimed could only hang. A BLANK owner reads as no owner:
it names no registered tool the platform could dispatch.
This name check does NOT authenticate the marker against any store — the resume owner is a
public continuation name, so a well-formed marker naming the bound continuation is treated as
adoptable here. Structural validation of the marker shape lives in
read_suspended_interaction_marker;
store-authoritative existence is a separate concern the claim seams that hold a store handle
apply.
Raises NestedParkOwnershipError BEFORE any state of the
caller’s own is recorded, so the owning run’s park stays untouched and resumable on its own
path. A seam holding the sentinel a nested CALL returned applies resolve_park_adoption
instead, which answers this same question but can also CHAIN the call rather than refuse it.
Parameters
attach_chained_park
tai42_kit.interactions.park_adoption.attach_chained_park
key as ATTACHED so the ledger drops it.
The driver recorded a park on it, so it is no longer a dead chain. A no-op when no
chained_park_claims ledger is open, or when the key was never claimed inside it.
Parameters
chained_park_claims
tai42_kit.interactions.park_adoption.chained_park_claims
resolve_park_adoption CLAIMED, yield the set.
A driver opens one around each drive so it can tell, when the drive stops, which chained
calls it actually parked on: it drops each key it persists, and whatever REMAINS is a
claim the drive never turned into a park (the run errored, or moved on without parking).
Those are dead chains — the nested run will still fire its terminal at them — so the
driver detaches them rather than leaving the fire to hunt a park that will never exist.
The yielded set is mutated in place, so a claim recorded inside a task the drive spawns
(every nested dispatch runs in a child context) is visible to the opener.
claims lets a caller pass an EXISTING set to re-bind rather than a fresh one. A driver
that binds per drive-step — the resume binding cannot span a generator’s yields, so it is
re-entered around each __anext__ — owns one accumulating set for the whole drive and
re-binds it here each step, so a claim recorded in an early step survives to the reconcile
at the end. Omit it (the default) to open a fresh ledger for the whole drive at once.
Parameters
is_chained_park_key
tai42_kit.interactions.park_adoption.is_chained_park_key
key names a chained CALL rather than a platform interaction.
The discriminator a driver indexing both key kinds reads before applying any policy that
only makes sense for one of them (a chained key has no interaction, so nothing expires
it and no answer is ever delivered against it directly).
Parameters
new_chained_park_key
tai42_kit.interactions.park_adoption.new_chained_park_key
repark_notice
tai42_kit.interactions.park_adoption.repark_notice
(tool, payload) fired when a park is raised under a bound chain routing.
Returns None when no chain routing is bound around the current dispatch.
A chained caller’s own suspension horizon is INHERITED from the nested run’s current ask,
so when that run re-parks on a new ask the caller’s horizon must move with it. The notice
is that signal: the routing’s delivery_tool paired with {CHAINED_PARK_TOKEN_KEY: routing.chain_key, "expiry_at": <iso>, "status": PARK_COMPLETION_REPARKED} — the one
non-terminal status, carrying the new deadline in place of a result and the chain key the
delivery tool reverses back to the caller’s park. It resolves nothing; the completion still
fires later under a terminal status.
Only a bound chain routing is notified, so no other delivery tool ever sees this fire.
Parameters
resolve_park_adoption
tai42_kit.interactions.park_adoption.resolve_park_adoption
(key, resume_owner) its own park is keyed and owned by.
The OBJECT seams’ form of assert_park_adoptable, for a seam holding the sentinel a
nested call returned. Three outcomes, in this order:
- the park is adoptable here (raised under the continuation bound HERE) — it is this run’s own park, returned unchanged, and the platform resumes it directly;
- otherwise, if this dispatch was CHAINED (a chain routing was bound around it,
get_chained_resume), the run parks on the chained resume KEY instead, owned by this run’s OWN resume continuation — because that park is genuinely this run’s: it waits on the CALL, while the nested run keeps its own park and its own resume and re-enters here through the chain’s delivery tool when it terminates. The key is recorded in the openchained_park_claimsledger, so a drive that never turns the claim into a park can detach it; - otherwise
NestedParkOwnershipError, exactly asassert_park_adoptableraises it: waiting on a foreign park with nothing chained would leave this run suspended behind a resume fired only at the nested run.
terminal_chain_notice
tai42_kit.interactions.park_adoption.terminal_chain_notice
(delivery tool, payload) a run’s terminal fires along its captured chain routing.
A RunFailed result is a failed terminal: its opaque
outcome rides as the result under the failed status. Any other result is a
success, carried whole. The payload keys are exactly the chain key, result and
status.
Parameters
The give-up handler seam: the driver that parked a run tells its waiter when the platform abandons the park.
When the platform gives up redelivering an answered park (its continuation-due record outlived
the redelivery horizon), the waiter to tell is the one the parking DRIVER captured for that
park. The platform names the interaction only; each driver that parks registers one handler,
reads its own record of that interaction, runs its own failed-terminal epilogue and returns the
outermost outcome for the platform to deliver to the run’s address. A handler returns
None
for an interaction that is not its park.
ParkGiveUpHandler
tai42_kit.interactions.park_giveup.ParkGiveUpHandler
ParkGiveUpOutcome
tai42_kit.interactions.park_giveup.ParkGiveUpOutcome
fire_park_giveup
tai42_kit.interactions.park_giveup.fire_park_giveup
interaction_id’s park; return the first one’s outcome.
A handler that owns the park returns its outcome and later handlers are not called; None
when no handler owns it. A handler’s raise propagates.
Parameters
register_park_giveup_handler
tai42_kit.interactions.park_giveup.register_park_giveup_handler

