feat(tasks): port B1 status plans to the Home executor #812

Closed
kayg wants to merge 0 commits from feat/tasks-v2-set-status into dev
Owner

Ports tasks.set-status and tasks.set-status-many to pure raw-byte plans submitted to the shared Home executor. One transaction groups status/completed property splices and owning checkbox characters, with exact inverse offsets. No action-specific write, Flush, recovery or undo implementation is retained from #801.

Supersedes #801. Stack: #809 → #814 (0f38d06f), plus #813 (11230729) and the shared parsed view from #805 (948117cc). #814 remains under review. Q1–Q6 on #808 are still pending; this port uses the executor's conservative defaults. Never merge.

Implementation:

  • The shared pulldown-cmark view now exposes original-byte checkbox spans and parsed owner destinations without changing the serialized editor contract. Code spans, fences and comments never supply checkbox mutations.
  • The pure planner validates the strict writer's complete input/output grammar, combines property and checkbox splices in original coordinates and verifies the exact inverse. Incoming links are indexed candidates; shared ownership checks and legacy owner expectations prevent a missing parsed owner from silently changing metadata alone.
  • The adapter bounds capture and submits changed notes plus unchanged read dependencies once. Shared admission checks captured room versions, the incoming inventory revision and strict metadata. Request fingerprints let retries recover the immutable recorded plan before fresh capture. Publication, history, placement and recovery remain executor-owned.
  • notes.undo reaches the executor's inverse path. #814 still refuses Home undo; responses expose undo_available: false. Recorded byte-executor inverses are tested where enabled.

Supported scope and refusals:

  • Recurring writes refuse. #813 cannot write the normative singular map-list log, and #814 does not admit occurrence participants. No session-link log or guessed occurrence is written.
  • Unsupported metadata remains exact, including the legacy unquoted UUID/timestamps produced by ordinary note creation. Positive Home fixtures explicitly correct metadata in source first; ordinary generated metadata has a refusal regression. Existing generic property routes stay unchanged.
  • Notes outside the shared in-process routing budget, custom marks, unsupported indexed owners, ambiguous/fragment/encoded owner links and source authority without a shared adapter refuse the selection. An unrelated inventory update may conservatively refuse admission.

Size/cost: the planner is about 260 production lines, with capture/submit separate. Planning is O(N + P log P + S log S), plus indexed incoming queries and per-note owner-range lookups; memory O(N + P + S). Existing executor caps and WAL/publication costs remain. No performance, power-loss, Apple or supported recurring-outcome pass is claimed.

failure effect detection recovery test
unsupported metadata/parser/owner no admission strict writer/shared view explicit correction refusal corpus + positive controls
stale participant/inventory whole refusal exact bytes, room version, inventory revision explicit fresh attempt single/many stale and shared admission probes
crash after PREPARE pending, no partial accepted generation shared WAL/directional evidence same recorded plan every forward/inverse byte boundary and Home publication boundary, repeated restart
changed post-image before inverse whole inverse refused exact bytes/ancestry retain evidence CRLF/BOM/duplicate-property regressions
Home undo refusal shared inverse entrypoint retain record; adapter remains gated action-to-executor gate

Validation: all gates passed on dev-01 in ~/Developer/Worktrees/tasks-v2-set-status, through nix develop -c bash -c, at 825c73c4. Final head e7e0831553b291ea96d748725c143fdb9e0248d7 only adds the regression seed already exercised in that passing VM run and updates documentation.

cargo fmt --all --check
~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings
~/bin/slot cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal
~/bin/slot cargo test -j4 -p calternal contract
~/bin/slot cargo test -j4 -p calternal-markdown-view
node apps/web/scripts/action-types.mjs --check

Results: tasks 56 passed; notes 497 passed with 6 existing ignored; all calternal suites passed with existing ignored tests; the explicit action contract passed; all 25 shared-view unit/integration tests passed, including the Rust corpus contract; doc tests passed. fmt, workspace clippy -D warnings and action-types check passed. Full log: ~/tasks-v2-b1-verified.log, ending B1_GATES_PASSED; systemd unit completed successfully. The expanded shared process-kill harness covers every forward and inverse byte boundary and every Home publication boundary, with repeated recovery. Existing crash/conflict/receipt regressions and all adapted B1 regressions passed. The saved property seed is retained.

Decisions/open risks: Q1–Q6 are unchanged and pending. Recurring outcome writes, Home undo, worker-routed inputs, source authority and metadata outside #813's grammar remain refused. In particular ordinary generated unquoted UUID/timestamp metadata requires explicit source correction before B1 can write it. No performance, Apple, power-loss or native recurring-outcome pass is claimed. #814 remains under review; this PR is ready for review, never merged.

Ports `tasks.set-status` and `tasks.set-status-many` to pure raw-byte plans submitted to the shared Home executor. One transaction groups status/completed property splices and owning checkbox characters, with exact inverse offsets. No action-specific write, Flush, recovery or undo implementation is retained from #801. Supersedes #801. Stack: #809 → #814 (`0f38d06f`), plus #813 (`11230729`) and the shared parsed view from #805 (`948117cc`). #814 remains under review. Q1–Q6 on #808 are still pending; this port uses the executor's conservative defaults. Never merge. Implementation: - The shared pulldown-cmark view now exposes original-byte checkbox spans and parsed owner destinations without changing the serialized editor contract. Code spans, fences and comments never supply checkbox mutations. - The pure planner validates the strict writer's complete input/output grammar, combines property and checkbox splices in original coordinates and verifies the exact inverse. Incoming links are indexed candidates; shared ownership checks and legacy owner expectations prevent a missing parsed owner from silently changing metadata alone. - The adapter bounds capture and submits changed notes plus unchanged read dependencies once. Shared admission checks captured room versions, the incoming inventory revision and strict metadata. Request fingerprints let retries recover the immutable recorded plan before fresh capture. Publication, history, placement and recovery remain executor-owned. - `notes.undo` reaches the executor's inverse path. #814 still refuses Home undo; responses expose `undo_available: false`. Recorded byte-executor inverses are tested where enabled. Supported scope and refusals: - Recurring writes refuse. #813 cannot write the normative singular map-list `log`, and #814 does not admit occurrence participants. No session-link log or guessed occurrence is written. - Unsupported metadata remains exact, including the legacy unquoted UUID/timestamps produced by ordinary note creation. Positive Home fixtures explicitly correct metadata in source first; ordinary generated metadata has a refusal regression. Existing generic property routes stay unchanged. - Notes outside the shared in-process routing budget, custom marks, unsupported indexed owners, ambiguous/fragment/encoded owner links and source authority without a shared adapter refuse the selection. An unrelated inventory update may conservatively refuse admission. Size/cost: the planner is about 260 production lines, with capture/submit separate. Planning is O(N + P log P + S log S), plus indexed incoming queries and per-note owner-range lookups; memory O(N + P + S). Existing executor caps and WAL/publication costs remain. No performance, power-loss, Apple or supported recurring-outcome pass is claimed. | failure | effect | detection | recovery | test | | --- | --- | --- | --- | --- | | unsupported metadata/parser/owner | no admission | strict writer/shared view | explicit correction | refusal corpus + positive controls | | stale participant/inventory | whole refusal | exact bytes, room version, inventory revision | explicit fresh attempt | single/many stale and shared admission probes | | crash after PREPARE | pending, no partial accepted generation | shared WAL/directional evidence | same recorded plan | every forward/inverse byte boundary and Home publication boundary, repeated restart | | changed post-image before inverse | whole inverse refused | exact bytes/ancestry | retain evidence | CRLF/BOM/duplicate-property regressions | | Home undo | refusal | shared inverse entrypoint | retain record; adapter remains gated | action-to-executor gate | Validation: all gates passed on dev-01 in `~/Developer/Worktrees/tasks-v2-set-status`, through `nix develop -c bash -c`, at `825c73c4`. Final head `e7e0831553b291ea96d748725c143fdb9e0248d7` only adds the regression seed already exercised in that passing VM run and updates documentation. ```sh cargo fmt --all --check ~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings ~/bin/slot cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal ~/bin/slot cargo test -j4 -p calternal contract ~/bin/slot cargo test -j4 -p calternal-markdown-view node apps/web/scripts/action-types.mjs --check ``` Results: tasks 56 passed; notes 497 passed with 6 existing ignored; all calternal suites passed with existing ignored tests; the explicit action contract passed; all 25 shared-view unit/integration tests passed, including the Rust corpus contract; doc tests passed. fmt, workspace clippy `-D warnings` and action-types check passed. Full log: `~/tasks-v2-b1-verified.log`, ending `B1_GATES_PASSED`; systemd unit completed successfully. The expanded shared process-kill harness covers every forward and inverse byte boundary and every Home publication boundary, with repeated recovery. Existing crash/conflict/receipt regressions and all adapted B1 regressions passed. The saved property seed is retained. Decisions/open risks: Q1–Q6 are unchanged and pending. Recurring outcome writes, Home undo, worker-routed inputs, source authority and metadata outside #813's grammar remain refused. In particular ordinary generated unquoted UUID/timestamp metadata requires explicit source correction before B1 can write it. No performance, Apple, power-loss or native recurring-outcome pass is claimed. #814 remains under review; this PR is ready for review, never merged.
kayg added 18 commits 2026-10-31 20:42:14 +00:00
docs: scope shared note-write executor byte protocol slice
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
0d951932b1
docs(tasks): record B1 port prerequisites and salvage manifest
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
baa02c65b3
Author
Owner

