Tool execution boundary — tools never participate in logical or simulation time
Status
Implementation and canonical documentation are merged and released. Framework
phoxal/framework#268 shipped
in phoxal 0.34.0 and catalog build-20260716-0000201; CLI
phoxal/phoxal-cli#148 shipped
in v0.14.1; organization
phoxal/organization#909
landed the canonical wording. The dedicated Webots boundary example/test is
removed, and hello-rover keeps its neutral default world with 1 m walls.
All tool-boundary acceptance criteria are satisfied. The tracker remains In
review only because the released clean-room full-world run still fails later
in unchanged clocked controller/safety participants; that broader simulation
startup failure is not attributed to this clockless-tool implementation.
Problem (pre-change)
Phoxal tools represent external devices, operator actions, engineering controls,
networking, recording, and host diagnostics. They currently share the generic
participant runner with robot services, drivers, and simulators. That makes it
possible for an orchestrator or a tool to select the robot's simulation clock
even though the tool does not own a robot state transition.
The concrete current violation is tool-joypad: its 50 Hz Tokio polling loop is
host-driven, but it obtains ctx.clock() for publish timestamps, and
phoxal-cli launches it with PHOXAL_CLOCK=simulation in Webots. This couples
external controller output and lifecycle timestamps to a clock that stops while
simulation is paused. The active joypad is already a #[phoxal::tool] using a
managed async task; it does not implement Runtime, use RuntimeProcess, or
have separate runtime.rs / args.rs modules.
service/motion compounds the mismatch by applying manual-command freshness to
the producer's logical envelope timestamp with a fixed 500 ms window. It does
not retain consumer-local monotonic arrival time. Although the bus subscription
continues receiving during a logical pause and its bounded ring drops the
oldest sample, motion drains it only at logical steps.
Without a structural boundary, future tools can repeat the same mistake:
simulation pause can freeze timestamps or tool work, slow/faster-than-real-time
execution can distort host I/O, and a tool can accidentally enter a logical
clock or barrier path it does not own.
Desired outcome
Establish and enforce one suite-wide invariant:
A tool may observe or affect semantic robot state through its owning typed
contracts, but it never joins the robot's clock. Router transport and raw
diagnostic observation remain narrow non-semantic exceptions.
Tools run from host-monotonic timers, wall time where dates are semantically
required, or external events. Robot services, drivers, and simulators remain the
only participants that may execute state transitions on logical time. The
logical-time consumer owns asynchronous-input retention, freshness,
authorization, arbitration, and sampling at the step boundary.
The same tool contracts and loop semantics must work in Run, Webots, and Deploy.
Scope and ownership
Primary owner: phoxal/framework.
Affected repositories:
phoxal/framework: participant/tool boundary, official tools,
service/motion, documentation, and intrinsic compile/source/runtime guards.
phoxal/phoxal-cli: site-tool launch environment, launch-graph assertions,
mode-parity tests, and clean-room integration.
phoxal/organization: reconcile canonical architecture/process wording after
the implementation lands.
phoxal/operator: audit-only for this tracker. The current Rerun proxy is
event-driven and has no logical-clock scheduling dependency; its migration is
owned by phoxal/organization#904.
This cross-repository tracker lives in phoxal/.github. Contract and framework
enforcement land first, followed by the required framework release and catalog,
then the CLI consumer cleanup, then canonical documentation reconciliation.
Verified pre-change inventory
| Process/surface |
Classification |
Pre-change scheduling/time behavior |
Required change |
framework/tool/router |
tool / required site transport |
Zenoh events plus a host one-second metrics interval; wall-time envelope stamp; no simulation clock |
Keep host/event driven; ensure periodic work never uses catch-up bursts; retain the router transport exception without making diagnostics a tick barrier. |
framework/tool/joypad |
tool / external continuous input |
Managed 50 Hz Tokio interval with MissedTickBehavior::Delay; publishes using ctx.clock(); CLI selects simulation clock in Webots |
Remove tool clock access and Webots clock selection; use host interval with Skip; publish zero immediately on selected-device disconnect. |
framework/tool/telemetry |
tool / host observation |
Managed host one-second interval; wall-time envelope stamp; Tokio default missed-tick behavior |
Set explicit MissedTickBehavior::Skip; retain host/event timing in every mode. |
planned framework/tool/rerun |
tool / engineering recorder |
Not implemented; phoxal/organization#904 now explicitly preserves generic metadata without a simulator-clock dependency |
Keep the implementation aligned: never subscribe to or schedule from a simulator clock. |
phoxal/operator Rerun proxy |
external observation client |
Event-driven typed subscriptions and host-time retry sleeps |
No code change in this tracker; keep the replacement in phoxal/organization#904 clock-independent. |
phoxal-cli |
orchestrator |
Host/event driven; observes simulation clock for TUI display; launches joypad with simulation clock in Webots; standard tools are outside the checked robot participant graph |
Preserve display-only observation; make all standard tools clockless host/event-driven launches with no clock selection and prove they never enter the logical participant set. |
service/motion |
robot service / logical-time consumer |
Steps at 20 Hz; bounded async subscribers keep receiving during pause; manual freshness uses producer logical timestamp and a fixed 500 ms window |
Retain latest input plus consumer-local monotonic arrival time; apply a fixed 150 ms initial timeout; sample only at logical steps. |
framework/service/* |
robot services |
Checked participant kind; scheduled steps follow logical time in Webots where declared |
No classification change. |
framework/component/* |
robot drivers |
Checked driver kind; physical or simulator-substituted device integration |
No classification change. A process that needs logical device/world state remains a driver or simulator, not a tool. |
| Webots supervisor/controller |
simulators |
World/clock authorities running from Webots/host scheduling; supervisor publishes and controller may observe simulation clock |
No classification change. Simulator clock ownership remains here. |
Locked decisions
#[phoxal::tool] always uses host-time/event-driven execution. A tool cannot
select or inherit ClockMode::Simulation, even through the generic
participant launch contract.
- Remove
SetupContextToolExt::clock(). A tool that publishes uses a
host-safe timestamp path for generic envelope metadata; add a small reusable
helper only if the existing router, joypad, and telemetry code demonstrates
real duplication.
- Existing macro enforcement that prevents
#[phoxal::tool] from declaring
#[step], #[server], or #[server_snapshot] remains the structural
lifecycle guard.
- Add a lightweight repository guard preventing
framework/tool/** from
importing simulation clock contracts, ClockSource, StepContext, clock
barriers, or equivalent logical scheduling APIs.
- Tools may preserve and render generic envelope timestamps or timeline IDs as
opaque diagnostic data. phoxal-cli may observe the simulation clock for
its title bar. Neither case may schedule work, decide freshness, or join a
barrier from that data.
- External continuous state is keep-latest with bounded memory. No queued
pre-pause backlog is replayed. A controller that remains connected and keeps
publishing during pause remains current external authority; after resume the
consumer samples only the latest locally fresh state.
service/motion records consumer-local monotonic arrival time independently
from producer envelope time and applies an initial fixed 150 ms manual-input
timeout. Configurability is deferred until a robot demonstrates a real need.
- A detected selected-device disconnect publishes zero manual intent
immediately. Process or transport loss independently reaches zero through
the motion timeout.
- Joypad disconnect does not publish or synthesize an emergency-stop release.
The current joypad does not own the emergency-stop contract; this work must
not add one. Existing software and component emergency-stop ownership in
service/motion is preserved independently from the parked safety-service
direction in phoxal/organization#906.
- Periodic tool loops use
MissedTickBehavior::Skip (or equivalent
event-driven newest-wins behavior), never catch-up bursts.
- Tool lifecycle policy is unchanged: the CLI may still require and supervise
standard site tools, and a required tool failure may fail the session.
This issue guarantees only that tool readiness/failure never becomes a
logical-step completion dependency. Making tools optional is out of scope.
- No generic
ToolProcess abstraction and no compatibility clock mode are
introduced. Make the direct boundary correction.
Implementation plan
1. Framework owner and enforcement
- Document the tool/runtime/simulator boundary in active framework architecture
and authoring documentation.
- Have the participant macro assign tools a clockless launch policy: tool
binaries expose neither --clock nor --simulation, and do not bind
PHOXAL_CLOCK.
- Remove the tool clock accessor and remove clock injection from the normal
embedding APIs. Keep deterministic clock injection available only to checked
typed-graph participants.
- Retain the existing macro compile guard against scheduled/server lifecycle
methods on tools.
- Add source/compile tests for forbidden logical/simulation clock dependencies.
- Add a graph-level test proving tools cannot become logical-clock/barrier
participants.
2. Official tool correction
- Change joypad polling to
MissedTickBehavior::Skip.
- Stamp joypad publications through the host-safe tool path.
- Publish one zero manual command immediately when the selected controller is
detected as disconnected, then stop publishing movement until a controller is
selected again.
- Keep device management, manual motion, and all typed contracts identical in
Run, Webots, and Deploy.
- Give telemetry an explicit skipped-missed-tick policy.
- Audit router timing and keep its metrics window host-driven and bounded.
3. Motion asynchronous-input boundary
- Receive manual commands independently of the logical step loop.
- Retain only the newest accepted command plus its consumer-local monotonic
arrival instant.
- Apply the fixed 150 ms local timeout, finite-value checks, robot limits,
emergency-stop state, safety constraints where present, and manual/navigation
arbitration before producing drive/target at the logical step.
- Ensure a pause cannot accumulate a replay backlog and process/transport loss
reaches zero without waiting for producer logical time.
- Keep emergency-stop latching/source ownership separate from manual command
freshness and from phoxal/organization#906.
4. CLI orchestration cleanup
- Remove the Webots-specific simulation clock selection for joypad.
- Launch every
STANDARD_SITE_TOOLS entry with no clock selection and clockless host/event behavior in Run,
Webots, and Deploy.
- Keep the CLI's simulation-clock feed observational and TUI-only.
- Add mode-parity and graph tests proving tools never enter the robot logical
participant/barrier set.
- Preserve current standard-tool readiness and session supervision policy.
5. Planning and canonical docs
- Keep the already-amended
phoxal/organization#904
aligned: Rerun profiles preserve generic envelope/timeline metadata without
subscribing to simulator time; duration/size limits use host monotonic time
and measured bytes.
- Reconcile canonical organization architecture wording to the landed boundary
and final repository ownership names.
6. Intrinsic validation
- Use launch/compile coverage to prove a tool exposes no clock CLI or environment
binding and cannot use the typed-graph clock-injection seam.
- Use framework runner coverage to prove tool host loops and raw subscriptions
operate without a logical clock input.
- Keep this invariant independent of any simulator or Webots-specific world.
Mode-parity and launch-graph validation remain CLI consumer tests.
Acceptance criteria
Architecture and enforcement
Joypad and motion
Other tools and orchestration
Validation
Required checks
Framework PR:
cargo test --workspace
- targeted tool/motion/runner/graph tests added by this issue
Framework release between owner and consumer:
- publish any changed shared crates
- publish changed official tool artifacts
- produce and validate one coherent catalog/build snapshot
CLI PR:
cargo check --workspace
cargo test --workspace
- targeted launch-plan, environment, graph, and mode-parity tests
- clean-room
phoxal-cli doctor -> update -> check --strict -> simulation run <world>
Organization documentation PR:
git diff --check
- local Markdown-link verification
Delivery and land order
phoxal/framework PR: architecture, enforcement, tool correction, motion
boundary, retained hello-rover world, and intrinsic tests.
- Human approval and framework release/catalog completion.
phoxal/phoxal-cli PR: consume the released framework/catalog, remove the
invalid tool clock launch configuration, and add mode-parity/clean-room
evidence.
phoxal/organization PR: reconcile canonical architecture and runbook
wording to the landed implementation.
Each repository gets one coherent final PR for this tracker. Every PR links this
issue, names the land/release order, and reports its health-check evidence.
Non-goals
- Removing logical time from robot services, component drivers, Webots
simulators, or the framework scheduler.
- Making standard tools optional or changing current session supervision policy.
- Adding simulation-specific copies of tool contracts.
- Creating a dedicated Webots world or simulator-specific test for the tool
clock boundary; the invariant is intrinsic to the participant API.
- Making live human/device input deterministic before the robot authority accepts
it.
- Requiring a controller release/re-press gesture across pause; continuously
refreshed, locally fresh latest state remains valid.
- Making the 150 ms manual timeout configurable before evidence requires it.
- Redesigning emergency stop or the parked future safety service in
phoxal/organization#906.
- Implementing Rerun; this tracker only corrects
phoxal/organization#904's
timing requirement.
- Implementing generic deterministic replay.
- Creating a generic
ToolProcess abstraction or a compatibility clock mode.
Related work
phoxal/organization#904
— Tool Rerun recording POC; must preserve generic timeline metadata
without simulation-clock scheduling.
phoxal/organization#906
— parked safety-service direction; independent from manual freshness and
existing emergency-stop preservation.
Tool execution boundary — tools never participate in logical or simulation time
Status
Implementation and canonical documentation are merged and released. Framework
phoxal/framework#268shippedin
phoxal 0.34.0and catalogbuild-20260716-0000201; CLIphoxal/phoxal-cli#148shippedin
v0.14.1; organizationphoxal/organization#909landed the canonical wording. The dedicated Webots boundary example/test is
removed, and hello-rover keeps its neutral default world with 1 m walls.
All tool-boundary acceptance criteria are satisfied. The tracker remains In
review only because the released clean-room full-world run still fails later
in unchanged clocked controller/safety participants; that broader simulation
startup failure is not attributed to this clockless-tool implementation.
Problem (pre-change)
Phoxal tools represent external devices, operator actions, engineering controls,
networking, recording, and host diagnostics. They currently share the generic
participant runner with robot services, drivers, and simulators. That makes it
possible for an orchestrator or a tool to select the robot's simulation clock
even though the tool does not own a robot state transition.
The concrete current violation is
tool-joypad: its 50 Hz Tokio polling loop ishost-driven, but it obtains
ctx.clock()for publish timestamps, andphoxal-clilaunches it withPHOXAL_CLOCK=simulationin Webots. This couplesexternal controller output and lifecycle timestamps to a clock that stops while
simulation is paused. The active joypad is already a
#[phoxal::tool]using amanaged async task; it does not implement
Runtime, useRuntimeProcess, orhave separate
runtime.rs/args.rsmodules.service/motioncompounds the mismatch by applying manual-command freshness tothe producer's logical envelope timestamp with a fixed 500 ms window. It does
not retain consumer-local monotonic arrival time. Although the bus subscription
continues receiving during a logical pause and its bounded ring drops the
oldest sample, motion drains it only at logical steps.
Without a structural boundary, future tools can repeat the same mistake:
simulation pause can freeze timestamps or tool work, slow/faster-than-real-time
execution can distort host I/O, and a tool can accidentally enter a logical
clock or barrier path it does not own.
Desired outcome
Establish and enforce one suite-wide invariant:
Tools run from host-monotonic timers, wall time where dates are semantically
required, or external events. Robot services, drivers, and simulators remain the
only participants that may execute state transitions on logical time. The
logical-time consumer owns asynchronous-input retention, freshness,
authorization, arbitration, and sampling at the step boundary.
The same tool contracts and loop semantics must work in Run, Webots, and Deploy.
Scope and ownership
Primary owner:
phoxal/framework.Affected repositories:
phoxal/framework: participant/tool boundary, official tools,service/motion, documentation, and intrinsic compile/source/runtime guards.phoxal/phoxal-cli: site-tool launch environment, launch-graph assertions,mode-parity tests, and clean-room integration.
phoxal/organization: reconcile canonical architecture/process wording afterthe implementation lands.
phoxal/operator: audit-only for this tracker. The current Rerun proxy isevent-driven and has no logical-clock scheduling dependency; its migration is
owned by
phoxal/organization#904.This cross-repository tracker lives in
phoxal/.github. Contract and frameworkenforcement land first, followed by the required framework release and catalog,
then the CLI consumer cleanup, then canonical documentation reconciliation.
Verified pre-change inventory
framework/tool/routerframework/tool/joypadMissedTickBehavior::Delay; publishes usingctx.clock(); CLI selects simulation clock in WebotsSkip; publish zero immediately on selected-device disconnect.framework/tool/telemetryMissedTickBehavior::Skip; retain host/event timing in every mode.framework/tool/rerunphoxal/organization#904now explicitly preserves generic metadata without a simulator-clock dependencyphoxal/operatorRerun proxyphoxal/organization#904clock-independent.phoxal-cliservice/motionframework/service/*framework/component/*Locked decisions
#[phoxal::tool]always uses host-time/event-driven execution. A tool cannotselect or inherit
ClockMode::Simulation, even through the genericparticipant launch contract.
SetupContextToolExt::clock(). A tool that publishes uses ahost-safe timestamp path for generic envelope metadata; add a small reusable
helper only if the existing router, joypad, and telemetry code demonstrates
real duplication.
#[phoxal::tool]from declaring#[step],#[server], or#[server_snapshot]remains the structurallifecycle guard.
framework/tool/**fromimporting simulation clock contracts,
ClockSource,StepContext, clockbarriers, or equivalent logical scheduling APIs.
opaque diagnostic data.
phoxal-climay observe the simulation clock forits title bar. Neither case may schedule work, decide freshness, or join a
barrier from that data.
pre-pause backlog is replayed. A controller that remains connected and keeps
publishing during pause remains current external authority; after resume the
consumer samples only the latest locally fresh state.
service/motionrecords consumer-local monotonic arrival time independentlyfrom producer envelope time and applies an initial fixed 150 ms manual-input
timeout. Configurability is deferred until a robot demonstrates a real need.
immediately. Process or transport loss independently reaches zero through
the motion timeout.
The current joypad does not own the emergency-stop contract; this work must
not add one. Existing software and component emergency-stop ownership in
service/motionis preserved independently from the parked safety-servicedirection in
phoxal/organization#906.MissedTickBehavior::Skip(or equivalentevent-driven newest-wins behavior), never catch-up bursts.
standard site tools, and a required tool failure may fail the session.
This issue guarantees only that tool readiness/failure never becomes a
logical-step completion dependency. Making tools optional is out of scope.
ToolProcessabstraction and no compatibility clock mode areintroduced. Make the direct boundary correction.
Implementation plan
1. Framework owner and enforcement
and authoring documentation.
binaries expose neither
--clocknor--simulation, and do not bindPHOXAL_CLOCK.embedding APIs. Keep deterministic clock injection available only to checked
typed-graph participants.
methods on tools.
participants.
2. Official tool correction
MissedTickBehavior::Skip.detected as disconnected, then stop publishing movement until a controller is
selected again.
Run, Webots, and Deploy.
3. Motion asynchronous-input boundary
arrival instant.
emergency-stop state, safety constraints where present, and manual/navigation
arbitration before producing
drive/targetat the logical step.reaches zero without waiting for producer logical time.
freshness and from
phoxal/organization#906.4. CLI orchestration cleanup
STANDARD_SITE_TOOLSentry with no clock selection and clockless host/event behavior in Run,Webots, and Deploy.
participant/barrier set.
5. Planning and canonical docs
phoxal/organization#904aligned: Rerun profiles preserve generic envelope/timeline metadata without
subscribing to simulator time; duration/size limits use host monotonic time
and measured bytes.
and final repository ownership names.
6. Intrinsic validation
binding and cannot use the typed-graph clock-injection seam.
operate without a logical clock input.
Mode-parity and launch-graph validation remain CLI consumer tests.
Acceptance criteria
Architecture and enforcement
processes that never participate in logical or simulation time.
#[phoxal::tool]has no clock launch parameter or environment binding,cannot use the checked-graph clock-injection seam, expose a tool clock
accessor, declare a scheduled step, import simulator-clock contracts, or join
a logical clock/barrier graph.
explicitly classified by responsibility.
freshness decisions based on simulator time.
Joypad and motion
logical/simulation clock dependency.
never synthesizes emergency-stop release.
time and rejects it after 150 ms without a fresh receipt.
replays a queued pause backlog.
timeout.
emergency-stop protections remain covered.
Other tools and orchestration
simulator-clock subscription.
Webots, and Deploy.
lifecycle or step authority.
gates completion of a robot logical step.
phoxal/organization#904contains no requirement for Rerun to subscribe to a simulation clock.
Validation
tool request handling, or async subscription receipt.
cadence or cause catch-up bursts.
consumer-local timeout, stale input, bounded newest-wins receipt, and no pause
backlog replay.
doctor -> update -> check --strict -> simulation runsucceedswith the released framework/catalog and CLI consumer.
Required checks
Framework PR:
cargo test --workspaceFramework release between owner and consumer:
CLI PR:
cargo check --workspacecargo test --workspacephoxal-cli doctor -> update -> check --strict -> simulation run <world>Organization documentation PR:
git diff --checkDelivery and land order
phoxal/frameworkPR: architecture, enforcement, tool correction, motionboundary, retained hello-rover world, and intrinsic tests.
phoxal/phoxal-cliPR: consume the released framework/catalog, remove theinvalid tool clock launch configuration, and add mode-parity/clean-room
evidence.
phoxal/organizationPR: reconcile canonical architecture and runbookwording to the landed implementation.
Each repository gets one coherent final PR for this tracker. Every PR links this
issue, names the land/release order, and reports its health-check evidence.
Non-goals
simulators, or the framework scheduler.
clock boundary; the invariant is intrinsic to the participant API.
it.
refreshed, locally fresh latest state remains valid.
phoxal/organization#906.phoxal/organization#904'stiming requirement.
ToolProcessabstraction or a compatibility clock mode.Related work
phoxal/organization#904— Tool Rerun recording POC; must preserve generic timeline metadata
without simulation-clock scheduling.
phoxal/organization#906— parked safety-service direction; independent from manual freshness and
existing emergency-stop preservation.