feat(calendar): contain default-off bulk execution (slice 1) #806

Open
kayg wants to merge 3 commits from feat/calendar-v2-s1-containment into dev
Owner

Calendar backend v2 plan — Slice 1: Containment

Plan from #802 (docs/calendar-backend-v2-plan @ c19747b2), slice 1 of 10: port the default-off bulk execution deferral and production replay tests only. Preserve receipts and partial owners, including restart and undo. Every slice is default-off for new writes; this PR leaves calendar writes disabled.

Failure Effect Detection Recovery Test
Disabled writes via replay/undo Defer before next write Single bulk boundary including undo ancestry Keep plans/progress/receipts; explicit version migration later Queued/partially completed jobs, cycles, direct service calls

Size: 3 files, 371 insertions and 3 deletions.
Complexity: O(d) history lookups and O(d) cycle-detection memory for d undo ancestors; constant time when there is no undo ancestry.

Implementation

The shared bulk execution boundary defers event jobs before the next bulk write. Undo jobs whose ancestry contains an event job are also deferred. Deferred rows remain eligible for startup replay with their plans, progress and receipts intact; missing or cyclic undo history fails closed. The narrow behavior was ported from held #785 at eb7ffd2d; #781, #783 and #785 remain unchanged.

Production replay coverage checks fresh event jobs and ordinary bulk jobs, startup replay after restart with a partial owner receipt, completed-event undo, and missing/cyclic undo history. The four replay tests assert that deferral causes no marker writes.

Verification

  • cargo fmt --all -- --check — passed.
  • cargo clippy -j4 -p calternal-notes -p calternal --all-targets --locked -- -D warnings — passed; no Rust warnings.
  • cargo test -j4 -p calternal-notes --locked — 447 passed, 0 failed, 6 ignored.
  • cargo test -j4 -p calternal --locked — 61 passed, 0 failed, 4 ignored.

Deferred event jobs stay durable and non-executable until a later explicit version migration. Refs #802.

## Calendar backend v2 plan — Slice 1: Containment Plan from #802 (docs/calendar-backend-v2-plan @ c19747b2), slice 1 of 10: port the default-off bulk execution deferral and production replay tests only. Preserve receipts and partial owners, including restart and undo. Every slice is default-off for new writes; this PR leaves calendar writes disabled. | Failure | Effect | Detection | Recovery | Test | | --- | --- | --- | --- | --- | | Disabled writes via replay/undo | Defer before next write | Single bulk boundary including undo ancestry | Keep plans/progress/receipts; explicit version migration later | Queued/partially completed jobs, cycles, direct service calls | **Size:** 3 files, 371 insertions and 3 deletions. **Complexity:** O(d) history lookups and O(d) cycle-detection memory for d undo ancestors; constant time when there is no undo ancestry. ## Implementation The shared bulk execution boundary defers event jobs before the next bulk write. Undo jobs whose ancestry contains an event job are also deferred. Deferred rows remain eligible for startup replay with their plans, progress and receipts intact; missing or cyclic undo history fails closed. The narrow behavior was ported from held #785 at eb7ffd2d; #781, #783 and #785 remain unchanged. Production replay coverage checks fresh event jobs and ordinary bulk jobs, startup replay after restart with a partial owner receipt, completed-event undo, and missing/cyclic undo history. The four replay tests assert that deferral causes no marker writes. ## Verification - cargo fmt --all -- --check — passed. - cargo clippy -j4 -p calternal-notes -p calternal --all-targets --locked -- -D warnings — passed; no Rust warnings. - cargo test -j4 -p calternal-notes --locked — 447 passed, 0 failed, 6 ignored. - cargo test -j4 -p calternal --locked — 61 passed, 0 failed, 4 ignored. Deferred event jobs stay durable and non-executable until a later explicit version migration. Refs #802.
style(notes): format replay containment tests
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
f1468f739a
Author
Owner

Independent review, round 1

Verdict: fix first. Reviewed f1468f739a50eadd42837629c541b278a326dd00 against 133cf2c2, slice 1 of plan #802, relevant ADRs, and held #785's final round-3 review (#71086). No code pushed or merged.

