Expand description
ProjectionPlacement — the single resolver that decides where a
Step’s materialized OUTPUT file lives on disk.
§Architecture
Before this module, the target path
<root>/workspace/tasks/<task_id>/ctx/<name>.md was hardcoded
independently at three call sites — the submit-time sink
(crate::core::engine::Engine::submit_output’s
materialize_final_submission, via
crate::core::projection::FileProjectionAdapter), the server-side
read-back (crates/mlua-swarm-server/src/projection.rs’s
materialized_file_path / resolve_materialized_file), and the
spawn-time in-flight pointer
(crates/mlua-swarm-server/src/operator_ws/session.rs’s
append_projection_pointer). The three copies had drifted: the first
two resolved root as work_dir falling back to project_root, the
third used work_dir ONLY (no fallback) — an asymmetry a Blueprint
whose spawn only carries project_root silently loses its in-flight
ctx_projection pointer to.
ProjectionPlacement collapses all three copies into one type: the
sole construction site is Compiler::compile (see [Self::from_spec]),
built once from Blueprint.projection_placement
(mlua_swarm_schema::ProjectionPlacementSpec), then threaded — the
SAME “construct once, read many” pattern
crate::core::step_naming::StepNaming established for GH #23 —
through crate::blueprint::EngineDispatcher::with_projection_placement
into EngineState.projection_placements (keyed by StepId), and read
back via crate::core::engine::Engine::projection_placement_for. All
three call sites above now resolve root via [Self::resolve_root]
and the target path via [Self::target_path] — the fallback order and
the directory template are, by construction, identical wherever the
resolver is consulted.
§Byte-compat default
ProjectionPlacement::default reproduces the pre-GH-#27 hardcoded
behavior exactly: root_preference = WorkDir (work_dir falling back
to project_root) and dir_template = "workspace/tasks/{task_id}/ctx".
Every Blueprint that never declares projection_placement resolves
through this default, so this module changes no observable behavior
for pre-#27 Blueprints.
Structs§
- Projection
Placement - The projection placement resolver (see the module doc for the full
architecture narrative). Small and
Clone— every consumer holds its own copy rather than sharing a lock.Serialize/Deserialize: the spawn-time in-flight pointer (crates/mlua-swarm-server/src/operator_ws/session.rs’sappend_projection_pointer) has no directEnginehandle, socrate::middleware::agent_context::AgentContextMiddleware(which does) resolves this once per spawn and stashes it JSON-serialized intoctx.meta.runtime[crate::core::agent_context::PROJECTION_PLACEMENT_KEY]— the same channelAGENT_CONTEXT_KEYalready establishes forAgentContextViewitself.
Enums§
- Projection
Placement Error - Everything that can go wrong building a
ProjectionPlacementfrom a Blueprint-declaredmlua_swarm_schema::ProjectionPlacementSpec. Every variant carries the offending literal for the caller’s error message (the same conventionblueprint::compiler::CompileErrorfollows). - Root
Preference - Which of the spawn-time
work_dir/project_rootAgentContextViewfieldsProjectionPlacement::resolve_rootprefers, falling back to the other when the preferred one is absent.