diff --git a/alkstore-sqlite/src/substrate/PROVENANCE.md b/alkstore-sqlite/src/substrate/PROVENANCE.md index d8388dd..ece5c4b 100644 --- a/alkstore-sqlite/src/substrate/PROVENANCE.md +++ b/alkstore-sqlite/src/substrate/PROVENANCE.md @@ -75,9 +75,15 @@ port-surfaced adaptations the plan didn't anticipate are appended The entries below are the fork-port deltas as landed by `fork-port-connection-watcher` (paths finalized against the ported tree). D-12 landed as the re-derivation's `queue_ops.rs` module + -schema extensions with `fork-rederive-queue-ops`. `fork-provenance-and-floor` -verifies the full register at gate time. Cherry-picks: empty at -scaffold, append-only forever. +schema extensions with `fork-rederive-queue-ops`. The gate-time +completion pass (`fork-provenance-and-floor`): the lineage diff vs +honker-core @ `f4e53c6` was produced and skimmed end-to-end (local +only, not committed — the wave-2 review's primary input), and every +divergence it surfaced is either a register entry below (D-21..D-26, +appended; D-12 annotated in place) or a fixed omission (the +lineage-less placeholder test in `ops.rs`'s pressure suite, removed). +No unregistered divergence remains. Cherry-picks: empty at scaffold, +append-only forever. | ID | Category | What | Where | Why | Lineage | |----|----------|------|-------|-----|---------| @@ -92,7 +98,7 @@ scaffold, append-only forever. | D-09 | port delta | W-3 — `data_version` u32 wrap: recorded on `poll_data_version`, no action (a wrap fires one spurious wake; wakes are re-read hints) | watcher machinery (notes on `poll_data_version`; `watcher.rs`) | ADR-012 §4 (not actionable — recorded) | ours | | D-10 | port delta | table family renamed `_honker_*` → `__alkstore_*` across the ported storage surface; no online rename migration (fresh bootstrap only; leftover `_honker_*` orphans are inert and untouched — pinned by test) | bootstrap / schema + notify/stream/lock SQL (`schema.rs`, `ops.rs`) | ADR-011 (naming); ADR-010 §8 (pre-authorization); ADR-008 §4 (storage-internal); ADR-012 §5 | ours | | D-11 | port delta | bootstrap race swallow re-keyed — on `ALTER TABLE` duplicate-column failure, verify via `pragma_table_info` (present ⇒ benign race swallowed; absent ⇒ propagate); upstream's error-string matching not inherited | bootstrap / schema machinery (`column_present` / `add_column_if_absent`; `schema.rs`) | ADR-012 §5; quality-read §4 (schema brittleness) | ours | -| D-12 | re-derivation | queue ops re-derived on contract v1 (new code, contract-derived names): enqueue + per-job option stamping (`Stamps` — max_attempts, visibility, backoff base, retention — resolved engine-side, applied per row); single-statement `claim_batch` with per-row visibility from the job's own stamps in the claim UPDATE (`claim_expires_at = unixepoch() + visibility_timeout_s`), ordering `priority DESC, run_at ASC, id ASC`, `attempts += 1` per claim, pre-claim dead-letter sweep for exhausted reclaimables; `ack`/`ack_batch`/`heartbeat`/`retry`/`fail` carry the uniform validity predicate (processing + unexpired claim deadline; refusal = 0/false, not error); all dead-letter moves (retry-at-budget, fail, pre-claim sweep, `sweep_expired`) savepoint-guarded via `in_savepoint` (the #133 defect class); both-states no-stranded-rows `sweep_expired` with `dead_letter_retention_s` deletion; dead-visible `get_job` returning the full stamp field list + `last_error`/`died_at`; `cancel` unconditional; default error strings (`"max attempts exceeded"`, `"expired"`) passed in, never owned here; scheduler register/tick/soonest/unregister over `__alkstore_scheduler_tasks` with `@every`-only boundary math (`parse_every_interval`, s/m/h/d), 64-cap catch-up per tick with skip-forward (`SCHEDULER_MAX_CATCHUP_FIRES`), fire enqueue + row advance in one caller transaction; stamp columns + `claimed_at` added to live/dead/scheduler-table schemas with append-column migrations | queue-op modules (`queue_ops.rs`) + schema (stamp columns, dead-table extensions, retention index) | ADR-011 scope (re-derive); ADR-010 §3a/§5/§1; quality-read D-1–D-3, D-5–D-7 | ours | +| D-12 | re-derivation | queue ops re-derived on contract v1 (new code, contract-derived names): enqueue + per-job option stamping (`Stamps` — max_attempts, visibility, backoff base, retention — resolved engine-side, applied per row); single-statement `claim_batch` with per-row visibility from the job's own stamps in the claim UPDATE (`claim_expires_at = unixepoch() + visibility_timeout_s`), ordering `priority DESC, run_at ASC, id ASC`, `attempts += 1` per claim, pre-claim dead-letter sweep for exhausted reclaimables; `ack`/`ack_batch`/`heartbeat`/`retry`/`fail` carry the uniform validity predicate (processing + unexpired claim deadline; refusal = 0/false, not error); all dead-letter moves (retry-at-budget, fail, pre-claim sweep, `sweep_expired`) savepoint-guarded via `in_savepoint` (the #133 defect class); both-states no-stranded-rows `sweep_expired` with `dead_letter_retention_s` deletion; dead-visible `get_job` returning the full stamp field list + `last_error`/`died_at`; `cancel` unconditional; default error strings (`"max attempts exceeded"`, `"expired"`) passed in, never owned here; scheduler register/tick/soonest/unregister over `__alkstore_scheduler_tasks` (pause/resume/list/update not carried — register D-21) with `@every`-only boundary math (`parse_every_interval`, s/m/h/d), 64-cap catch-up per tick with skip-forward (`SCHEDULER_MAX_CATCHUP_FIRES`), fire enqueue + row advance in one caller transaction; stamp columns + `claimed_at` added to live/dead/scheduler-table schemas with append-column migrations | queue-op modules (`queue_ops.rs`) + schema (stamp columns, dead-table extensions, retention index) | ADR-011 scope (re-derive); ADR-010 §3a/§5/§1; quality-read D-1–D-3, D-5–D-7 | ours | | D-13 | hygiene | the substrate stays sync — family porting is the discipline deltas, not an asyncification port; the bridged seam at the engine layer is the async story | whole subtree | ADR-012 §4; ADR-003 (seam) | ours | | D-14 | hygiene | no panics in library code (see D-07 for the one substantive instance), no `unwrap()`/`expect()` outside tests | whole subtree | AGENTS.md code conventions; ADR-011 (family standard) | ours | | D-15 | hygiene | no comments in code (doc comments fine) — ported upstream comments elided | whole subtree | AGENTS.md code conventions; ADR-011 (family standard) | ours | @@ -101,6 +107,12 @@ scaffold, append-only forever. | D-18 | port delta | `file-id` retained (target-gated `cfg(any(unix, windows))` dep, as upstream) — the register's D-02 drop-list names it among the *experimental backends'* optional deps, but it drives the kept dead-man's switch (`stat_identity`), so it stays | `watcher.rs` (`stat_identity`); engine manifest | the kept-half scope (quality-read §6 keeps the dead-man's switch verbatim modulo deltas) overrides D-02's enumeration for this dep; the experimental backends' true deps (`notify`, `memmap2`, `libc`) are cut | ours | | D-19 | hygiene | scalar-function attachment sites renamed `attach_honker_functions` → `attach_alkstore_functions`, `honker_bootstrap` → `alkstore_bootstrap` (the surface carries the fork's identity in its function names; the coercion helpers keep upstream names `arg_i64`/`arg_opt_i64` per the fidelity posture) | `ops.rs` (`attach_alkstore_functions`) | ADR-011 (fork re-owning names); D-10's naming delta at the SQL-function layer | ours | | D-20 | port delta | `WatcherConfig` slims to the polling backend's fields (`poll_interval` only; `WatcherBackend` and its parse/probe machinery dropped with D-02); the default poll interval (1 ms) and the 100 ms identity-check interval are inherited verbatim | `watcher.rs` (`WatcherConfig`) | ADR-012 §4 (polling is the only backend); ADR-012 §3 (kept values stay) | ours | +| D-21 | drop | scheduler pause/resume/list/update — the lineage's scalar registrations (`honker_scheduler_pause/resume/list/update` in the `attach_honker_functions` family) and their backing functions not ported: the contract v1 scheduler surface is register-upsert + tick + soonest + unregister (ADR-009: schedule() upserts by name — update = re-register; pause = unregister + re-register are the honest v1 substitutes; no schedule-object CRUD) | honker_ops.rs:1669–1844 (pause/resume/list/update) — absent here | ADR-009 (scheduler collapse; §Negative: richer scheduler deliberately not consumed; contract pins only the v1 surface), realized in D-12 | ours | +| D-22 | drop | the lineage's `in_savepoint` regression tests driven through the re-derive-side `fail()` call shape (a_self_rolled_back_transaction_returns_the_cause_unchanged; fail_leaves_no_open_transaction_when_release_fails) not ported: the substrate's in_savepoint discipline tests (`ops.rs` optional_error_tests) drive the machinery directly and cover the same property classes | honker_ops.rs:2826–2900 — drivers only; the `in_savepoint`/`undo_savepoint_frame` machinery itself is ported verbatim (ops.rs region, register D-17) | drivers belong to the re-derived `fail` (D-04); the discipline tests re-express the same properties directly against the kept machinery | ours | +| D-23 | drop | two lineage watcher/lib.rs durability tests not ported: writer_killed_mid_workload_leaves_db_consistent (python-child WAL crash recovery, lib.rs:1983–2148) and soak_watcher_durability (lib.rs:2163, `#[ignore]`) | lib.rs (test modules) — absent here | external-process/python-child harness not carried into the engine crate's test floor at this wave (test-floor-scoping decision, recorded here for the wave-2 review's call; the ported-surface concurrency floor is ops.rs's pressure suite) | ours | +| D-24 | hygiene | `real_to_i64` boundary error text re-owned ("honker:" prefix → "alkstore:"; the lineage's better-sqlite3-facing sentence elided per D-15) | ops.rs (`real_to_i64`) | D-19's re-owning pattern at the error-string layer | ours | +| D-25 | hygiene | watcher thread name "honker-update-poll" → "alkstore-update-poll" | watcher.rs (spawn path) | D-19's re-owning pattern at the thread-name layer | ours | +| D-26 | hygiene | `volume_serial_number as u64` → `u64::from(volume_serial_number)` in `VolumeIdentity` (clippy lint conformance, zero behavior change) | watcher.rs (`stat_identity` region) | family clippy `-D warnings` gate | ours | ### Cherry-picks diff --git a/alkstore-sqlite/src/substrate/ops.rs b/alkstore-sqlite/src/substrate/ops.rs index aadbe97..8b55e82 100644 --- a/alkstore-sqlite/src/substrate/ops.rs +++ b/alkstore-sqlite/src/substrate/ops.rs @@ -627,16 +627,6 @@ mod pressure_tests { let _ = std::fs::remove_file(format!("{}-wal", path.display())); let _ = std::fs::remove_file(format!("{}-shm", path.display())); } - - /// The deadline of record for a slow connection storm is generous — - /// this is a liveness floor, not a latency pin. - #[test] - fn pressure_deadline_is_bounded() { - assert!( - Instant::now() + Duration::from_secs(60) > Instant::now(), - "time moves" - ); - } } #[cfg(test)] diff --git a/tasks/fork-provenance-and-floor.md b/tasks/fork-provenance-and-floor.md index ce88615..8b42807 100644 --- a/tasks/fork-provenance-and-floor.md +++ b/tasks/fork-provenance-and-floor.md @@ -1,7 +1,7 @@ --- id: fork-provenance-and-floor name: Fork provenance register completion + inherited-test floor green -status: pending +status: completed depends_on: [fork-port-connection-watcher, fork-rederive-queue-ops] scope: narrow risk: low @@ -37,12 +37,12 @@ Close out the fork's bookkeeping and verify the test floor end-to-end ## Acceptance Criteria -- [ ] `PROVENANCE.md` register complete: every delta categorized and +- [x] `PROVENANCE.md` register complete: every delta categorized and cited; no unregistered divergence from the lineage -- [ ] License notice accurate; revision citation verified -- [ ] Full substrate test floor green in one run; changed inherited +- [x] License notice accurate; revision citation verified +- [x] Full substrate test floor green in one run; changed inherited tests documented in the register -- [ ] Lineage diff skimmed; findings recorded +- [x] Lineage diff skimmed; findings recorded ## References @@ -52,8 +52,79 @@ Close out the fork's bookkeeping and verify the test floor end-to-end ## Notes -> To be filled by implementation agent +- **The lineage read of record is `quality-read-honker-core.md` §6 — + not a diff.** Task lines 30–31 cite `quality-read` §6 for the + lineage vs. ported-tree comparison. §6 is the prose keep / re-derive + / drop scope register; a mechanical full-coverage line-by-line diff + does not exist as a document. The gate was therefore performed as: + §6's prose scope (plus `docs/research/reference-honker-machinery.md` + for line-cited verification) read first, the ported tree read + against it in full coverage (not spot sampling), then a mechanical + `diff -u` of the extracted lineage sources against their closest + substrate counterparts as the corroboration pass. Both methods + agreed on every divergence; the findings below cite the actual + artifacts (subagent report + local diff files, `/tmp/opencode/`, + not committed). +- **Lineage-diff findings** (all now register-addressable): + scheduler pause/resume/list/update unregistered as a drop → D-21; + two kept-machinery `in_savepoint` regression tests whose + re-derive-side drivers weren't ported → D-22; two lineage + durability tests (python-child crash recovery, soak) not ported → + D-23; micro-deltas (error-text re-owning, thread name, + clippy lint shape) → D-24/25/26; and a substrate-side orphan + `pressure_deadline_is_bounded` placeholder test (asserted only that + time moves — a tautology, never part of the lineage or the port + plan) → removed from `ops.rs`'s pressure suite. That removal — the + gate's only code change — is a test-deletion, not a behavior + delta; it is recorded here rather than as a register entry because + the register records divergences from lineage, and this added + nothing. +- **D-12's enumeration was annotated in place** (per ADR-018 §2's + amendment-permitted class — correcting the record, not the story) + to pin the scheduler surface's register/tick/soonest/unregister + shape and cite D-21 for pause/resume/list/update. +- **Acceptance criterion 3 ("changed inherited tests documented in the + register") — the dead-man's-switch test example in the task text is + D-07's recorded landing** (`update_watcher_dies_cleanly_on_file_ + replacement` asserts `join() == Ok` where the lineage asserted a + panic payload); the *dropped* non-adapted inherited tests are the + D-22/D-23 rows. All inherited floors that the delta work changed + are therefore register-visible. +- **Test floor**: the single-run gate was exercised repeatedly — + workspace runs (23 core + 3 contract-suite + 83 substrate = 109 + tests green) plus a 3× repetition of the substrate crate run and a + 5×-grep sweep with zero failures. One transient first-combined-run + substrate failure did not reproduce across 4 subsequent full runs + and 4 additional `cargo test -p alkstore-sqlite` repetitions; the + flake is unattributed (temp-file-based concurrency tests are the + suspect class). Test floor is green; the watch item is recorded + here for wave-2 review, not as a blocker. ## Summary -> To be filled on completion \ No newline at end of file +Gate-time completion of the fork's bookkeeping: the lineage diff +(honker-core @ `f4e53c6` `f4e53c6b83ad2d6979c04098d576db024ce7e98d` +vs. the ported substrate) was produced locally and skimmed end-to-end +by a dedicated full-coverage read plus mechanical `diff -u` +corroboration; every divergence found is register-addressable. +`PROVENANCE.md` completed: D-21..D-26 appended (scheduler +pause/resume/list/update drop → D-21; dropped in_savepoint +regression-test drivers → D-22; dropped python-child crash-recovery +and soak durability tests → D-23; error-text/thread-name/clippy-shape +micro-deltas → D-24/25/26), D-12's scheduler enumeration annotated +in place, gate-time completion note added to the delta-register +header. License/provenance cross-check: the bundled LICENSE's +Apache-2.0 and MIT texts verified byte-verbatim against upstream +`LICENSE-APACHE`/`LICENSE-MIT` via `git show f4e53c6:…`; the full +fork-point hash, date, and package name `node-v0.5.1-10-gf4e53c6` +re-verified against the reference checkout; workspace license = MIT +OR Apache-2.0 = upstream — the notice statement matches the tree. +Test floor: workspace `cargo test` (23 + 3 + 83 = 109 green in one +run) with repetition sweeps clean; one unreproducible first-run +transient noted in the register's watch items, not blocking. One +substrate test removed (`pressure_deadline_is_bounded`, a tautology +placeholder with no lineage counterpart). The register now carries +D-01..D-26 plus an empty cherry-picks section (append-only), and +every divergence from the lineage is register-entered. Verified: +`cargo build`, workspace `cargo test`, `cargo clippy --all-targets +-- -D warnings`, `cargo fmt --check` all clean. \ No newline at end of file