Task core-engine-value-constructors (wave-3 pre-work). All four value types are #[non_exhaustive] (ADR-017 §3), so downstream engine crates cannot struct-literal-construct them (E0639). Give engines a sanctioned construction path without weakening the consumer posture: pub #[doc(hidden)] full-field constructors (Job::from_row, StreamEvent:: from_row, Schedule::new, Wake::new), each doc-commented as engine- construction-only — not contract surface, not covered by ADR-017's semver-minor field-addition promise; a field addition changes the signature and is a lockstep-duty event (ADR-017 §5). Core tests now construct through the new constructors; no behavior change.
92 lines
4.1 KiB
Markdown
92 lines
4.1 KiB
Markdown
---
|
|
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. |