pixelflow-core 0.1.0

Core abstractions shared by PixelFlow crates.
Documentation
# PIXELFLOW-CORE KNOWLEDGE BASE

## OVERVIEW

- `src/lib.rs` re-exports intended public surface. Downstream code should prefer crate-root imports over deep module paths.
- Main risk zones: frame/storage math, metadata schema enforcement, render scheduling/order, plugin ABI/host bridge.

## FILE MAP

- `src/core.rs``Core` owner, per-instance registry/config, auto plugin scan, worker-thread wiring into `RenderEngine`.
- `src/error.rs` — stable `ErrorCategory`, static dotted `ErrorCode`, shared `PixelFlowError`/`Result`.
- `src/filter.rs` — filter descriptors, generic option values, planner contract, per-core `FilterRegistry`, metadata-key registration.
- `src/format.rs` — canonical alias resolver, format families, plane descriptors, stored `SampleType` rules.
- `src/frame.rs` — aligned zeroed plane storage, `FrameBuilder`, zero-copy `view()`, typed plane APIs, raw plane seam. Contains crate unsafe storage code.
- `src/graph.rs` — immutable graph nodes/builders, clip media state, Phase 1 validation, Y4M-compatibility check.
- `src/log.rs``Logger`, `LogSink`, structured records for host/plugin diagnostics.
- `src/metadata.rs``MetadataSchema`, typed `Metadata`, core key bootstrap, plugin-key validation.
- `src/plugin_abi.rs` — stable `#[repr(C)]` host/plugin ABI structs, status codes, entry symbol/version constants.
- `src/plugin_host.rs` — dynamic library load/scan, ABI entry handshake, registrar callbacks, plugin-name/string view bridge. Contains crate unsafe FFI/load code.
- `src/render.rs``FrameExecutor`, blocking ordered render iterator, `(node, frame)` coalescing, dependency requests, timing collection.
- `src/scheduler.rs` — dependency/concurrency contracts, source capabilities, worker pool, ordered commit gate, timing report.
- `src/source.rs` — source request path/options shared by graph build and source plugins; option-name validation lives here.
- `src/y4m.rs` — Phase 1 Y4M writer and chroma-tag mapping for supported integer gray/YUV formats.
- `tests/sample_plugin.rs` — ignored end-to-end ABI smoke test using built sample plugin via `PIXELFLOW_SAMPLE_PLUGIN_PATH`.

## INVARIANTS

- Error codes stay static dotted lowercase strings. Callers may branch on `category + code`; avoid churn in existing names.
- `AllocatorConfig::actual_alignment()` normalizes requested alignment to power-of-two minimum 64. Frame stride/alignment math flows from normalized value.
- `FrameBuilder::new()` rejects zero dimensions. Per-plane width/height use descriptor divisors with round-up semantics for odd chroma sizes.
- Plane storage is zeroed on allocation. `Frame::with_metadata()` swaps metadata only; planes remain shared. `Frame::view()` is zero-copy crop-like view using original stride/storage plus advanced offset.
- Typed plane access must match stored `SampleType` exactly. No implicit conversion between `u8`, `u16`, `f32` paths.
- `Metadata::new()` prepopulates all `core:*` keys with `MetadataValue::None`.
- Plugin keys must be `publisher/plugin:key` and register before writes. `MetadataValue::None` stays valid clear/reset value for registered keys.
- `resolve_format_alias()` canonicalizes aliases; `gbrp*` resolves to canonical `rgbp*`. `FormatDescriptor::sample_type()` is storage type, so 10/12/16-bit integer formats still store as `U16`.
- Ordered render stays output-ordered even when workers finish out of order. Duplicate `(NodeId, frame_number)` requests coalesce and completed frames remain cached for waiter reuse during iterator lifetime.
- `ordered_stateful` executors may `prepare` concurrently but `commit` must serialize in increasing frame order per node.
- Successful plugin loads intentionally leak `libloading::Library` handle so resolved function pointers stay valid until process exit.
- Unsafe code lives only in `src/frame.rs` and `src/plugin_host.rs`. `plugin_abi.rs` exposes unsafe function-pointer types, but no unsafe blocks/impls.

## ANTI-PATTERNS

- Do not add public API in submodule without deciding crate-root re-export in `src/lib.rs`.
- Do not treat `bits_per_sample` as storage width selector. Use `sample_type` / `Sample` trait path.
- Do not clone frame buffers for metadata edits or crop views unless ownership model truly changes.
- Do not accept free-form metadata keys or move pointer math/FFI decoding outside `frame.rs` + `plugin_host.rs`.

## TESTING NOTES

- `frame.rs` tests are storage contract. Extend them first for alignment, sharing, offsets, raw plane, typed row access changes.
- `render.rs` tests lock ordered output, coalescing, dependency enforcement, source gates, ordered commit behavior, timing aggregation.
- `metadata.rs`, `format.rs`, `source.rs`, `plugin_abi.rs`, `plugin_host.rs` each lock local contract edges; keep error category/code assertions when behavior changes.
- `tests/sample_plugin.rs` covers real host/plugin registration path. Keep ignored unless sample plugin artifact is available.