--- id: core-engine-value-constructors name: Core — engine-side constructors for the non_exhaustive value types status: completed depends_on: [] scope: narrow risk: low impact: component level: implementation tags: [wave-3, core, pre-work] --- ## Description The engine crates must produce `Job`, `StreamEvent`, `Schedule`, and `Wake` — but all four are `#[non_exhaustive]` (ADR-017 §3), which bans struct-literal construction from outside the defining crate (E0639). Wave 3's engine is the first code that must build these values from row data, and it cannot. Give the engine crates a sanctioned construction path without weakening the consumer posture. Add `#[doc(hidden)]` constructors on each type — e.g. `Job::from_row(...)`, `StreamEvent::from_row(...)`, `Schedule::new(...)`, `Wake::new(...)` — taking the full field set, `pub` (engines are ordinary downstream crates, not in-crate) but `#[doc(hidden)]` so they stay out of the consumer-facing docs and are visibly not contract surface. Doc-comment each with its posture: engine-construction-only, not covered by ADR-017's semver-minor field-addition promise (an engine breaking on a field addition is a lockstep-duty event, ADR-017 §5 — engines are in-repo and updated with core). Alternative considered and rejected: making the fields `pub(crate)` + engine `#[cfg]` tricks, or a builder trait — both add machinery for a problem a hidden constructor solves; the non_exhaustive posture for *consumers* is untouched either way. This is deliberately a separate pre-work task (not folded into the first engine task): it touches core's contract-adjacent surface, is consumed by both engines (wave 4 needs the same constructors), and is cheap to review in isolation. ## Acceptance Criteria - [ ] `Job`, `StreamEvent`, `Schedule`, `Wake` each carry a `#[doc(hidden)]` full-field constructor, documented as engine-construction-only (not consumer API, not semver-covered) - [ ] No change to the consumer posture: the types stay `#[non_exhaustive]`; consumers cannot reach the constructors in docs (spot-check `cargo doc`) - [ ] Core tests construct through the new constructors where natural (no behavior change; existing tests keep passing) - [ ] `cargo build`, `cargo test -p alkstore`, clippy `-D warnings`, fmt clean ## References - docs/architecture/decisions/017-contract-versioning.md §3, §5 - docs/architecture/decisions/019-mechanism-handle-surfaces.md §3 - alkstore/src/job.rs, stream.rs, schedule.rs, wake.rs ## Notes - Names pinned as `Job::from_row` and `StreamEvent::from_row` (row-shaped values) but `Schedule::new` and `Wake::new` (not row-shaped) — matching the task's own examples. - `Job::from_row` takes 18 args and carries an explicit `#[allow(clippy::too_many_arguments)]` — the task pins "taking the full field set" as the posture, so arg count is intrinsic, not a smell to engineer around (no opts struct / builder introduced). - Doc-comments follow the crate's `# Contract posture` section style (see `job.rs` / `stream.rs`), naming ADR-017 §3 and §5 explicitly. - Core tests updated to construct through the new constructors: `value_type_tests.rs` (`sample_job`, `sample_event`, `wake_test`) and `trait_probe_tests.rs` (`schedule()` return). All 25 core tests still pass. ## Summary Added `#[doc(hidden)]` full-field constructors to core's four `#[non_exhaustive]` value types: `Job::from_row` (18 fields), `StreamEvent::from_row` (5 fields), `Schedule::new` (4 fields), `Wake::new` (1 field) — each `pub` with a "Contract posture" doc comment pinning engine-construction-only status, exclusion from the contract surface and ADR-017's semver-minor field-addition promise, and the ADR-017 §5 lockstep duty for field additions. `#[non_exhaustive]` left untouched on all four; consumer posture unchanged. Verified: `cargo build`, `cargo test` (workspace; core unchanged-behavior), `cargo clippy --all-targets -- -D warnings`, `cargo fmt --check` all clean. `cargo doc` spot-check: none of the four constructors appears in the generated `struct.*.html` pages; the only rustdoc warnings are three pre-existing unresolved intra-doc links in `validation.rs`, untouched by this task.