Files
alkstore/tasks/fuzz-parser-exposure.md
T

9.1 KiB
Raw Blame History

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
fuzz-parser-exposure Parser exposure — `#[doc(hidden)]` narrow surface for the three `@every` parsers + boundary arithmetic completed
narrow low component implementation
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 — #[doc(hidden)] pub use re-exports at the engine crate root:

  • alkstore-sqlite: parse_every_interval (Result<i64, String>) and skip_forward from substrate::queue_ops, widened to pub in place and re-exported from lib.rs.
  • alkstore-postgres: parse_every_interval (Result<i64> → InvalidSpec) and skip_forward from scheduler.rs, widened to pub in place and re-exported from lib.rs.
  • alkstore-mem: same shape as pg (scheduler.rs's parser + skip_forward).

The mechanical constraint this task was decomposed against (resolved 2026-10-10 with the user — do not re-derive): pub use re-exports require the item itself to carry pub — pub(crate) and module-private items fail with E0364/E0603 (compile-probed). The decomposition's original "substrate files untouched" criterion was therefore unsatisfiable for SQLite and was amended: the substrate delta is visibility-only (pub(crate)→pub on the parser, private→pub on skip_forward — two keywords in queue_ops.rs), which is legitimate because substrate/mod.rs itself classifies queue_ops.rs as the re-derived half — owned contract-v1 code, not lineage body; the ADR-012 §3 lineage-fidelity discipline governs the ported honker body (watcher.rs, connection.rs, …), untouched here. Containment holds: mod substrate is private (lib.rs), so pub items inside leak nothing until re-exported. The delta must be recorded as a PROVENANCE.md register entry (the D-31 one-line-delta precedent — category re-derivation-adjacent; a visibility-only delta on re-derived code, registered so the story stays complete). pg/mem widen to pub (not pub(crate)) for the same E0364 reason — their scheduler.rs files are engine-owned, no provenance concern.

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 keywords plus re-exports. The semver note is recorded, not hidden: doc-hidden pub items are still public API (removal is technically breaking) — the same commitment the four core #[doc(hidden)] constructors already made, bounded here to a fuzz/test purpose.

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 visibility-only: exactly the two keywords in queue_ops.rs (parse_every_interval → pub, skip_forward → pub); the lineage body (watcher.rs, connection.rs, ops.rs, schema.rs) untouched; a PROVENANCE.md delta entry records the change (amended at implementation, 2026-10-10 — mod.rs was in this list, but a second mechanical constraint forced one facade line there: see Notes. No lineage-body file was touched.)
  • pg/mem scheduler.rs diffs are visibility-only (two keywords each: parser → pub, skip_forward → pub) plus nothing else
  • 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 — and its boundary: the re-derived half is alkstore-owned)
  • alkstore-sqlite/src/substrate/mod.rs (the module doc's own classification: queue_ops.rs is "owned contract-v1 code, not lineage body")
  • alkstore-sqlite/src/substrate/PROVENANCE.md (the delta register the visibility delta is recorded in; D-31 — the one-line-delta precedent)
  • 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

Decisions of record the implementation made that the description didn't pin:

  • Second mechanical amendment — mod.rs could not stay untouched. Widening queue_ops.rs's two functions to pub is necessary but not sufficient: lib.rs cannot name the path substrate::queue_ops::… at all — mod substrate is private to substrate's subtree for queue_ops purposes, so a through-the-path re-export fails E0603, and skip_forward had no mod.rs export whatsoever (it was not in the pub(crate) use list). The only route is the facade: mod.rs gained pub use queue_ops::{parse_every_interval, skip_forward}; (one line; parse_every_interval moved out of the pub(crate) list into it — a duplicate binding would be E0252), compile-probed clean. This remains visibility-only — zero logic, zero signatures, zero names; lineage body (watcher.rs/connection.rs/ops.rs/ schema.rs) untouched; containment holds (mod substrate private).
  • mod.rs's boundary-doc sentence amended. "Nothing here is re-exported through the engine crate's public API" would have become stale the moment the facade landed; the sentence now names this sole exception inline, and the full story is registered as PROVENANCE.md D-37 (category re-derivation, per this task's amendment).
  • Reachability pin (criterion 4): compile-level test. Each engine gained src/fuzz_surface_tests.rs (#[cfg(test)], declared in lib.rs) — doc_hidden_reexports_reach_the_crate_root drives both re-exports through the crate-root path (one accept case + one skip_forward assertion each). Compile of the pub use itself is the E0364-class pin; the true external-crate consumption arrives with fuzz-target-every-parse's build (its shared crate path-depends on all three engines). Neither engine's existing suite files were touched — the pin is a separate module.
  • Semver note (recorded per the description): doc-hidden pub items are still public API — removal is technically breaking; the same commitment core's four #[doc(hidden)] constructors made, bounded to a fuzz/test purpose.

Summary

Landed (2026-10-10): the #[doc(hidden)] narrow fuzz/test surface for the three engines — parse_every_interval + skip_forward re-exported from each crate root with the one-line fuzz/test-only doc note (Job::from_row doc-posture style).

  • alkstore-sqlite: substrate/queue_ops.rs two keywords widened to pub; substrate/mod.rs gained the facade pub use line + the boundary-doc exception sentence; substrate/PROVENANCE.md D-37 registered; lib.rs #[doc(hidden)] pub use substrate::… ×2.
  • alkstore-postgres / alkstore-mem: scheduler.rs two keywords each widened to pub; lib.rs #[doc(hidden)] pub use scheduler::… ×2. No provenance concern (engine-owned files).
  • Reachability pins: src/fuzz_surface_tests.rs ×3 — one test per engine driving both crate-root re-exports.

Verified: cargo build clean; cargo test green (all suites; the three new pins pass; no engine suite touched); cargo clippy --all-targets -- -D warnings clean; cargo fmt --check clean; cargo check --target wasm32-unknown-unknown -p alkstore-mem clean. Diff audited against the (twice-amended) criteria: engine scheduler.rs/queue_ops.rs diffs are visibility keywords only.