pub struct FileProjectionAdapter { /* private fields */ }Expand description
File-backed ProjectionAdapter: materializes the projected value
under root, at the target ProjectionPlacement::target_path
resolves for key, and reads it back on Self::fetch. Self::new
resolves through ProjectionPlacement::default (the pre-GH-#27
hardcoded <root>/workspace/tasks/<task_id>/ctx/<step-or-_ctx>.md
layout, unchanged); Self::with_placement resolves through a
caller-supplied resolver instead — see
crate::core::projection_placement’s module doc for the “3 path”
convergence this collapses.
Implementations§
Source§impl FileProjectionAdapter
impl FileProjectionAdapter
Sourcepub fn new(root: impl Into<PathBuf>) -> Self
pub fn new(root: impl Into<PathBuf>) -> Self
Builds an adapter rooted at root (typically the resolved
work_dir / project_root) using the byte-compat
ProjectionPlacement::default resolver.
Sourcepub fn with_placement(
root: impl Into<PathBuf>,
placement: ProjectionPlacement,
) -> Self
pub fn with_placement( root: impl Into<PathBuf>, placement: ProjectionPlacement, ) -> Self
Builds an adapter rooted at root, resolving materialize targets
through the given placement instead of the byte-compat default —
the constructor every one of the “3 path” call sites
(crate::core::projection_placement’s module doc) uses once they
hold a Blueprint-resolved ProjectionPlacement.
Sourcepub fn materialize_submission(
&self,
key: &ProjectionKey,
value: &Value,
attempt: u32,
ok: bool,
) -> Result<ProjectionRef, ProjectionError>
pub fn materialize_submission( &self, key: &ProjectionKey, value: &Value, attempt: u32, ok: bool, ) -> Result<ProjectionRef, ProjectionError>
Submit-path materialize (subtask-4 / ST2 rework — see the module
doc’s “Submit-path projection” section). Unlike Self::project,
value is not narrowed out of a larger ctx_data via
ProjectionKey::resolve — it is the exact submitted content, so
this writes it directly. Reuses Self::target_path (the same
ProjectionPlacement-resolved target — byte-compat default
<root>/workspace/tasks/<task_id>/ctx/<step>.md — as
Self::project), so a later Self::fetch against the same
key reads it back unchanged (fetch only parses the fenced
```json block, so the extra attempt / ok front-matter
fields this writes are inert to it). A full replace, never append —
re-submitting the same (task_id, producer_agent) overwrites
(idempotent, latest wins — Subtask 4 Invariant 2 / Test 4).
key.step must be Some(producer_agent) — this is a submission
slot, never “the whole ctx” (step: None still resolves to a valid
path via ProjectionKey::step_slug’s "_ctx" fallback, but a
caller addressing an actual submission should always name the
producing agent).
Sourcepub fn materialize_part(
&self,
task_id: &str,
name: &str,
value: &Value,
) -> Result<ProjectionRef, ProjectionError>
pub fn materialize_part( &self, task_id: &str, name: &str, value: &Value, ) -> Result<ProjectionRef, ProjectionError>
Submit-path materialize for a staged named part — the file half
of the Artifact staging sink, sibling
of Self::materialize_submission. Where materialize_submission
wraps a Final OUTPUT in the YAML front-matter + fenced-JSON
convention Self::fetch parses back, this writes a part’s content
raw, because a part file is not a fetch-round-tripped
projection: it is the literal IN file the next Agent step reads. A
part named plan.md is the plan document itself, byte-for-byte, not
a JSON envelope around it — so a Value::String lands as its own
bytes with no front matter and no fenced wrapper; any other Value
is rendered as pretty JSON (the best faithful text form for a
non-string part).
name is written verbatim as the file name — unlike
Self::target_path’s <stem>.md synthesis, a part’s name
already carries its own extension (plan.md), so it IS the file
name. Because name is caller-supplied and joined onto the ctx
directory, it is guarded first: it must be a plain file name — empty,
., .., or any name containing / or \ is rejected with
ProjectionError::InvalidKey, structurally closing every path that
could escape ProjectionPlacement::target_dir.
A full replace, never append — re-staging the same name overwrites
(idempotent, latest wins — matching the fold’s last-write-wins per
name).
Trait Implementations§
Source§impl ProjectionAdapter for FileProjectionAdapter
impl ProjectionAdapter for FileProjectionAdapter
Source§fn name(&self) -> &'static str
fn name(&self) -> &'static str
"file" / "mcp-query"), used in log lines
and diagnostics.Source§fn project(
&self,
key: &ProjectionKey,
ctx_data: &Value,
) -> Result<ProjectionRef, ProjectionError>
fn project( &self, key: &ProjectionKey, ctx_data: &Value, ) -> Result<ProjectionRef, ProjectionError>
ctx_data addressed by key and returns a
locator a worker can later Self::fetch. ctx_data is the
policy-filtered ctx data slice this projection is drawn from — the
adapter never mutates it.Source§fn fetch(&self, key: &ProjectionKey) -> Result<Value, ProjectionError>
fn fetch(&self, key: &ProjectionKey) -> Result<Value, ProjectionError>
key directly, without going through
a previously returned ProjectionRef locator.Source§fn pointer_line(&self, r: &ProjectionRef) -> String
fn pointer_line(&self, r: &ProjectionRef) -> String
ProjectionRef
contributes to the directive header. Must never embed the
projected value itself (inline full-embed is the exact problem
projection exists to avoid — see the module doc).Auto Trait Implementations§
impl Freeze for FileProjectionAdapter
impl RefUnwindSafe for FileProjectionAdapter
impl Send for FileProjectionAdapter
impl Sync for FileProjectionAdapter
impl Unpin for FileProjectionAdapter
impl UnsafeUnpin for FileProjectionAdapter
impl UnwindSafe for FileProjectionAdapter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more