Implementation plan: merge #814 (on #809), #813 and the shared parsed view dependency #805. Add exact checkbox spans to that view; add strict metadata validation at Home executor admission. Implement a pure B1 planner and thin set-status adapters, grouped by note, with exact inverse splices. No action-specific placement, recovery or undo. Home undo remains gated by #814. Recurring operations refuse because #813 does not support normative map-list log values or occurrence participants. Keep Q1–Q6 conservative defaults. Costs and failure/gate matrix remain in docs/plans/tasks-v2-set-status.md; extend them with the new admission boundary. Target 150–300 planner lines plus a separate adapter and tests. Run independent range/inverse/refusal properties, salvaged regressions and the shared crash harness, then all requested VM gates. Never merge.

Implementation plan: merge #814 (on #809), #813 and the shared parsed view dependency #805. Add exact checkbox spans to that view; add strict metadata validation at Home executor admission. Implement a pure B1 planner and thin set-status adapters, grouped by note, with exact inverse splices. No action-specific placement, recovery or undo. Home undo remains gated by #814. Recurring operations refuse because #813 does not support normative map-list log values or occurrence participants. Keep Q1–Q6 conservative defaults. Costs and failure/gate matrix remain in docs/plans/tasks-v2-set-status.md; extend them with the new admission boundary. Target 150–300 planner lines plus a separate adapter and tests. Run independent range/inverse/refusal properties, salvaged regressions and the shared crash harness, then all requested VM gates. Never merge.
kayg changed title from WIP: Tasks v2 B1 prerequisite audit (blocked on shared integration) to WIP: Tasks v2 B1 status plans through the Home executor 2026-10-31 21:41:56 +00:00
kayg changed title from WIP: Tasks v2 B1 status plans through the Home executor to feat(tasks): port B1 status plans to the Home executor 2026-10-31 21:50:54 +00:00
Author
Owner

Independent review, round 1

Verdict: fix first. Reviewed head e7e0831553b291ea96d748725c143fdb9e0248d7. P0: none identified. P1: none identified.

P2: an unrelated URL checkbox refuses the selected task

crates/tasks/src/status.rs:159–179 rejects every checkbox destination containing :, # or % before determining whether that row owns a selected task. A daily note containing these independent rows refuses the entire action:

