--- id: fuzz-parser-exposure name: Parser exposure — `#[doc(hidden)]` narrow surface for the three `@every` parsers + boundary arithmetic status: pending depends_on: [] scope: narrow risk: low impact: component level: implementation tags: [wave-7, fuzzing] --- ## Description The §3.2 exposure design point, resolved by this decomposition: **option (b)** — a `#[doc(hidden)]` narrow exposure mirroring the existing `Job::from_row` / `Schedule::new` constructor precedent — with **(a)** (the public-`schedule()` path) as the in-suite companion, no new suite rows. Option (c) (a `fuzzing` feature flag) is rejected per the family's no-`#[cfg(fuzzing)]` experience. Rationale: the fast byte-level differential target the upstream docs favor needs direct parser access; the parsers are engine-internal test surfaces, not contract surface (ADR-017 §3's consumer-read policy governs core types, not these); and the `#[doc(hidden)]` precedent already exists in-repo for exactly this shape of narrow, undocumented-but-public access. What gets exposed, per engine — **at the engine crate root only; substrate files untouched** (the SQLite parser and its `skip_forward` live in the lineage-governed `substrate/queue_ops.rs`, ADR-012 §3 — the exposure is a re-export in the engine's `lib.rs`, never a substrate edit): - **alkstore-sqlite**: `#[doc(hidden)] pub use` of `parse_every_interval` (`Result`) and `skip_forward` from `substrate::queue_ops`. - **alkstore-postgres**: `parse_every_interval` (`Result` → `InvalidSpec`, currently `pub(crate)`) and `skip_forward` (currently private) widened to `pub(crate)` as needed and `#[doc(hidden)] pub use`-re-exported from `lib.rs`. - **alkstore-mem**: same shape as pg (`scheduler.rs`'s parser + `skip_forward`). Doc posture: each re-export carries a one-line doc note marking it a fuzz/test-only surface (not contract surface, not consumer API, no stability guarantee) — the `Job::from_row` precedent's doc style. No engine behavior changes; no parser logic moves; the diff is visibility plus re-exports. The **(a) companion** is recorded, not built: the public `schedule()` path against the mem and SQLite factories remains the suite's behavioral pin (already green, three-way); the `every_parse` target may optionally drive `schedule()` for register-path posture seeds, but the byte-level differential runs on the exposed functions. ## Acceptance Criteria - [ ] All three engines re-export their `parse_every_interval` and `skip_forward` from the crate root, `#[doc(hidden)]`, with the fuzz/test-only doc note - [ ] `alkstore-sqlite/src/substrate/**` diff is empty (lineage fidelity preserved — the exposure is engine-side only) - [ ] The re-exports are reachable from an external crate (pinned by a compile-level test or the `fuzz-target-every-parse` build itself; record which) - [ ] No behavior change: workspace gates green (`cargo build`, `cargo test`, clippy `-D warnings`, fmt); the engines' own scheduler/parser test suites untouched and green - [ ] `cargo check --target wasm32-unknown-unknown -p alkstore-mem` still clean (visibility widening is wasm-neutral, pinned anyway) ## References - docs/research/fuzzing.md §3.2 (the design point this resolves — options (a)/(b)/(c) and the lean) - docs/architecture/decisions/012-forked-substrate-design.md §2–§3 (one-owner parsers; substrate lineage fidelity) - docs/architecture/decisions/017-contract-versioning.md §3 (the `#[doc(hidden)]` precedent's policy boundary — engine-internal surfaces sit outside it) - alkstore/src/job.rs (`Job::from_row` — the in-repo doc-hidden precedent) ## Notes > To be filled by implementation agent ## Summary > To be filled on completion