P0: none found. P1: none found.

P2 — Complete the production restart/undo preservation matrix before calling containment proven. crates/notes/src/bulk/replay_tests.rs:119–200 reopens one running, create-completed/edit-pending promotion job. It never reopens a completely queued job or an already-deferred job. :204–277 undoes a completed promotion, not the deferred partial-owner job, and does not restart with its deferred undo. Thus the required queued/partial replay row and preservation of deferred partial owners through restart and undo are only partly covered. The assertion at :276 calls the owner partial even though both original steps completed. This is a validation gap, not a demonstrated write bypass.

Add production Notes::new reopen cases for (1) a queued Create+Edit event plan, asserting no owner creation or source edit, (2) the already-deferred partial job across a second restart, and (3) undo of that deferred partial job, followed by restart with both original and undo deferred. Assert original/undo plans, summary, progress and durable receipts survive, owner/source bytes remain exact, rows remain discoverable, and repeated runner/undo calls cannot execute them. Observe completion of startup's attempt rather than treating a pre-existing deferred state as proof the attempt ran. This is within slice 1; no enablement or new event implementation is needed.

P3: no additional finding.

Static trace and scope:

  • drive and drive_locked converge on drive_inner; the gate at bulk/mod.rs:336 precedes rebase, undo guards and every step executor. events-* jobs are durably deferred; ordinary jobs retain their existing execution path. Already-deferred jobs cannot fall through to execution.
  • Undo plans retain undo_of; ancestry lookup recognizes event ancestors and refuses missing/cyclic history before steps. An error from the deferred undo prevents the original being marked undone or its unapplied history being dropped. The new history query includes deferred rows; job_save preserves step receipt rows while storing the loaded progress.
  • This dev-based slice contains no crates/events, event service, event action registry, or automatic event marker allocator/importer. Ordinary imports/source edits may preserve authored marker bytes; that is not automatic marker generation. Existing normal note writes remain enabled. No production event-writing bypass found in this scope.
  • Exactly three changed files: bulk gate, history running/deferred lookup, and containment tests. No parser, props writer, claims, promotion, UI or later-slice implementation was imported. #785's inherited writer/parser blockers are not imported by this diff.

Fresh verification on dev-02 at the exact reviewed head, using the Nix shell and slot wrapper:

nix develop -c bash -c '~/bin/slot cargo test -j4 -p calternal-notes --locked bulk:: -- --nocapture'

8 passed, 0 failed, including all four new containment tests. Log: ~/review806-r1-tests.log on dev-02. The first launch was blocked by missing Git-visible Nix scaffolding; after applying the brief's temporary scaffold setup, the command above passed. No fresh full-suite, clippy, browser or process-kill proof is claimed. These tests synthesize durable boundaries and perform graceful reopen; they are not OS-kill tests.