- [ ] read [site](https://example.org)

- [ ] selected
  - [task](<task.md>)

A standalone VM probe calling the actual planner returned Ok(2) without the first row and InvalidInput: unsupported owner binding with it. The unrelated web link is not a task owner. Determine relevance before applying owner restrictions, while continuing to refuse unsupported bindings that could own a selected task. Add the action-level positive regression and retain exact unrelated bytes.

P2: the salvaged encoding and duplicate-property probes no longer reproduce their original conditions

crates/tasks/src/status/tests.rs:161–168 appends each variant to daily.md, which has no frontmatter. Appending CRLF does not convert the file to CRLF; appending U+FEFF does not introduce a BOM; appending completed: later in body text does not recreate a frontmatter property that the inverse reinserts. All three currently prove only rejection of an arbitrary appended edit.

Retain those checks if useful, but also adapt the actual #801 regressions: convert the recorded post-image to CRLF, prepend a BOM, and run done-with-completed → todo, then recreate completed inside the task frontmatter before inverse admission. Assert whole-inverse refusal before PREPARE, unchanged task and owner files, and retained evidence. Home undo can remain gated; exercise the recorded inverse through the supported offline executor.

P2: B1 generated and crash coverage is not connected to B1 executor admission/recovery

The generated B1 cases in crates/tasks/src/status/tests.rs call status::plan and apply_splices; refusal cases compare immutable input maps. They do not execute generated task plans or inspect files, records or publication. The shared executor properties genuinely execute generic string-replacement plans, and its process-kill tests genuinely kill executor processes, but their fixtures do not consume B1 plans. The Home crash fixture also omits B1's newly added metadata, expected-room, inventory and request-fingerprint requirements. The old forward/inverse × unchanged/outside-CRLF matrix is therefore not replaced by the B1 coverage claimed here.

Connect generated B1 plans to the shared executor and verify independent expected files, exact recorded inverse identity and refusal side effects. Add B1-derived task/owner plans to the crash harness, including outside encoding changes and repeated recovery; cover the new Home requirements and recorded-plan retry at admission/publication boundaries. No task-specific recovery implementation is needed.

Architecture/parser assessment: the action contains capture/submit glue and a pure planner; I found no task-specific placement, Flush, recovery or undo implementation. Frontmatter edits use the strict planner and checkbox spans use the shared parsed view. The shared #805 vectors include multiline code, comments, frontmatter and mixed endings; B1 retains positive controls in its original CommonMark corpus. Recurring writes and Home undo remain explicitly refused. The known non-target UUID/timestamp writer issue is excluded from these findings.

Validation: on dev-01, nix develop -c bash -c '~/bin/slot cargo test -j4 -p calternal-tasks status -- --nocapture' passed 16 tests. VM checkout is 825c73c4; its difference from reviewed head is only the saved property seed and documentation. Independently inspected the existing full gate log ending B1_GATES_PASSED; that is prior implementation evidence, not a new full-suite run. The URL probe used the built task library, ran through Nix/slot, and removed its temporary files. No repository code edited or pushed. No P3 findings.

## Independent review, round 1 **Verdict: fix first.** Reviewed head `e7e0831553b291ea96d748725c143fdb9e0248d7`. P0: none identified. P1: none identified. ### P2: an unrelated URL checkbox refuses the selected task `crates/tasks/src/status.rs:159–179` rejects every checkbox destination containing `:`, `#` or `%` before determining whether that row owns a selected task. A daily note containing these independent rows refuses the entire action: ```md - [ ] read [site](https://example.org) - [ ] selected - [task](<task.md>) ``` A standalone VM probe calling the actual planner returned `Ok(2)` without the first row and `InvalidInput: unsupported owner binding` with it. The unrelated web link is not a task owner. Determine relevance before applying owner restrictions, while continuing to refuse unsupported bindings that could own a selected task. Add the action-level positive regression and retain exact unrelated bytes. ### P2: the salvaged encoding and duplicate-property probes no longer reproduce their original conditions `crates/tasks/src/status/tests.rs:161–168` appends each variant to `daily.md`, which has no frontmatter. Appending CRLF does not convert the file to CRLF; appending U+FEFF does not introduce a BOM; appending `completed: later` in body text does not recreate a frontmatter property that the inverse reinserts. All three currently prove only rejection of an arbitrary appended edit. Retain those checks if useful, but also adapt the actual #801 regressions: convert the recorded post-image to CRLF, prepend a BOM, and run done-with-completed → todo, then recreate `completed` inside the task frontmatter before inverse admission. Assert whole-inverse refusal before PREPARE, unchanged task and owner files, and retained evidence. Home undo can remain gated; exercise the recorded inverse through the supported offline executor. ### P2: B1 generated and crash coverage is not connected to B1 executor admission/recovery The generated B1 cases in `crates/tasks/src/status/tests.rs` call `status::plan` and `apply_splices`; refusal cases compare immutable input maps. They do not execute generated task plans or inspect files, records or publication. The shared executor properties genuinely execute generic string-replacement plans, and its process-kill tests genuinely kill executor processes, but their fixtures do not consume B1 plans. The Home crash fixture also omits B1's newly added metadata, expected-room, inventory and request-fingerprint requirements. The old forward/inverse × unchanged/outside-CRLF matrix is therefore not replaced by the B1 coverage claimed here. Connect generated B1 plans to the shared executor and verify independent expected files, exact recorded inverse identity and refusal side effects. Add B1-derived task/owner plans to the crash harness, including outside encoding changes and repeated recovery; cover the new Home requirements and recorded-plan retry at admission/publication boundaries. No task-specific recovery implementation is needed. Architecture/parser assessment: the action contains capture/submit glue and a pure planner; I found no task-specific placement, Flush, recovery or undo implementation. Frontmatter edits use the strict planner and checkbox spans use the shared parsed view. The shared #805 vectors include multiline code, comments, frontmatter and mixed endings; B1 retains positive controls in its original CommonMark corpus. Recurring writes and Home undo remain explicitly refused. The known non-target UUID/timestamp writer issue is excluded from these findings. Validation: on dev-01, `nix develop -c bash -c '~/bin/slot cargo test -j4 -p calternal-tasks status -- --nocapture'` passed 16 tests. VM checkout is `825c73c4`; its difference from reviewed head is only the saved property seed and documentation. Independently inspected the existing full gate log ending `B1_GATES_PASSED`; that is prior implementation evidence, not a new full-suite run. The URL probe used the built task library, ran through Nix/slot, and removed its temporary files. No repository code edited or pushed. No P3 findings.
Author
Owner

Updated head: a0d5592d1bf06c94a48e7cecbe4dbc3dc08d8cd0. Merged origin/feat/strict-frontmatter-writer (81c339725bb674710c4ed50ab982a196b355f11c) into this branch with merge commit 01dbcbd1. No merge into dev.

Ordinary generated note metadata no longer requires source correction before task status edits. Non-target UUIDs/timestamps and other structurally bounded plain scalar leaves/lists pass through byte-identically. Target types, exact inverses, independent byte audit and executor admission remain enforced. Positive Home fixtures now retain their original generated metadata. A new end-to-end test compares every non-target raw line after ticking a normal task; executor live-room/history/index coverage now explicitly requests metadata validation. Refusal coverage uses actual unsupported flow metadata and a commented post-image rather than treating ordinary UUID/timestamps as invalid. Existing stale-selection, recurring/custom-owner, recovery and undo gates remain. Documentation updated.

All gates passed on calternal-dev-01-compute02 in this branch’s existing VM worktree through /nix/var/nix/profiles/default/bin/nix develop -c bash -c. Every heavy command used the slot wrapper. Log: ~/tasks-b1-opaque-gates.log, ending B1_OPAQUE_GATES_PASSED; systemd unit exited 0.

cargo fmt --all
cargo fmt --all -- --check
~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings
~/bin/slot cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal
~/bin/slot cargo test -j4 -p calternal contract
~/bin/slot cargo test -j4 -p calternal-markdown-view
node apps/web/scripts/action-types.mjs --check

Results: tasks 57 passed; notes 500 passed / 6 existing ignored / 0 failed; all calternal suites passed with existing ignored cases; explicit action contract passed; all 25 markdown-view unit/integration tests and doctests passed. Fmt, workspace clippy -D warnings and action-types check passed. The tested formatting is committed; VM-only Nix scaffolding is excluded. The prior untracked property seed was preserved and matches the now-tracked seed. No build/test/install ran on the control host.

Decisions/open limits: target value types remain restricted, and all retained #781 structural/comment/envelope refusal cases run in the notes suite. Existing key/map/depth/size limits remain. Q1–Q6, recurring map-list writes, source authority, worker-routed inputs and Home undo remain as previously gated. No new independent review, performance, Apple or power-loss result is claimed. No repository settings changed.

Updated head: `a0d5592d1bf06c94a48e7cecbe4dbc3dc08d8cd0`. Merged `origin/feat/strict-frontmatter-writer` (`81c339725bb674710c4ed50ab982a196b355f11c`) into this branch with merge commit `01dbcbd1`. No merge into dev. Ordinary generated note metadata no longer requires source correction before task status edits. Non-target UUIDs/timestamps and other structurally bounded plain scalar leaves/lists pass through byte-identically. Target types, exact inverses, independent byte audit and executor admission remain enforced. Positive Home fixtures now retain their original generated metadata. A new end-to-end test compares every non-target raw line after ticking a normal task; executor live-room/history/index coverage now explicitly requests metadata validation. Refusal coverage uses actual unsupported flow metadata and a commented post-image rather than treating ordinary UUID/timestamps as invalid. Existing stale-selection, recurring/custom-owner, recovery and undo gates remain. Documentation updated. All gates passed on `calternal-dev-01-compute02` in this branch’s existing VM worktree through `/nix/var/nix/profiles/default/bin/nix develop -c bash -c`. Every heavy command used the slot wrapper. Log: `~/tasks-b1-opaque-gates.log`, ending `B1_OPAQUE_GATES_PASSED`; systemd unit exited 0. ```sh cargo fmt --all cargo fmt --all -- --check ~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings ~/bin/slot cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal ~/bin/slot cargo test -j4 -p calternal contract ~/bin/slot cargo test -j4 -p calternal-markdown-view node apps/web/scripts/action-types.mjs --check ``` Results: tasks 57 passed; notes 500 passed / 6 existing ignored / 0 failed; all calternal suites passed with existing ignored cases; explicit action contract passed; all 25 markdown-view unit/integration tests and doctests passed. Fmt, workspace clippy -D warnings and action-types check passed. The tested formatting is committed; VM-only Nix scaffolding is excluded. The prior untracked property seed was preserved and matches the now-tracked seed. No build/test/install ran on the control host. Decisions/open limits: target value types remain restricted, and all retained #781 structural/comment/envelope refusal cases run in the notes suite. Existing key/map/depth/size limits remain. Q1–Q6, recurring map-list writes, source authority, worker-routed inputs and Home undo remain as previously gated. No new independent review, performance, Apple or power-loss result is claimed. No repository settings changed.
Author
Owner

Round-1 P2 follow-up to #issuecomment-71843. Head a9304c4abb509625d15d38069cd65ec5df16b78d.

Item Status Change and regression evidence
Updated strict writer Merged 81c339725bb674710c4ed50ab982a196b355f11c is retained through merge 01dbcbd1. Ordinary non-target UUID/timestamp metadata passes through byte-identically; target restrictions and byte audit remain. Ordinary-note action and strict-writer regressions pass in the notes/tasks gates.
P2 unrelated URL checkbox refuses selection Fixed Determine selected-task relevance with the existing shared link reader before applying binding restrictions. No second destination decoder. unrelated_url_checkboxes_keep_exact_bytes_when_selected_task_changes exercises the actual action with unrelated URL/fragment/encoded URL rows and exact owner-note bytes; it failed on the previous implementation with unsupported owner binding. Selected fragment, encoded and self-fragment owner bindings still refuse in unsupported_bindings_that_could_own_selected_task_still_refuse.
P2 inverse probes lost their original conditions Fixed recorded_byte_executor_inverse_is_exact_and_changed_post_images_refuse converts the actual task post-image to CRLF, prepends a BOM, and separately plans done-with-completed → todo before recreating completed inside task frontmatter. Every refused inverse leaves both files, the complete record set and retained evidence unchanged, proving no inverse PREPARE. The unchanged inverse/idempotence control remains.
P2 B1 generated/crash coverage disconnected from executor Fixed Existing generated B1 cases now execute their actual plans against files through the shared byte executor, compare independently authored expected bytes, assert exact recorded plan/inverse identity and restore originals. Generated invalid-status actions inspect task/owner files, absence of a record and absence of transaction publication. B1-derived task/owner plans run all 30 byte boundaries × forward/inverse × unchanged/outside-CRLF (120 killed-child cases), with two recoveries each; outside bytes remain exact and records retain plans. Actual B1 actions run 14 Home admission/publication boundaries with two reopen/retry cycles, checking metadata/expected-room/inventory/request-fingerprint requirements, immutable recorded plans, exact inverse images, request mismatch refusal and one two-note journal batch. B1-derived admission tests separately refuse stale room/inventory and unsupported metadata before PREPARE with no file/record/publication side effects.

Only the owner relevance check changes action behavior. The shared link helper extracts existing reader logic. Cross-crate crash tests use the notes crate’s existing crash-points dev feature and shared executor pause boundaries; no task-specific recovery or undo implementation was added. Home fixtures settle participant rooms before taking a fresh admission snapshot, preserving the conservative inventory checks. The initial Home harness runs exposed startup inventory refusals; the settled-room fixture passes.

After the fixes and focused regression checks, the requested full gate set ran once on dev-01, in the existing VM worktree through /nix/var/nix/profiles/default/bin/nix develop -c bash -c. Log ~/tasks-b1-p2-gates.log ends B1_P2_GATES_PASSED; systemd unit exited 0:

cargo fmt --all
cargo fmt --all -- --check
~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings
~/bin/slot cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal
~/bin/slot cargo test -j4 -p calternal-markdown-view
~/bin/slot cargo test -j4 -p calternal contract
node apps/web/scripts/action-types.mjs --check

Passed: tasks 65; notes 500 with 6 existing ignored; all calternal suites with existing ignored cases; all 25 markdown-view unit/integration tests; explicit action contract; doctests; fmt; workspace clippy -D warnings; action-types. No gate failures in that full run. The tested formatting is committed and pushed; VM-only Nix scaffolding is excluded. No build/test/install ran on the control host.

Existing Q1–Q6, recurring map-list/source authority/worker-routing limits and Home undo gating remain unchanged. No new independent review or power-loss/performance result is claimed. No merge into dev and no repository settings changed.

Round-1 P2 follow-up to #issuecomment-71843. Head `a9304c4abb509625d15d38069cd65ec5df16b78d`. | Item | Status | Change and regression evidence | | --- | --- | --- | | Updated strict writer | Merged | `81c339725bb674710c4ed50ab982a196b355f11c` is retained through merge `01dbcbd1`. Ordinary non-target UUID/timestamp metadata passes through byte-identically; target restrictions and byte audit remain. Ordinary-note action and strict-writer regressions pass in the notes/tasks gates. | | P2 unrelated URL checkbox refuses selection | Fixed | Determine selected-task relevance with the existing shared link reader before applying binding restrictions. No second destination decoder. `unrelated_url_checkboxes_keep_exact_bytes_when_selected_task_changes` exercises the actual action with unrelated URL/fragment/encoded URL rows and exact owner-note bytes; it failed on the previous implementation with `unsupported owner binding`. Selected fragment, encoded and self-fragment owner bindings still refuse in `unsupported_bindings_that_could_own_selected_task_still_refuse`. | | P2 inverse probes lost their original conditions | Fixed | `recorded_byte_executor_inverse_is_exact_and_changed_post_images_refuse` converts the actual task post-image to CRLF, prepends a BOM, and separately plans done-with-completed → todo before recreating completed inside task frontmatter. Every refused inverse leaves both files, the complete record set and retained evidence unchanged, proving no inverse PREPARE. The unchanged inverse/idempotence control remains. | | P2 B1 generated/crash coverage disconnected from executor | Fixed | Existing generated B1 cases now execute their actual plans against files through the shared byte executor, compare independently authored expected bytes, assert exact recorded plan/inverse identity and restore originals. Generated invalid-status actions inspect task/owner files, absence of a record and absence of transaction publication. B1-derived task/owner plans run all 30 byte boundaries × forward/inverse × unchanged/outside-CRLF (120 killed-child cases), with two recoveries each; outside bytes remain exact and records retain plans. Actual B1 actions run 14 Home admission/publication boundaries with two reopen/retry cycles, checking metadata/expected-room/inventory/request-fingerprint requirements, immutable recorded plans, exact inverse images, request mismatch refusal and one two-note journal batch. B1-derived admission tests separately refuse stale room/inventory and unsupported metadata before PREPARE with no file/record/publication side effects. | Only the owner relevance check changes action behavior. The shared link helper extracts existing reader logic. Cross-crate crash tests use the notes crate’s existing `crash-points` dev feature and shared executor pause boundaries; no task-specific recovery or undo implementation was added. Home fixtures settle participant rooms before taking a fresh admission snapshot, preserving the conservative inventory checks. The initial Home harness runs exposed startup inventory refusals; the settled-room fixture passes. After the fixes and focused regression checks, the requested full gate set ran once on dev-01, in the existing VM worktree through `/nix/var/nix/profiles/default/bin/nix develop -c bash -c`. Log `~/tasks-b1-p2-gates.log` ends `B1_P2_GATES_PASSED`; systemd unit exited 0: ```sh cargo fmt --all cargo fmt --all -- --check ~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings ~/bin/slot cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal ~/bin/slot cargo test -j4 -p calternal-markdown-view ~/bin/slot cargo test -j4 -p calternal contract node apps/web/scripts/action-types.mjs --check ``` Passed: tasks 65; notes 500 with 6 existing ignored; all calternal suites with existing ignored cases; all 25 markdown-view unit/integration tests; explicit action contract; doctests; fmt; workspace clippy -D warnings; action-types. No gate failures in that full run. The tested formatting is committed and pushed; VM-only Nix scaffolding is excluded. No build/test/install ran on the control host. Existing Q1–Q6, recurring map-list/source authority/worker-routing limits and Home undo gating remain unchanged. No new independent review or power-loss/performance result is claimed. No merge into dev and no repository settings changed.
Author
Owner

Independent review, round 2

verdict: ready for scoped B1 at a9304c4abb509625d15d38069cd65ec5df16b78d. New P0–P3 findings: none identified. Reviewed round-1 #issuecomment-71843 and fix status #issuecomment-71912. No code pushed or merged.

round-1 item round-2 status / evidence
P2 unrelated URL checkbox refuses selection Verified fixed. Relevance now uses the shared link resolver before owner restrictions. The actual-action regression passes and compares exact unrelated URL/fragment/encoded-URL rows. Selected fragment, encoded and self-fragment bindings retain refusal coverage.
P2 inverse tests lost original conditions Verified fixed. The test converts the actual task post-image to CRLF, prepends a BOM, and separately executes done-with-completed → todo before recreating completed inside frontmatter. Each inverse refuses with both files, complete records and retained evidence unchanged. The exact inverse/idempotence control passes.
P2 generated/crash coverage disconnected from B1 executor Verified fixed. Generated B1 plans execute against files with independently authored expected images, recorded plan/inverse identity and restoration checks. Generated invalid-status actions inspect file/record/publication side effects. The B1-derived byte matrix passes all 30 boundaries × forward/inverse × unchanged/outside-CRLF, with two recoveries per case. Actual B1 Home actions pass 14 admission/publication boundaries with two reopen/retry cycles, immutable recorded requirements/plans, request mismatch refusal and one two-note journal batch. Stale room/inventory and unsupported metadata refuse before PREPARE.
updated strict-writer dependency Verified 81c33972 is included; its round-2 scalar/list, byte-preservation and refusal probes pass independently. Ordinary generated metadata action regression passes.

Fresh validation on dev-01 in ~/Developer/Worktrees/tasks-v2-set-status, with HEAD confirmed as a9304c4abb509625d15d38069cd65ec5df16b78d:

export PATH=/nix/var/nix/profiles/default/bin:$PATH
nix develop -c bash -c '~/bin/slot cargo test --locked -p calternal-tasks status -j4 -- --nocapture'

25 passed / 0 failed / 40 filtered out, including the generated execution/refusal tests, byte/Home crash matrices, URL action regression and encoding/duplicate-property inverse checks. Log: ~/review-812-r2.log. Inspected the earlier full gate log ending B1_P2_GATES_PASSED; that is implementation evidence, not a new full-suite/clippy run. No build/test/install ran on the control host.

No task-specific writer, recovery or undo implementation was introduced by these fixes. Recurring map-list writes, source authority, isolated-parser routing, Q1–Q6 and Home undo remain explicitly gated; ready does not enable those capabilities or authorize a merge.

## Independent review, round 2 **verdict: ready** for scoped B1 at `a9304c4abb509625d15d38069cd65ec5df16b78d`. New P0–P3 findings: none identified. Reviewed round-1 #issuecomment-71843 and fix status #issuecomment-71912. No code pushed or merged. | round-1 item | round-2 status / evidence | | --- | --- | | P2 unrelated URL checkbox refuses selection | Verified fixed. Relevance now uses the shared link resolver before owner restrictions. The actual-action regression passes and compares exact unrelated URL/fragment/encoded-URL rows. Selected fragment, encoded and self-fragment bindings retain refusal coverage. | | P2 inverse tests lost original conditions | Verified fixed. The test converts the actual task post-image to CRLF, prepends a BOM, and separately executes done-with-completed → todo before recreating `completed` inside frontmatter. Each inverse refuses with both files, complete records and retained evidence unchanged. The exact inverse/idempotence control passes. | | P2 generated/crash coverage disconnected from B1 executor | Verified fixed. Generated B1 plans execute against files with independently authored expected images, recorded plan/inverse identity and restoration checks. Generated invalid-status actions inspect file/record/publication side effects. The B1-derived byte matrix passes all 30 boundaries × forward/inverse × unchanged/outside-CRLF, with two recoveries per case. Actual B1 Home actions pass 14 admission/publication boundaries with two reopen/retry cycles, immutable recorded requirements/plans, request mismatch refusal and one two-note journal batch. Stale room/inventory and unsupported metadata refuse before PREPARE. | | updated strict-writer dependency | Verified `81c33972` is included; its round-2 scalar/list, byte-preservation and refusal probes pass independently. Ordinary generated metadata action regression passes. | Fresh validation on dev-01 in `~/Developer/Worktrees/tasks-v2-set-status`, with HEAD confirmed as `a9304c4abb509625d15d38069cd65ec5df16b78d`: ```sh export PATH=/nix/var/nix/profiles/default/bin:$PATH nix develop -c bash -c '~/bin/slot cargo test --locked -p calternal-tasks status -j4 -- --nocapture' ``` 25 passed / 0 failed / 40 filtered out, including the generated execution/refusal tests, byte/Home crash matrices, URL action regression and encoding/duplicate-property inverse checks. Log: `~/review-812-r2.log`. Inspected the earlier full gate log ending `B1_P2_GATES_PASSED`; that is implementation evidence, not a new full-suite/clippy run. No build/test/install ran on the control host. No task-specific writer, recovery or undo implementation was introduced by these fixes. Recurring map-list writes, source authority, isolated-parser routing, Q1–Q6 and Home undo remain explicitly gated; ready does not enable those capabilities or authorize a merge.
Author
Owner

Round-2 integration status — head 56451a2c47d79dc2b241862e25ef3067dcf2a13e.

Merged final #814 head 2e08de7481bf8e8bea5cf1feeca18e8d9285642f into this branch. Accepted source readers still pin generation::Snapshot; B1 writes continue through the Home executor admission path. recorded_note_write reads atomically replaced journal records without jobs or the exclusive DataLock. The new recorded_plan_lookup_does_not_take_executor_writer_lock regression reproduced WouldBlock before the fix and passes while the writer lock is held. Unchanged participants remain executor read dependencies; Home undo remains refused by the executor boundary.

All requested gates passed on dev-01 through Nix:

  • cargo fmt --all and cargo fmt --all --check
  • ~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings
  • ~/bin/slot cargo test -j4 -p calternal-notes -p calternal-tasks -p calternal -p calternal-store -p calternal-search
  • ~/bin/slot cargo test -j4 -p calternal-markdown-view
  • ~/bin/slot cargo test -j4 -p calternal contract (1 passed)
  • node apps/web/scripts/action-types.mjs --check

The focused writer-lock regression passed (1 passed). No Playwright run was started.

Round-2 integration status — head `56451a2c47d79dc2b241862e25ef3067dcf2a13e`. Merged final #814 head `2e08de7481bf8e8bea5cf1feeca18e8d9285642f` into this branch. Accepted source readers still pin `generation::Snapshot`; B1 writes continue through the Home executor admission path. `recorded_note_write` reads atomically replaced journal records without `jobs` or the exclusive `DataLock`. The new `recorded_plan_lookup_does_not_take_executor_writer_lock` regression reproduced `WouldBlock` before the fix and passes while the writer lock is held. Unchanged participants remain executor read dependencies; Home undo remains refused by the executor boundary. All requested gates passed on dev-01 through Nix: - `cargo fmt --all` and `cargo fmt --all --check` - `~/bin/slot cargo clippy --workspace --all-targets -j4 -- -D warnings` - `~/bin/slot cargo test -j4 -p calternal-notes -p calternal-tasks -p calternal -p calternal-store -p calternal-search` - `~/bin/slot cargo test -j4 -p calternal-markdown-view` - `~/bin/slot cargo test -j4 -p calternal contract` (1 passed) - `node apps/web/scripts/action-types.mjs --check` The focused writer-lock regression passed (1 passed). No Playwright run was started.
Author
Owner

Independent review: snapshot adaptation

verdict: ready for the scoped B1 adaptation at 56451a2c47d79dc2b241862e25ef3067dcf2a13e. P0: none identified. P1: none identified. P2: none identified. P3: none identified.

Reviewed a9304c4a..56451a2c, subtracting the changes in 0f38d06f..2e08de74 belonging to #814. This is an adaptation review, not a fresh approval of all dependency code.

  • Reader admission: recorded-plan lookup now reads atomically replaced, validated journal records in spawn_blocking, without jobs, executor_generation, or the exclusive DataLock. It holds no reader lock across an await. Returning a retained plan still leads through execute_note_write, writer admission/recovery and the durable directory barrier. Request/author matching remains enforced.
  • Snapshot lifetime/retries: source pins retain tokens rather than writer exclusion; old active generations are capped at four and revoked before row reclamation. B1 itself does not consume a source Snapshot: capture and response versions use the live-room Notes::get path. There is no new B1 stale-snapshot propagation or retry loop. The shared search consumer reacquires snapshots after failed staging with a quiet delay. The probe below verifies expiry and a successful fresh read, and bounds action retries rather than concealing stale-selection refusals.
  • B1 semantics: unchanged participants still become ReadDependency entries and receive actor leases plus expected-room checks. Exact pre-images, room revisions and inventory admission remain in place. The planner and its inverse-splice calculation are unchanged. Existing exact-inverse/changed-post-image regressions pass; Home undo remains explicitly gated.

Fresh dev-01 evidence, isolated uncommitted worktree ~/Developer/Worktrees/review-812-snapshot at the reviewed head:

export PATH=/nix/var/nix/profiles/default/bin:$PATH
export CARGO_TARGET_DIR=/tmp/review-812-snapshot-target
nix develop -c bash -c '~/bin/slot cargo test --locked -p calternal-tasks review_snapshot_task_concurrency -j4 -- --nocapture'
nix develop -c bash -c '~/bin/slot cargo test --locked -p calternal-tasks status -j4 -- --nocapture && ~/bin/slot cargo test --locked -p calternal-notes recorded_plan_lookup_does_not_take_executor_writer_lock -j4 -- --nocapture'

The new status_action::executor_tests::review_snapshot_task_concurrency probe passed independently and in the status run. It races actual tasks.set-status actions against append edits to the same note while retaining successive source snapshots. Across 16 rounds, all 16 initial racing status admissions refused, bounded fresh retries succeeded, every append marker survived exactly once in live and on-disk text, deliberately stale task versions refused without changes, the oldest source pin expired with NotSavedYet, and a fresh snapshot read succeeded. A 45-second outer deadline detects stalls; the independent run finished in 2.26 seconds. This sampled schedule does not claim exhaustive interleaving coverage.

Status regressions: 26 passed, 0 failed, including the added probe, exact inverse/refusal checks and existing byte/Home crash matrices. Writer-lock lookup regression: 1 passed, 0 failed. Logs: ~/review-812-snapshot-probe.log and ~/review-812-snapshot-gates.log. Probe source remains in the VM worktree, uncommitted. Root storage was tight, so build artifacts used memory-backed /tmp; the review's temporary target was removed afterward. No control-host build/test/install, push, merge or settings change. Existing B1 capability gates remain unchanged.

## Independent review: snapshot adaptation **verdict: ready for the scoped B1 adaptation at `56451a2c47d79dc2b241862e25ef3067dcf2a13e`.** P0: none identified. P1: none identified. P2: none identified. P3: none identified. Reviewed `a9304c4a..56451a2c`, subtracting the changes in `0f38d06f..2e08de74` belonging to #814. This is an adaptation review, not a fresh approval of all dependency code. - Reader admission: recorded-plan lookup now reads atomically replaced, validated journal records in `spawn_blocking`, without `jobs`, `executor_generation`, or the exclusive DataLock. It holds no reader lock across an await. Returning a retained plan still leads through `execute_note_write`, writer admission/recovery and the durable directory barrier. Request/author matching remains enforced. - Snapshot lifetime/retries: source pins retain tokens rather than writer exclusion; old active generations are capped at four and revoked before row reclamation. B1 itself does not consume a source Snapshot: capture and response versions use the live-room `Notes::get` path. There is no new B1 stale-snapshot propagation or retry loop. The shared search consumer reacquires snapshots after failed staging with a quiet delay. The probe below verifies expiry and a successful fresh read, and bounds action retries rather than concealing stale-selection refusals. - B1 semantics: unchanged participants still become `ReadDependency` entries and receive actor leases plus expected-room checks. Exact pre-images, room revisions and inventory admission remain in place. The planner and its inverse-splice calculation are unchanged. Existing exact-inverse/changed-post-image regressions pass; Home undo remains explicitly gated. Fresh dev-01 evidence, isolated **uncommitted** worktree `~/Developer/Worktrees/review-812-snapshot` at the reviewed head: ```sh export PATH=/nix/var/nix/profiles/default/bin:$PATH export CARGO_TARGET_DIR=/tmp/review-812-snapshot-target nix develop -c bash -c '~/bin/slot cargo test --locked -p calternal-tasks review_snapshot_task_concurrency -j4 -- --nocapture' nix develop -c bash -c '~/bin/slot cargo test --locked -p calternal-tasks status -j4 -- --nocapture && ~/bin/slot cargo test --locked -p calternal-notes recorded_plan_lookup_does_not_take_executor_writer_lock -j4 -- --nocapture' ``` The new `status_action::executor_tests::review_snapshot_task_concurrency` probe passed independently and in the status run. It races actual `tasks.set-status` actions against append edits to the same note while retaining successive source snapshots. Across 16 rounds, all 16 initial racing status admissions refused, bounded fresh retries succeeded, every append marker survived exactly once in live and on-disk text, deliberately stale task versions refused without changes, the oldest source pin expired with `NotSavedYet`, and a fresh snapshot read succeeded. A 45-second outer deadline detects stalls; the independent run finished in 2.26 seconds. This sampled schedule does not claim exhaustive interleaving coverage. Status regressions: **26 passed, 0 failed**, including the added probe, exact inverse/refusal checks and existing byte/Home crash matrices. Writer-lock lookup regression: **1 passed, 0 failed**. Logs: `~/review-812-snapshot-probe.log` and `~/review-812-snapshot-gates.log`. Probe source remains in the VM worktree, uncommitted. Root storage was tight, so build artifacts used memory-backed `/tmp`; the review's temporary target was removed afterward. No control-host build/test/install, push, merge or settings change. Existing B1 capability gates remain unchanged.
Author
Owner

ADR 0003 evidence migration: docs/plans/tasks-v2-set-status.md

Source commit: d2362e5c9afee81bedc7c85da7c36fb2f46b5320; snapshot from dev 55f35fcd. Full original source preserved below before repository removal/stripping. Design, code and test inputs are retained where applicable.

# Tasks writes v2: B1 status port

Status: implemented for strict-writer-supported, nonrecurring task notes; all
requested VM gates passed. Evidence and exact commands: [#812](https://git.kayg.org/kayg/calternal/pulls/812).
Supersedes #801 without retaining its write machinery.
Stack: #809 → #814 (`0f38d06f`) plus #813 (`81c33972`) and the shared parsed
view from #805 (`948117cc`). Q1–Q6 remain pending; conservative defaults apply.
Never merge.

## Implementation and limits

`tasks::status::plan` takes immutable raw notes, requested task paths/states,
an actual offset completion time and indexed owner expectations. It returns one
exact forward/inverse splice set per distinct note or a whole-plan refusal.
Status/completed leaves use the strict frontmatter planner; checkbox characters
come from the shared pulldown-cmark view. No local task/YAML parser or writer.
Changed status/timestamps and boxes compose in original-byte coordinates; inverse
offsets account for unequal property lengths. Other bytes remain exact.

The adapter bounds source/owner counts and raw capture, checks task versions,
captures general incoming-link candidates plus legacy task-owner expectations,
and submits a single Home transaction. Shared admission pins room versions and
the incoming inventory connection revision under its metadata barrier. Input and
output metadata are strictly validated at admission. Request fingerprints allow
retries to load the immutable recorded plan before any fresh capture. Placement,
history, publication, crash recovery and inverse execution remain executor-owned.
No action calls Edit/Flush/save or creates a task-specific undo/recovery job.

Home undo is wired from `notes.undo` to the executor's inverse entrypoint, which
still refuses Home payloads under #814. Responses state `undo_available: false`.
Offline executor tests exercise the recorded inverse where enabled.

Recurring writes refuse: #813 supports scalar lists, not the normative singular
map-list `log`, and #814 refuses occurrence participants. No session-link log or
invented completion/occurrence fallback. Source-connected/occurrence-managed notes
also refuse until their authority adapters exist. The shared writer passes through
ordinary unquoted UUIDs, timestamps and other structurally bounded plain scalars
in non-target keys byte-identically. Target value types remain restricted; flow
metadata, comments and map lists still refuse. Existing property routes are
unchanged. Positive Home tests use ordinary generated metadata without source
correction and independently compare every non-target line. Unsupported metadata
still has an explicit refusal regression, including executor admission.
Notes outside the shared in-process parser routing budget refuse until its worker
is integrated. Unsupported indexed owning lines, custom marks and ambiguous or
fragment/encoded owner links refuse the selection. No policy answer is inferred.

Production size: planner about 260 lines; capture/submit adapter separate. For N
participant bytes, P parsed nodes/edges and S splices, planning is O(N + P log P +
S log S), plus indexed incoming-link queries; memory O(N + P + S). Home's existing
WAL/publication costs and caps still apply. Whole-inventory revision checks are
conservative and may refuse after an unrelated index update. No performance,
Apple, power-loss or supported recurring outcome pass is claimed.

| failure | effect | detection | recovery | gate |
| --- | --- | --- | --- | --- |
| unsupported metadata/parser/owner | no admission | strict writer/shared view | explicit source correction | refusal corpus + positive controls |
| stale task, source or incoming inventory | whole refusal | captured versions/raw bytes/inventory revision | explicit new attempt | single/many stale + shared admission tests |
| crash after PREPARE | pending, no partial accepted generation | shared WAL/directional evidence | same recorded plan | expanded shared process-kill matrix, two restarts |
| changed inverse post-image | whole inverse refused | executor exact bytes and ancestry | preserve outside bytes and inverse | CRLF/BOM/duplicate-property probes |
| Home undo request | refusal | shared inverse entrypoint | retain record; Home adapter remains gated | action-to-executor undo gate |

## Original prerequisite audit and salvage manifest

The following records the original audit at `baa02c65` for traceability. Its
missing-dependency observations describe that base, not the current stack.

## Intended implementation

One pure planner in `calternal-tasks`: current immutable note bytes plus request
produce exact forward/inverse byte splices or a refusal. Submit all distinct
notes in one transaction to the shared Home executor. Reuse the shared parsed
view and strict frontmatter writer. Never salvage CheckedEdit, Flush, recovery
or undo code from B1. Target 150–300 production lines, tests separate.
For B affected bytes, P parsed rows and S splices: O(B + P + S log S) planning,
O(B + output bytes + S) inverse validation, O(B + output bytes + P + S) memory.

## Missing dependencies at the requested base

- `docs/implementation/note-write-executor.md` explicitly describes #809 as an
  offline byte-protocol slice and says later ports remain blocked on semantic
  writer/parser integration, room publication and applicable platform gates.
- `write_executor/plan.rs::Requirement` includes `RoomRevision`,
  `BindingGeneration`, `Occurrence`, `Publication` and `MetadataValidation`.
  `policy.rs::refuse_unsupported_participants` refuses all nonempty lists.
  Omitting required participants would falsely claim integrated completion.
- `NoteWriteExecutor::open` requires room/namespace writers to be quiescent.
  There is no production Home owner, room admission adapter or publication
  barrier. An action cannot open a second executor beside active note rooms.
- The base has no `calternal-markdown-view`. Calendar slice 2 at `331647ec`
  (`feat/calendar-v2-s2-parser-contract`) has the shared pulldown-cmark 0.13.4
  extraction candidate and contracts, explicitly unconnected. It does not
  deliver the strict input/output-validated frontmatter splice writer.
- The existing `notes::props` is a lenient reader/UTF-16 room-edit writer.
  `New` supports text, text lists and booleans, not normative outcome-map
  singular `log`. It is not the planned strict byte-splice writer. A task-only
  guard/scanner would violate the plan's prohibition on replacement writers.

The plan's executor-first and proof-before-porting gates are therefore not
satisfied for integrated B1. Keep Q1–Q6 unchanged. Recurring writes must refuse
until the shared map-list extension is proven; never revive session-link logs.
Do not cherry-pick the cumulative B1 stack. Deliver shared prerequisites before
wiring the action; the byte executor review alone does not establish them.

## Salvage manifest

Sources below are at #801 `ac9bceb1`. Adapt assertions/callers to pure plans and
the shared executor, retaining independent expected bytes rather than old APIs.

| Source | Preserve / adapt |
| --- | --- |
| `crates/tasks/src/status.rs::Status` | todo/someday → space, doing → slash, done → x, cancelled → dash; custom marks refuse |
| `crates/tasks/src/tests.rs::set_status_changes_only_checkbox_marks_and_undo_restores_exact_bytes` | exact raw-byte forward/inverse oracle |
| `status_updates_only_commonmark_task_lines_in_the_corpus` | no planned boxes in code spans, multiline code, fences or HTML/comments; positive controls |
| `status_to_checkbox_mapping_matches_the_shared_status_names` | all five mapping vectors |
| `set_status_refuses_a_stale_task_version`, `set_status_many_refuses_all_changes_when_one_version_is_stale` | entire action refused, no journal/publication changes |
| `set_status_many_is_one_undoable_job`, `status_many_preserves_checkbox_offsets_after_property_insertion` | one multi-note transaction, one image per note; shifted inverse offsets |
| `status_refuses_custom_owning_checkbox_marks_without_writes`, `status_rejects_unusual_frontmatter_without_changing_any_bytes` | shared-writer refusal corpus with unchanged files/history |
| `recurring_tick_records_and_untick_removes_the_session_link`, `recurring_untick_requires_the_session_line`, `crash_replay_does_not_duplicate_a_recurring_session_link` | occurrence deduplication/untick/master-open invariants; replace obsolete link-list expectations with normative maps or unsupported refusal |
| `crates/notes/src/room/save/tests.rs::review801_exact_patch_late_outside_write` | change status/encoding at executor placement; preserve outside bytes/evidence |
| `review801_undo_encoding_guard`, `review801_undo_duplicate_property` | changed post-image refuses whole inverse before PREPARE; no duplicate completed |
| `checked_images_crash_and_replay_matrix` | 16 cases: four boundaries × forward/undo × unchanged/outside CRLF; extend to every shared journal/fsync/staging/commit boundary |
| `checked_receipt_replay_refuses_changed_post_image` | receipts never authorize replaying changed bytes; distinguish pending recovery from committed receipt retry |

## Failure and gate matrix

| Failure | Effect | Detection | Recovery | Gate |
| --- | --- | --- | --- | --- |
| missing writer/view/Home adapter | no action port | dependency audit | shared prerequisites first | no fallback or omitted requirements |
| unsupported metadata/log/custom mark | pure refusal | shared input/output validation | source editing, no journal | refusal writes nothing; positive controls |
| stale participant | whole refusal | full pre-image/revision/binding admission | explicit fresh plan | all B1 stale/late-write probes |
| crash after PREPARE | pending | shared WAL/directional evidence | recorded plan only | process exit at every harness boundary; restart twice |
| edit before undo | whole inverse refused | exact committed post-image | retain inverse/outside bytes | encoding/duplicate-property probes |

Before delivery, independently generated properties must prove allowed-range
confinement, refused plans write nothing, and undo composed with do is raw-byte
identity. Run all salvaged regressions and shared executor crash boundaries.

Implementation gates, on a VM through Nix and slot for heavy commands:
`cargo fmt --all --check`;
`cargo clippy --workspace --all-targets -j4 -- -D warnings`;
`cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal`;
`cargo test -j4 -p calternal contract`;
`node apps/web/scripts/action-types.mjs --check`.
Not run for this documentation-only audit. Local gate: `git diff --check`.
Never merge. No B1 completion or runtime pass is claimed.

ADR 0003 evidence migration: `docs/plans/tasks-v2-set-status.md` Source commit: [d2362e5c9afee81bedc7c85da7c36fb2f46b5320](https://git.kayg.org/kayg/calternal/commit/d2362e5c9afee81bedc7c85da7c36fb2f46b5320); snapshot from dev `55f35fcd`. Full original source preserved below before repository removal/stripping. Design, code and test inputs are retained where applicable. ```text # Tasks writes v2: B1 status port Status: implemented for strict-writer-supported, nonrecurring task notes; all requested VM gates passed. Evidence and exact commands: [#812](https://git.kayg.org/kayg/calternal/pulls/812). Supersedes #801 without retaining its write machinery. Stack: #809 → #814 (`0f38d06f`) plus #813 (`81c33972`) and the shared parsed view from #805 (`948117cc`). Q1–Q6 remain pending; conservative defaults apply. Never merge. ## Implementation and limits `tasks::status::plan` takes immutable raw notes, requested task paths/states, an actual offset completion time and indexed owner expectations. It returns one exact forward/inverse splice set per distinct note or a whole-plan refusal. Status/completed leaves use the strict frontmatter planner; checkbox characters come from the shared pulldown-cmark view. No local task/YAML parser or writer. Changed status/timestamps and boxes compose in original-byte coordinates; inverse offsets account for unequal property lengths. Other bytes remain exact. The adapter bounds source/owner counts and raw capture, checks task versions, captures general incoming-link candidates plus legacy task-owner expectations, and submits a single Home transaction. Shared admission pins room versions and the incoming inventory connection revision under its metadata barrier. Input and output metadata are strictly validated at admission. Request fingerprints allow retries to load the immutable recorded plan before any fresh capture. Placement, history, publication, crash recovery and inverse execution remain executor-owned. No action calls Edit/Flush/save or creates a task-specific undo/recovery job. Home undo is wired from `notes.undo` to the executor's inverse entrypoint, which still refuses Home payloads under #814. Responses state `undo_available: false`. Offline executor tests exercise the recorded inverse where enabled. Recurring writes refuse: #813 supports scalar lists, not the normative singular map-list `log`, and #814 refuses occurrence participants. No session-link log or invented completion/occurrence fallback. Source-connected/occurrence-managed notes also refuse until their authority adapters exist. The shared writer passes through ordinary unquoted UUIDs, timestamps and other structurally bounded plain scalars in non-target keys byte-identically. Target value types remain restricted; flow metadata, comments and map lists still refuse. Existing property routes are unchanged. Positive Home tests use ordinary generated metadata without source correction and independently compare every non-target line. Unsupported metadata still has an explicit refusal regression, including executor admission. Notes outside the shared in-process parser routing budget refuse until its worker is integrated. Unsupported indexed owning lines, custom marks and ambiguous or fragment/encoded owner links refuse the selection. No policy answer is inferred. Production size: planner about 260 lines; capture/submit adapter separate. For N participant bytes, P parsed nodes/edges and S splices, planning is O(N + P log P + S log S), plus indexed incoming-link queries; memory O(N + P + S). Home's existing WAL/publication costs and caps still apply. Whole-inventory revision checks are conservative and may refuse after an unrelated index update. No performance, Apple, power-loss or supported recurring outcome pass is claimed. | failure | effect | detection | recovery | gate | | --- | --- | --- | --- | --- | | unsupported metadata/parser/owner | no admission | strict writer/shared view | explicit source correction | refusal corpus + positive controls | | stale task, source or incoming inventory | whole refusal | captured versions/raw bytes/inventory revision | explicit new attempt | single/many stale + shared admission tests | | crash after PREPARE | pending, no partial accepted generation | shared WAL/directional evidence | same recorded plan | expanded shared process-kill matrix, two restarts | | changed inverse post-image | whole inverse refused | executor exact bytes and ancestry | preserve outside bytes and inverse | CRLF/BOM/duplicate-property probes | | Home undo request | refusal | shared inverse entrypoint | retain record; Home adapter remains gated | action-to-executor undo gate | ## Original prerequisite audit and salvage manifest The following records the original audit at `baa02c65` for traceability. Its missing-dependency observations describe that base, not the current stack. ## Intended implementation One pure planner in `calternal-tasks`: current immutable note bytes plus request produce exact forward/inverse byte splices or a refusal. Submit all distinct notes in one transaction to the shared Home executor. Reuse the shared parsed view and strict frontmatter writer. Never salvage CheckedEdit, Flush, recovery or undo code from B1. Target 150–300 production lines, tests separate. For B affected bytes, P parsed rows and S splices: O(B + P + S log S) planning, O(B + output bytes + S) inverse validation, O(B + output bytes + P + S) memory. ## Missing dependencies at the requested base - `docs/implementation/note-write-executor.md` explicitly describes #809 as an offline byte-protocol slice and says later ports remain blocked on semantic writer/parser integration, room publication and applicable platform gates. - `write_executor/plan.rs::Requirement` includes `RoomRevision`, `BindingGeneration`, `Occurrence`, `Publication` and `MetadataValidation`. `policy.rs::refuse_unsupported_participants` refuses all nonempty lists. Omitting required participants would falsely claim integrated completion. - `NoteWriteExecutor::open` requires room/namespace writers to be quiescent. There is no production Home owner, room admission adapter or publication barrier. An action cannot open a second executor beside active note rooms. - The base has no `calternal-markdown-view`. Calendar slice 2 at `331647ec` (`feat/calendar-v2-s2-parser-contract`) has the shared pulldown-cmark 0.13.4 extraction candidate and contracts, explicitly unconnected. It does not deliver the strict input/output-validated frontmatter splice writer. - The existing `notes::props` is a lenient reader/UTF-16 room-edit writer. `New` supports text, text lists and booleans, not normative outcome-map singular `log`. It is not the planned strict byte-splice writer. A task-only guard/scanner would violate the plan's prohibition on replacement writers. The plan's executor-first and proof-before-porting gates are therefore not satisfied for integrated B1. Keep Q1–Q6 unchanged. Recurring writes must refuse until the shared map-list extension is proven; never revive session-link logs. Do not cherry-pick the cumulative B1 stack. Deliver shared prerequisites before wiring the action; the byte executor review alone does not establish them. ## Salvage manifest Sources below are at #801 `ac9bceb1`. Adapt assertions/callers to pure plans and the shared executor, retaining independent expected bytes rather than old APIs. | Source | Preserve / adapt | | --- | --- | | `crates/tasks/src/status.rs::Status` | todo/someday → space, doing → slash, done → x, cancelled → dash; custom marks refuse | | `crates/tasks/src/tests.rs::set_status_changes_only_checkbox_marks_and_undo_restores_exact_bytes` | exact raw-byte forward/inverse oracle | | `status_updates_only_commonmark_task_lines_in_the_corpus` | no planned boxes in code spans, multiline code, fences or HTML/comments; positive controls | | `status_to_checkbox_mapping_matches_the_shared_status_names` | all five mapping vectors | | `set_status_refuses_a_stale_task_version`, `set_status_many_refuses_all_changes_when_one_version_is_stale` | entire action refused, no journal/publication changes | | `set_status_many_is_one_undoable_job`, `status_many_preserves_checkbox_offsets_after_property_insertion` | one multi-note transaction, one image per note; shifted inverse offsets | | `status_refuses_custom_owning_checkbox_marks_without_writes`, `status_rejects_unusual_frontmatter_without_changing_any_bytes` | shared-writer refusal corpus with unchanged files/history | | `recurring_tick_records_and_untick_removes_the_session_link`, `recurring_untick_requires_the_session_line`, `crash_replay_does_not_duplicate_a_recurring_session_link` | occurrence deduplication/untick/master-open invariants; replace obsolete link-list expectations with normative maps or unsupported refusal | | `crates/notes/src/room/save/tests.rs::review801_exact_patch_late_outside_write` | change status/encoding at executor placement; preserve outside bytes/evidence | | `review801_undo_encoding_guard`, `review801_undo_duplicate_property` | changed post-image refuses whole inverse before PREPARE; no duplicate completed | | `checked_images_crash_and_replay_matrix` | 16 cases: four boundaries × forward/undo × unchanged/outside CRLF; extend to every shared journal/fsync/staging/commit boundary | | `checked_receipt_replay_refuses_changed_post_image` | receipts never authorize replaying changed bytes; distinguish pending recovery from committed receipt retry | ## Failure and gate matrix | Failure | Effect | Detection | Recovery | Gate | | --- | --- | --- | --- | --- | | missing writer/view/Home adapter | no action port | dependency audit | shared prerequisites first | no fallback or omitted requirements | | unsupported metadata/log/custom mark | pure refusal | shared input/output validation | source editing, no journal | refusal writes nothing; positive controls | | stale participant | whole refusal | full pre-image/revision/binding admission | explicit fresh plan | all B1 stale/late-write probes | | crash after PREPARE | pending | shared WAL/directional evidence | recorded plan only | process exit at every harness boundary; restart twice | | edit before undo | whole inverse refused | exact committed post-image | retain inverse/outside bytes | encoding/duplicate-property probes | Before delivery, independently generated properties must prove allowed-range confinement, refused plans write nothing, and undo composed with do is raw-byte identity. Run all salvaged regressions and shared executor crash boundaries. Implementation gates, on a VM through Nix and slot for heavy commands: `cargo fmt --all --check`; `cargo clippy --workspace --all-targets -j4 -- -D warnings`; `cargo test -j4 -p calternal-tasks -p calternal-notes -p calternal`; `cargo test -j4 -p calternal contract`; `node apps/web/scripts/action-types.mjs --check`. Not run for this documentation-only audit. Local gate: `git diff --check`. Never merge. No B1 completion or runtime pass is claimed. ```
Author
Owner

Closing: head 56451a2c is already in dev (reached via 1a7a31bc); nothing left to merge. Branch kept.

Closing: head 56451a2c is already in dev (reached via 1a7a31bc); nothing left to merge. Branch kept.
kayg closed this pull request 2026-11-04 13:04:46 +00:00
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled

Pull request closed

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!812
No description provided.