cellos-export-local 0.5.0

Local-filesystem ExportSink for CellOS — writes per-cell evidence bundles to an operator-configured directory.
Documentation

cellos-export-local

ExportSink that copies each declared evidence artifact into a local directory tree.

What it is

Implements cellos_core::ports::ExportSink. For each pushed artifact, the sink writes to <root>/<cell_id>/<safe-name>, creating directories as needed, and returns an ExportReceipt with targetKind = LocalPath.

Selected in cellos-supervisor::composition::build_export_sinks as the default sink when CELLOS_EXPORT_DIR=<path> is set and no HTTP / S3 sink is configured for the default target.

What it does NOT do:

  • It does not upload anywhere — purely filesystem cp.
  • It does not retry, hash, or sign — those are concerns of the evidence-bundle layer upstream.
  • It does not let artifact names escape the cell-export directory. The sink rejects empty names, absolute paths, path separators (/ or \\), NUL bytes, any .. traversal segment, and a leading ~. The cell_id itself is required to be a single path segment. Contract validation upstream (is_portable_identifier) already rejects most of these; this sink re-checks raw names as defense-in- depth for direct callers of push_with_len (tests, adapters).
  • On Linux it opens the destination with O_NOFOLLOW so a tampered cell directory cannot redirect writes via symlink.

Public API surface

Symbol Purpose
LocalExportSink The sink.
LocalExportSink::new(root, cell_id) Construct; rejects unsafe cell_id.
LocalExportSink::push_with_len(name, src) Lower-level helper that returns bytes written; primarily for tests / metrics.

Source: src/lib.rs.

Configuration

Env var Description
CELLOS_EXPORT_DIR Root directory for local exports. When set (and no HTTP base URL is set), the default sink is LocalExportSink::new($CELLOS_EXPORT_DIR, $cell_id).

The cell_id segment comes from spec.id.

Examples

mkdir -p /var/lib/cellos/exports
export CELLOS_EXPORT_DIR=/var/lib/cellos/exports
cellos-supervisor --spec cell.yaml
# After the cell completes:
ls /var/lib/cellos/exports/<spec.id>/

Testing

cargo test -p cellos-export-local

Tests use tempfile so no shared filesystem state is required.

Related crates

  • cellos-export-s3 — S3 presigned PUT.
  • cellos-export-http — generic HTTP PUT.
  • cellos-supervisor — selects this sink in build_export_sinks when CELLOS_EXPORT_DIR is set.
  • cellos-core — defines the ExportSink port and ExportReceipt.

ADRs

  • ADR-0006 — the evidence bundle is the 1.0 deliverable; LocalExportSink is the dev / single-host path for honouring it.