# Independent review, round 1 **Verdict: fix first.** Reviewed `f1468f739a50eadd42837629c541b278a326dd00` against `133cf2c2`, slice 1 of plan #802, relevant ADRs, and held #785's final round-3 review (#71086). No code pushed or merged. **P0: none found. P1: none found.** **P2 — Complete the production restart/undo preservation matrix before calling containment proven.** `crates/notes/src/bulk/replay_tests.rs:119–200` reopens one **running, create-completed/edit-pending** promotion job. It never reopens a completely queued job or an already-**deferred** job. `:204–277` undoes a **completed** promotion, not the deferred partial-owner job, and does not restart with its deferred undo. Thus the required queued/partial replay row and preservation of deferred partial owners through restart **and undo** are only partly covered. The assertion at :276 calls the owner partial even though both original steps completed. This is a validation gap, not a demonstrated write bypass. Add production `Notes::new` reopen cases for (1) a queued Create+Edit event plan, asserting no owner creation or source edit, (2) the already-deferred partial job across a second restart, and (3) undo of that deferred partial job, followed by restart with both original and undo deferred. Assert original/undo plans, summary, progress and durable receipts survive, owner/source bytes remain exact, rows remain discoverable, and repeated runner/undo calls cannot execute them. Observe completion of startup's attempt rather than treating a pre-existing deferred state as proof the attempt ran. This is within slice 1; no enablement or new event implementation is needed. **P3: no additional finding.** Static trace and scope: - `drive` and `drive_locked` converge on `drive_inner`; the gate at `bulk/mod.rs:336` precedes rebase, undo guards and every step executor. `events-*` jobs are durably deferred; ordinary jobs retain their existing execution path. Already-deferred jobs cannot fall through to execution. - Undo plans retain `undo_of`; ancestry lookup recognizes event ancestors and refuses missing/cyclic history before steps. An error from the deferred undo prevents the original being marked undone or its unapplied history being dropped. The new history query includes deferred rows; `job_save` preserves step receipt rows while storing the loaded progress. - This dev-based slice contains no `crates/events`, event service, event action registry, or automatic event marker allocator/importer. Ordinary imports/source edits may preserve authored marker bytes; that is not automatic marker generation. Existing normal note writes remain enabled. No production event-writing bypass found in this scope. - Exactly three changed files: bulk gate, history running/deferred lookup, and containment tests. No parser, props writer, claims, promotion, UI or later-slice implementation was imported. #785's inherited writer/parser blockers are not imported by this diff. Fresh verification on dev-02 at the exact reviewed head, using the Nix shell and slot wrapper: ```sh nix develop -c bash -c '~/bin/slot cargo test -j4 -p calternal-notes --locked bulk:: -- --nocapture' ``` **8 passed, 0 failed**, including all four new containment tests. Log: `~/review806-r1-tests.log` on dev-02. The first launch was blocked by missing Git-visible Nix scaffolding; after applying the brief's temporary scaffold setup, the command above passed. No fresh full-suite, clippy, browser or process-kill proof is claimed. These tests synthesize durable boundaries and perform graceful reopen; they are not OS-kill tests.
Author
Owner

round 1 follow-up

Added the requested production reopen coverage:

  • A queued Create+Edit event plan becomes deferred after Notes::new, keeps its plan and empty progress, remains discoverable, and repeated drive calls leave the owner absent and source bytes unchanged.
  • A partial event job keeps its created-owner receipt across restart. Its undo plan remains deferred; a second restart replays both deferred rows. The test observes each job-row update, checks the original and undo plans, summary, progress and receipts, and verifies repeated runner/undo calls leave owner/source bytes and markers unchanged.

No production bug was exposed, so this is test-only. Head: a451ac72.

Verification on dev-01, inside nix develop through ~/bin/slot:

  • cargo fmt --all -- --check — passed.
  • cargo clippy -j4 -p calternal-notes -p calternal --all-targets --locked -- -D warnings — passed with no Rust warnings.
  • cargo test -j4 -p calternal-notes --locked — 447 passed, 0 failed, 6 ignored.
  • cargo test -j4 -p calternal --locked — 61 passed, 0 failed, 4 ignored.
  • cargo test -j4 -p calternal-notes --locked bulk:: -- --nocapture — 8 passed, 0 failed.

Nix evaluation printed its existing stdenv.isLinux and stdenv.isDarwin deprecation warnings.

## round 1 follow-up Added the requested production reopen coverage: - A queued Create+Edit event plan becomes deferred after `Notes::new`, keeps its plan and empty progress, remains discoverable, and repeated `drive` calls leave the owner absent and source bytes unchanged. - A partial event job keeps its created-owner receipt across restart. Its undo plan remains deferred; a second restart replays both deferred rows. The test observes each job-row update, checks the original and undo plans, summary, progress and receipts, and verifies repeated runner/undo calls leave owner/source bytes and markers unchanged. No production bug was exposed, so this is test-only. Head: `a451ac72`. Verification on dev-01, inside `nix develop` through `~/bin/slot`: - `cargo fmt --all -- --check` — passed. - `cargo clippy -j4 -p calternal-notes -p calternal --all-targets --locked -- -D warnings` — passed with no Rust warnings. - `cargo test -j4 -p calternal-notes --locked` — 447 passed, 0 failed, 6 ignored. - `cargo test -j4 -p calternal --locked` — 61 passed, 0 failed, 4 ignored. - `cargo test -j4 -p calternal-notes --locked bulk:: -- --nocapture` — 8 passed, 0 failed. Nix evaluation printed its existing `stdenv.isLinux` and `stdenv.isDarwin` deprecation warnings.
Author
Owner

housekeeping #1009: rebased+failing, left open for review.

rebased calendar containment slice.

head: 44a080ebb3938c4aa4d6c7e83078c051f2706e8b; based on dev cd7f84432febfc63b788fbb9b9f9950452982d74, pushed with the original exact force-with-lease.

frontend frozen install, check, lint, build and unit tests passed. bundle gate passed. first-paint brotli vs dev: JS 230777 B (+0 B), CSS 18386 B (+0 B).

Rust gate results (Mac VM):

exit command
0 cargo fmt -p calternal-notes -- --check
0 cargo check -j4 --locked -p calternal-notes --all-targets
0 cargo clippy -j4 --locked -p calternal-notes --all-targets -- -D warnings
101 cargo test -j4 --locked -p calternal-notes

the Notes suite was stopped after six minutes with two executor tests still pending. this is an incomplete run, not an assertion failure or a performance measurement.

all executed gates used the VM Nix environment, shared Mac lock and slot. exact commands, source heads, logs and dev baseline. frontend inputs are identical to the tested frontend tree when a Rust-only repair changed the head.

original-head cherry/patch inventory, pr-806.md; unmatched entries are missing-patch candidates, with semantic overlap/replacements noted above.

housekeeping #1009: rebased+failing, left open for review. rebased calendar containment slice. head: `44a080ebb3938c4aa4d6c7e83078c051f2706e8b`; based on dev `cd7f84432febfc63b788fbb9b9f9950452982d74`, pushed with the original exact force-with-lease. frontend frozen install, check, lint, build and unit tests passed. bundle gate passed. first-paint brotli vs dev: JS 230777 B (+0 B), CSS 18386 B (+0 B). Rust gate results (Mac VM): | exit | command | |---|---| | 0 | `cargo fmt -p calternal-notes -- --check` | | 0 | `cargo check -j4 --locked -p calternal-notes --all-targets` | | 0 | `cargo clippy -j4 --locked -p calternal-notes --all-targets -- -D warnings` | | 101 | `cargo test -j4 --locked -p calternal-notes` | the Notes suite was stopped after six minutes with two executor tests still pending. this is an incomplete run, not an assertion failure or a performance measurement. all executed gates used the VM Nix environment, shared Mac lock and slot. [exact commands, source heads, logs and dev baseline](https://git.kayg.org/attachments/bdb8d284-b80d-4185-b0be-6fa74f48a191). frontend inputs are identical to the tested frontend tree when a Rust-only repair changed the head. [original-head cherry/patch inventory](https://git.kayg.org/attachments/e05a38dc-c028-4d77-8655-efa9d5c8ea50), `pr-806.md`; unmatched entries are missing-patch candidates, with semantic overlap/replacements noted above.
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Merge conflict checking is in progress. Try again in few moments.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/calendar-v2-s1-containment:feat/calendar-v2-s1-containment
git switch feat/calendar-v2-s1-containment

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch dev
git merge --no-ff feat/calendar-v2-s1-containment
git switch feat/calendar-v2-s1-containment
git rebase dev
git switch dev
git merge --ff-only feat/calendar-v2-s1-containment
git switch feat/calendar-v2-s1-containment
git rebase dev
git switch dev
git merge --no-ff feat/calendar-v2-s1-containment
git switch dev
git merge --squash feat/calendar-v2-s1-containment
git switch dev
git merge --ff-only feat/calendar-v2-s1-containment
git switch dev
git merge feat/calendar-v2-s1-containment
git push origin dev
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal!806
No description provided.