tasks.move and tasks.reorder (B2) #799

Closed
kayg wants to merge 1 commit from feat/tasks-move-reorder into dev
Owner

A single Tasks drop can now move an anchored checkbox to another note (or change its list/group properties) and place the same task at a manual rank. Note deltas, exact inverses and a recoverable rank intent share one history commit; target-first file publication also survives save retries and restart.

B2 is complete except the explicitly deferred B1 status integration. Unsupported status drops still refuse, with TODOs and tests. Never merge.

B2 implementation record

Spec: ADRs 0056, 0066 and 0068; tasks-ui-port-plan.md B2.
Resumed pushed head 2f0f71e5; no newer branch commits or PR comments existed.
B1 status integration is deliberately deferred while B1 is in progress.

Design and costs

tasks.move accepts a physical anchored-line move, a list/property drop, and
an optional rank for that same tracked task, in one action. A private one-task
index uses the ordinary describer to verify the destination list/group after
the planned property edits. A different rank owner or mismatched group refuses.
No frontend behavior changes. The continuation adds roughly 400 production
lines plus focused tests; the rank intent and file barrier helpers are separate
small modules.

CommonMark (pulldown-cmark) selects the whole subtree, including continuation
lines, children and own → sub-bullets. Source, target and incoming-link rooms
are reserved in stable note-id order. Each re-reads outside bytes and checks
the exact planned version before mutation. Duplicate block IDs, ambiguous
owners, unsupported Markdown and non-allowlisted frontmatter refuse. Property
changes use notes::props; untouched bytes, BOM and line endings are preserved.
Incoming parent/child block links and the owning task's from follow the move.

One history transaction commits all note deltas, exact inverses, a rank intent
and the file-publication order. The existing order.db writer validates the rank
revision privately before that commit. Its keyed receipt then publishes the
intent once. Pending intents drain before any later bulk job can write ranks.
A failure after the history commit leaves the job running for recovery, rather
than recording an un-undoable partial failure. Jobs and rank writers share the
Home's job turn; ordinary room edits stay serialized by each held actor turn.

The target file, with its block ID, is saved before the source loses that block.
A durable publication barrier also covers ordinary save retries and restart:
an older room version or a source whose target is still pending cannot save.
Replay recognizes the committed per-note/rank receipts and completes stored
writes instead of planning another insertion. A half-done file move therefore
recovers to one block copy. Undo reserves and checks every note and the rank
revision before a shared commit, then restores stored exact bytes and ranks.
Its publication order reverses the transfer so the original source returns first.

Let S/T be source/target bytes, K moved block markers, and B bytes of affected
incoming-link notes. Planning remains O(K*(S+T)+B) time and O(S+T+B) space, plus
indexed link lookups. Fanout above 128 notes refuses. A reorder reads at most
100,000 matching tasks, sorts N group members and loads L ranks:
O(M + N log N + L) time and O(M+L) space. First drag seeds N rows; subsequent
drags change one row. Rank length is capped at 256. A combined move adds an
O(task-bytes) one-task projection, a bounded note publication queue and a rank
intent proportional to the changed rank rows. Partial indexes keep completed
publication/intent history out of recovery scans.

B1 boundary

TODO(B1) comments mark the status integration points. Done, cancelled and
waiting drops, terminal reopening, and a status change combined with a physical
line move still refuse before writing. Existing open property drops remain
supported. This PR does not integrate the in-progress B1 branch. Everything
else in B2 is complete and verified below. Never merge.

Failure table

Failure Effect Detection Recovery Test
stale source/target or outside edit neither notes nor ranks change room re-read and version check refresh and retry stale destination bytes; stale move
stale rank or wrong group/owner no note edits rank revision and projected membership refresh/choose matching task combined refusal tests
duplicate marker or unsafe frontmatter no plan applied parser uniqueness and strict allowlist fix source parser/frontmatter corpus
concurrent moves one move and rank revision wins job turn plus held room versions losing action refuses concurrent combined moves
crash before history commit no committed move or rank absent receipt replay stored plan SIGKILL before commit
crash after history, before rank note deltas and rank intent durable pending intent publish rank by receipt SIGKILL after commit
crash after rank, before progress rank already durable original keyed receipt no second rank write SIGKILL rank-written/after-rank
crash between files target written, source still has original ordered file receipts and block ID target-first flush, then source SIGKILL plus disk assertions
target save failure or cancelled coordinator source file cannot lose last copy durable publication barrier recover earlier files before source barrier restart/version test
undo after later note/rank change no part undone held note versions and rank revision refuse entire undo both combined stale-undo tests
large list seed once; later drag changes one row bounded plan and rank revision refuse exhaustion 10,000-task ordering test
B1-dependent status drop neither store changes explicit refusal await B1 integration B1 boundary test

Verification

All heavy commands ran through ~/bin/slot inside nix develop -c bash -c.
Full notes/server gates ran on dev-02 (aarch64); the final regression, contract
comparison and lint run used a free dev-01 (x86_64) slot.

  • cargo test -j4 -p calternal-tasks: 67 passed, including five SIGKILL
    boundaries, concurrent combined moves, exact reopened undo, stale note/rank
    refusals, no-op property version checks, B1 refusals and the 10,000-row list.
  • cargo test -j4 -p calternal-notes: 445 passed, 6 existing ignored.
  • cargo test -j4 -p calternal-notes history::task_orders::tests: the newly
    added publication barrier restart/version regression passed (1 test).
  • UPDATE_CONTRACTS=1 cargo test -j4 -p calternal contract: passed; regenerated
    the contract, followed by node apps/web/scripts/action-types.mjs.
  • cargo test -j4 -p calternal: 61 passed across unit/integration binaries,
    4 existing ignored.
  • cargo test -j4 -p calternal contract: final contract comparison passed.
  • cargo clippy -j4 -p calternal-tasks -p calternal-notes -p calternal --all-targets -- -D warnings: passed.
  • cargo fmt --all -- --check: passed.
  • node apps/web/scripts/action-types.mjs --check: passed.

Evidence: dev-02 ~/tasks-b2-combined-green.log (full notes/server gates),
dev-01 ~/tasks-b2-combined-final.log (final 67 Tasks tests, new barrier test,
contract, clippy, fmt and action types; ends B2_FINAL_GATES_PASSED).
The initial combined regression failed on the old explicit refusal before the
implementation. Final test fixtures explicitly settle ordinary append saves
before taking exact-byte comparison snapshots.

No independent review or latency measurements. Existing ignored tests are not
enabled. Temporary Nix overlays stay VM-local and are not committed.

A single Tasks drop can now move an anchored checkbox to another note (or change its list/group properties) and place the same task at a manual rank. Note deltas, exact inverses and a recoverable rank intent share one history commit; target-first file publication also survives save retries and restart. B2 is complete except the explicitly deferred B1 status integration. Unsupported status drops still refuse, with TODOs and tests. Never merge. # B2 implementation record Spec: ADRs 0056, 0066 and 0068; tasks-ui-port-plan.md B2. Resumed pushed head 2f0f71e5; no newer branch commits or PR comments existed. B1 status integration is deliberately deferred while B1 is in progress. ## Design and costs `tasks.move` accepts a physical anchored-line move, a list/property drop, and an optional rank for that same tracked task, in one action. A private one-task index uses the ordinary describer to verify the destination list/group after the planned property edits. A different rank owner or mismatched group refuses. No frontend behavior changes. The continuation adds roughly 400 production lines plus focused tests; the rank intent and file barrier helpers are separate small modules. CommonMark (pulldown-cmark) selects the whole subtree, including continuation lines, children and own → sub-bullets. Source, target and incoming-link rooms are reserved in stable note-id order. Each re-reads outside bytes and checks the exact planned version before mutation. Duplicate block IDs, ambiguous owners, unsupported Markdown and non-allowlisted frontmatter refuse. Property changes use notes::props; untouched bytes, BOM and line endings are preserved. Incoming parent/child block links and the owning task's `from` follow the move. One history transaction commits all note deltas, exact inverses, a rank intent and the file-publication order. The existing order.db writer validates the rank revision privately before that commit. Its keyed receipt then publishes the intent once. Pending intents drain before any later bulk job can write ranks. A failure after the history commit leaves the job running for recovery, rather than recording an un-undoable partial failure. Jobs and rank writers share the Home's job turn; ordinary room edits stay serialized by each held actor turn. The target file, with its block ID, is saved before the source loses that block. A durable publication barrier also covers ordinary save retries and restart: an older room version or a source whose target is still pending cannot save. Replay recognizes the committed per-note/rank receipts and completes stored writes instead of planning another insertion. A half-done file move therefore recovers to one block copy. Undo reserves and checks every note and the rank revision before a shared commit, then restores stored exact bytes and ranks. Its publication order reverses the transfer so the original source returns first. Let S/T be source/target bytes, K moved block markers, and B bytes of affected incoming-link notes. Planning remains O(K*(S+T)+B) time and O(S+T+B) space, plus indexed link lookups. Fanout above 128 notes refuses. A reorder reads at most 100,000 matching tasks, sorts N group members and loads L ranks: O(M + N log N + L) time and O(M+L) space. First drag seeds N rows; subsequent drags change one row. Rank length is capped at 256. A combined move adds an O(task-bytes) one-task projection, a bounded note publication queue and a rank intent proportional to the changed rank rows. Partial indexes keep completed publication/intent history out of recovery scans. ## B1 boundary TODO(B1) comments mark the status integration points. Done, cancelled and waiting drops, terminal reopening, and a status change combined with a physical line move still refuse before writing. Existing open property drops remain supported. This PR does not integrate the in-progress B1 branch. Everything else in B2 is complete and verified below. Never merge. ## Failure table | Failure | Effect | Detection | Recovery | Test | |---|---|---|---|---| | stale source/target or outside edit | neither notes nor ranks change | room re-read and version check | refresh and retry | stale destination bytes; stale move | | stale rank or wrong group/owner | no note edits | rank revision and projected membership | refresh/choose matching task | combined refusal tests | | duplicate marker or unsafe frontmatter | no plan applied | parser uniqueness and strict allowlist | fix source | parser/frontmatter corpus | | concurrent moves | one move and rank revision wins | job turn plus held room versions | losing action refuses | concurrent combined moves | | crash before history commit | no committed move or rank | absent receipt | replay stored plan | SIGKILL before commit | | crash after history, before rank | note deltas and rank intent durable | pending intent | publish rank by receipt | SIGKILL after commit | | crash after rank, before progress | rank already durable | original keyed receipt | no second rank write | SIGKILL rank-written/after-rank | | crash between files | target written, source still has original | ordered file receipts and block ID | target-first flush, then source | SIGKILL plus disk assertions | | target save failure or cancelled coordinator | source file cannot lose last copy | durable publication barrier | recover earlier files before source | barrier restart/version test | | undo after later note/rank change | no part undone | held note versions and rank revision | refuse entire undo | both combined stale-undo tests | | large list | seed once; later drag changes one row | bounded plan and rank revision | refuse exhaustion | 10,000-task ordering test | | B1-dependent status drop | neither store changes | explicit refusal | await B1 integration | B1 boundary test | ## Verification All heavy commands ran through `~/bin/slot` inside `nix develop -c bash -c`. Full notes/server gates ran on dev-02 (aarch64); the final regression, contract comparison and lint run used a free dev-01 (x86_64) slot. - `cargo test -j4 -p calternal-tasks`: 67 passed, including five SIGKILL boundaries, concurrent combined moves, exact reopened undo, stale note/rank refusals, no-op property version checks, B1 refusals and the 10,000-row list. - `cargo test -j4 -p calternal-notes`: 445 passed, 6 existing ignored. - `cargo test -j4 -p calternal-notes history::task_orders::tests`: the newly added publication barrier restart/version regression passed (1 test). - `UPDATE_CONTRACTS=1 cargo test -j4 -p calternal contract`: passed; regenerated the contract, followed by `node apps/web/scripts/action-types.mjs`. - `cargo test -j4 -p calternal`: 61 passed across unit/integration binaries, 4 existing ignored. - `cargo test -j4 -p calternal contract`: final contract comparison passed. - `cargo clippy -j4 -p calternal-tasks -p calternal-notes -p calternal --all-targets -- -D warnings`: passed. - `cargo fmt --all -- --check`: passed. - `node apps/web/scripts/action-types.mjs --check`: passed. Evidence: dev-02 `~/tasks-b2-combined-green.log` (full notes/server gates), dev-01 `~/tasks-b2-combined-final.log` (final 67 Tasks tests, new barrier test, contract, clippy, fmt and action types; ends `B2_FINAL_GATES_PASSED`). The initial combined regression failed on the old explicit refusal before the implementation. Final test fixtures explicitly settle ordinary append saves before taking exact-byte comparison snapshots. No independent review or latency measurements. Existing ignored tests are not enabled. Temporary Nix overlays stay VM-local and are not committed.
docs: plan safe task moves and manual ordering
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
f008148b61
kayg changed title from WIP: tasks.move and tasks.reorder (B2) to tasks.move and tasks.reorder (B2) 2026-10-31 19:11:13 +00:00
Author
Owner

Independent review, round 1

verdict: fix first. reviewed 6a07b845fc4743312517d1fc02f4af078091b201, the implementation record, ADRs 0056/0066/0068, and the B1 #801 / B3 #798 review findings. no P0 identified. two P1 findings and one P2 finding below.

P1: the move's checked-write contract does not survive placement, replay or undo

crates/notes/src/room/atomic.rs:64–89 checks a room version for an initial attempt, but returns an existing receipt before re-reading or validating the file. bulk/atomic.rs::recover_files uses ordinary Flush; room/load.rs:124–179 merges outside bytes on restart. Every atomic move and its inverse then use room/save.rs:253–258, which ingests conflicting file bytes and retries instead of refusing the checked operation. Neither the durable Change nor atomic_files stores expected raw pre/post images.

Two concrete inspection scenarios:

  • Pause at the destination's atomic-before-file, change the destination file, and resume. The committed move can merge and publish against the changed bytes. The same boundary on the original source during Undo permits a changed note to be rewritten after Undo's version check. Unsafe YAML introduced at this point also bypasses the planning allowlist.
  • Kill at between-files, when the target is durable and the source still contains the task. While stopped, remove the target's moved block, retaining the note's identity. On reopen, the target's outside deletion is ingested, but its atomic_files row is already done. Nothing revalidates that target block before recovery saves the source deletion. This can remove the last surviving checkbox subtree; a done publication row is not proof that the target still contains it.

Persist each checked note's raw pre/post bytes or hashes with its receipt and enforce them at actual placement, on every retry, during recovery and for the inverse. Accept a replay only against the expected pre-image or already placed post-image; preserve/refuse conflicts. Before publishing a source removal, verify the destination still holds the expected moved block/image. Keep the rank intent and job recoverable when publication refuses.

Unrun probes: review799_late_apply, review799_late_undo, review799_recovery_must_refuse_changed_source_bytes, and review799_recovery_must_not_remove_last_copy_after_target_edit.

crates/tasks/src/moving.rs:120–137 gathers moved IDs only from each parsed item's/paragraph's/heading's first physical line. markdown.rs::candidates has the same first-line restriction. For example:

- [ ] Carry ^0123456789abcdef
  - child first
    child last ^fedcba9876543210
- ordinary stays

The parser-selected subtree includes the child continuation, so that ID physically moves, but markers omits it. An incoming [child](<Source.md#^fedcba9876543210>) is left pointing at Source. An existing destination block with that same ID is also missed by the collision preflight, allowing two identities in one destination. This is the continuation-marker omission B3 round 1 already found in duplication.

Enumerate supported markers throughout the parsed block extents using the shared marker rules, then use that complete set for uniqueness and incoming/self-link rewrites. If a layout cannot be resolved safely, refuse before committing it. Preserve ordinary sibling bullets.

Unrun probe: review799_move_must_retarget_continuation_marker.

P2: exact Undo does not retain original file bytes for mixed line endings

The stored inverse is UTF-16 text edits (bulk/atomic.rs::Prepared and history/receipts.rs::append_group_recorded), not an original byte image. text.rs::decode removes every CRLF and retains only the majority Style; room/save.rs re-encodes the whole file in that style. An accepted note containing both LF and CRLF therefore has untouched line endings normalized by the move, and Undo cannot restore its original bytes, even with no intervening edit. Uniform CRLF/BOM retention does not cover this case.

Retain and restore the original raw image for checked move/Undo, or refuse non-round-trippable input before either file changes. Apply the same rule to incoming-link notes.

Unrun probe: review799_undo_must_restore_mixed_newline_bytes.

scope and validation limits

This is a code-inspection review; the new runtime scenarios above are not claimed reproduced. Six probes remain uncommitted on dev-01 in ~/Developer/Worktrees/review-799-r1 at the reviewed head. All six dev-01 slots and all three dev-02 slots were occupied. I stopped only my queued review799-r1-probes-v3 unit before Cargo started. Its log contains only Nix evaluation warnings; no test results. Earlier launch errors were PATH/working-directory setup errors, not test failures.

To run from that worktree: CARGO_TARGET_DIR=/home/claude/Developer/Worktrees/tasks-move-reorder/target nix develop -c bash -c '~/bin/slot cargo test -j4 -p calternal-tasks review799 -- --nocapture'. Temporary Nix files remain uncommitted. No code pushed, no merge.

The parsed Item extent does include nested/continuation content, and the existing code/comment corpus and lexical YAML checks cover the named interior-quote, list-comment, flow and multiline cases by inspection. The identity enumeration and later write paths above are separate gaps. Reorder's rank transaction, receipt and revision checks showed no additional blocker by inspection. B1 integration remains deferred as requested; this review does not require integrating #801.

## Independent review, round 1 **verdict: fix first.** reviewed `6a07b845fc4743312517d1fc02f4af078091b201`, the implementation record, ADRs 0056/0066/0068, and the B1 #801 / B3 #798 review findings. no P0 identified. two P1 findings and one P2 finding below. ### P1: the move's checked-write contract does not survive placement, replay or undo `crates/notes/src/room/atomic.rs:64–89` checks a room version for an initial attempt, but returns an existing receipt before re-reading or validating the file. `bulk/atomic.rs::recover_files` uses ordinary Flush; `room/load.rs:124–179` merges outside bytes on restart. Every atomic move and its inverse then use `room/save.rs:253–258`, which ingests conflicting file bytes and retries instead of refusing the checked operation. Neither the durable Change nor atomic_files stores expected raw pre/post images. Two concrete inspection scenarios: - Pause at the destination's `atomic-before-file`, change the destination file, and resume. The committed move can merge and publish against the changed bytes. The same boundary on the original source during Undo permits a changed note to be rewritten after Undo's version check. Unsafe YAML introduced at this point also bypasses the planning allowlist. - Kill at `between-files`, when the target is durable and the source still contains the task. While stopped, remove the target's moved block, retaining the note's identity. On reopen, the target's outside deletion is ingested, but its atomic_files row is already done. Nothing revalidates that target block before recovery saves the source deletion. This can remove the last surviving checkbox subtree; a done publication row is not proof that the target still contains it. Persist each checked note's raw pre/post bytes or hashes with its receipt and enforce them at actual placement, on every retry, during recovery and for the inverse. Accept a replay only against the expected pre-image or already placed post-image; preserve/refuse conflicts. Before publishing a source removal, verify the destination still holds the expected moved block/image. Keep the rank intent and job recoverable when publication refuses. Unrun probes: `review799_late_apply`, `review799_late_undo`, `review799_recovery_must_refuse_changed_source_bytes`, and `review799_recovery_must_not_remove_last_copy_after_target_edit`. ### P1: continuation-line child identities bypass collision checks and link retargeting `crates/tasks/src/moving.rs:120–137` gathers moved IDs only from each parsed item's/paragraph's/heading's first physical line. `markdown.rs::candidates` has the same first-line restriction. For example: ```markdown - [ ] Carry ^0123456789abcdef - child first child last ^fedcba9876543210 - ordinary stays ``` The parser-selected subtree includes the child continuation, so that ID physically moves, but `markers` omits it. An incoming `[child](<Source.md#^fedcba9876543210>)` is left pointing at Source. An existing destination block with that same ID is also missed by the collision preflight, allowing two identities in one destination. This is the continuation-marker omission B3 round 1 already found in duplication. Enumerate supported markers throughout the parsed block extents using the shared marker rules, then use that complete set for uniqueness and incoming/self-link rewrites. If a layout cannot be resolved safely, refuse before committing it. Preserve ordinary sibling bullets. Unrun probe: `review799_move_must_retarget_continuation_marker`. ### P2: exact Undo does not retain original file bytes for mixed line endings The stored inverse is UTF-16 text edits (`bulk/atomic.rs::Prepared` and `history/receipts.rs::append_group_recorded`), not an original byte image. `text.rs::decode` removes every CRLF and retains only the majority Style; `room/save.rs` re-encodes the whole file in that style. An accepted note containing both LF and CRLF therefore has untouched line endings normalized by the move, and Undo cannot restore its original bytes, even with no intervening edit. Uniform CRLF/BOM retention does not cover this case. Retain and restore the original raw image for checked move/Undo, or refuse non-round-trippable input before either file changes. Apply the same rule to incoming-link notes. Unrun probe: `review799_undo_must_restore_mixed_newline_bytes`. ### scope and validation limits This is a code-inspection review; the new runtime scenarios above are not claimed reproduced. Six probes remain uncommitted on dev-01 in `~/Developer/Worktrees/review-799-r1` at the reviewed head. All six dev-01 slots and all three dev-02 slots were occupied. I stopped only my queued `review799-r1-probes-v3` unit before Cargo started. Its log contains only Nix evaluation warnings; no test results. Earlier launch errors were PATH/working-directory setup errors, not test failures. To run from that worktree: `CARGO_TARGET_DIR=/home/claude/Developer/Worktrees/tasks-move-reorder/target nix develop -c bash -c '~/bin/slot cargo test -j4 -p calternal-tasks review799 -- --nocapture'`. Temporary Nix files remain uncommitted. No code pushed, no merge. The parsed Item extent does include nested/continuation content, and the existing code/comment corpus and lexical YAML checks cover the named interior-quote, list-comment, flow and multiline cases by inspection. The identity enumeration and later write paths above are separate gaps. Reorder's rank transaction, receipt and revision checks showed no additional blocker by inspection. B1 integration remains deferred as requested; this review does not require integrating #801.
Author
Owner

round 1 repair plan and reproduced baseline

Merged B3 #798 at f1600ed0, reusing its ONE task_ops::verify_target(note, expected_source_bytes, expected_kind) in crates/notes/src/task_ops.rs; no second guard. No merge into dev.

Persist raw pre/post images alongside atomic receipts in the same history transaction. Forward plans pin disk bytes; inverse plans pin the forward post-image. Placement, ordinary Flush, replay and undo use the shared guard. Source publication rechecks completed destination images while the group is pending. Conflicts retain the running job, committed deltas and rank receipts for recovery. Non-round-trippable bytes (mixed newlines / invalid UTF-8) refuse before any file mutation. Reuse B3 marker extent enumeration, restricted to markers physically within the moved subtree.

Additional storage is O(sum of affected file bytes) per committed group; planning/verification adds O(sum of affected bytes), plus bounded predecessor image reads (at most 128 notes). Image helpers remain small, without a second write framework.

failure effect detection recovery regression
late destination/source edit checked placement refuses, outside bytes retained raw pre/post and semantic kind guard restore expected bytes then replay late apply / late undo
target edited after target-first crash source retains last disk copy recheck completed predecessor image resolve target then replay between-files target deletion
source changed while stopped no source overwrite stored raw pre-image resolve conflict then replay changed source recovery
continuation ID collision/link refuse collision; retarget only moved identities shared parsed marker extents fix duplicate IDs continuation link + collision tests
mixed line endings no checked write exact decode/encode round trip normalize explicitly outside this action mixed newline refusal

Reviewer probes copied from the untouched dev-01 review worktree and committed. Baseline at 5fa65132: 5 fail, 1 pass (tasks799-red.log). Changed-source probe already passed; the other five reproduce the reported problems. Post-fix gates in progress on dev-01 via slots; final status table will follow.

## round 1 repair plan and reproduced baseline Merged B3 #798 at f1600ed0, reusing its ONE `task_ops::verify_target(note, expected_source_bytes, expected_kind)` in `crates/notes/src/task_ops.rs`; no second guard. No merge into dev. Persist raw pre/post images alongside atomic receipts in the same history transaction. Forward plans pin disk bytes; inverse plans pin the forward post-image. Placement, ordinary Flush, replay and undo use the shared guard. Source publication rechecks completed destination images while the group is pending. Conflicts retain the running job, committed deltas and rank receipts for recovery. Non-round-trippable bytes (mixed newlines / invalid UTF-8) refuse before any file mutation. Reuse B3 marker extent enumeration, restricted to markers physically within the moved subtree. Additional storage is O(sum of affected file bytes) per committed group; planning/verification adds O(sum of affected bytes), plus bounded predecessor image reads (at most 128 notes). Image helpers remain small, without a second write framework. | failure | effect | detection | recovery | regression | |---|---|---|---|---| | late destination/source edit | checked placement refuses, outside bytes retained | raw pre/post and semantic kind guard | restore expected bytes then replay | late apply / late undo | | target edited after target-first crash | source retains last disk copy | recheck completed predecessor image | resolve target then replay | between-files target deletion | | source changed while stopped | no source overwrite | stored raw pre-image | resolve conflict then replay | changed source recovery | | continuation ID collision/link | refuse collision; retarget only moved identities | shared parsed marker extents | fix duplicate IDs | continuation link + collision tests | | mixed line endings | no checked write | exact decode/encode round trip | normalize explicitly outside this action | mixed newline refusal | Reviewer probes copied from the untouched dev-01 review worktree and committed. Baseline at 5fa65132: 5 fail, 1 pass (`tasks799-red.log`). Changed-source probe already passed; the other five reproduce the reported problems. Post-fix gates in progress on dev-01 via slots; final status table will follow.
Author
Owner

on hold pending the shared Tasks writes v2 plan

Stopped further fixes as requested. B1–B3 are on hold after B3's final review failed on recurring write-path classes. Resume only against docs/plans/0066-tasks-writes-v2.md: a pure planner of exact splices plus ONE journaled executor for apply, recovery and undo across every action. This branch is an intermediate implementation, not approved for merge.

All current work is committed and pushed at 76568947 (feat/tasks-move-reorder). The reviewer's six probes are preserved in commit 5fa65132, with subsequent regression adaptations for the permitted mixed-newline refusal and disk-level last-copy assertion, plus continuation collision/sibling identity and filesystem race tests. These tests should carry into the redesign. B3's existing task_ops::verify_target was reused via branch merge; no second target guard was introduced.

item status at hold
reviewer baseline probes 5 failed, 1 passed before fixes; log ~/tasks799-red.log on dev-01
intermediate tasks suite 80 passed, including six review regressions; ~/tasks799-green2.log
latest broader gates stopped my tasks799-final unit on request; incomplete, no all-gates-passed claim
fmt / generated action types generated VM changes preserved in final commit; temporary Nix overlays excluded
final review / merge no approval claimed; never merged

Latest partial run evidence: dev-01 ~/tasks799-final.log. The earlier contract ordering failure was corrected and contract passed in the latest server test run. Clippy and final action-types/fmt checks were not reached. Existing VM implementation and review worktrees were preserved. No further fix or gate work is running for this task.

## on hold pending the shared Tasks writes v2 plan Stopped further fixes as requested. B1–B3 are on hold after B3's final review failed on recurring write-path classes. Resume only against `docs/plans/0066-tasks-writes-v2.md`: a pure planner of exact splices plus ONE journaled executor for apply, recovery and undo across every action. This branch is an intermediate implementation, not approved for merge. All current work is committed and pushed at `76568947` (`feat/tasks-move-reorder`). The reviewer's six probes are preserved in commit `5fa65132`, with subsequent regression adaptations for the permitted mixed-newline refusal and disk-level last-copy assertion, plus continuation collision/sibling identity and filesystem race tests. These tests should carry into the redesign. B3's existing `task_ops::verify_target` was reused via branch merge; no second target guard was introduced. | item | status at hold | |---|---| | reviewer baseline probes | 5 failed, 1 passed before fixes; log `~/tasks799-red.log` on dev-01 | | intermediate tasks suite | 80 passed, including six review regressions; `~/tasks799-green2.log` | | latest broader gates | stopped my `tasks799-final` unit on request; incomplete, no all-gates-passed claim | | fmt / generated action types | generated VM changes preserved in final commit; temporary Nix overlays excluded | | final review / merge | no approval claimed; never merged | Latest partial run evidence: dev-01 `~/tasks799-final.log`. The earlier contract ordering failure was corrected and contract passed in the latest server test run. Clippy and final action-types/fmt checks were not reached. Existing VM implementation and review worktrees were preserved. No further fix or gate work is running for this task.
Author
Owner

on hold pending the shared Tasks writes v2 plan, PR #808, branch docs/tasks-writes-v2-plan, head 8d32f656049061a195653e950c9db097d10285c7.

docs/plans/0066-tasks-writes-v2.md covers all task writes: pure exact-byte splice planners plus ONE journaled executor for apply, recovery and recorded inverse undo, reusing calendar v2’s parsed view and frontmatter writer. Undo requires a committed change and the exact recorded post-image; refused removals cannot be restored. Executor first, then B1, B2, B3. Keep existing work/probes preserved; no further patch/review loop or merge of this held implementation pending the plan. Docs only; no implementation started.

on hold pending the shared [Tasks writes v2 plan, PR #808](https://git.kayg.org/kayg/calternal/pulls/808), branch `docs/tasks-writes-v2-plan`, head `8d32f656049061a195653e950c9db097d10285c7`. `docs/plans/0066-tasks-writes-v2.md` covers all task writes: pure exact-byte splice planners plus ONE journaled executor for apply, recovery and recorded inverse undo, reusing calendar v2’s parsed view and frontmatter writer. Undo requires a committed change and the exact recorded post-image; refused removals cannot be restored. Executor first, then B1, B2, B3. Keep existing work/probes preserved; no further patch/review loop or merge of this held implementation pending the plan. Docs only; no implementation started.
Author
Owner

Pointer: #894 (feat/tasks-actions) overlaps this PR. The review that compares the two is here: #894 (comment)

Recommendation (c): keep #894's API, version, reorder and status-only move. Rebuild delete/duplicate (and later any line move) as v2 planners on the shared executor (#808). From this PR: the pulldown-cmark subtree extent, marker enumeration, the 256-byte rank cap, the group-membership refusal and the six review799_* probes. #894 has the same exact-byte guard gap as r1 P1 (old room/bulk path) and the same mixed-newline risk as r1 P2.

After those pieces are ported to the v2 rebuild, close this PR. Keep the branch until then.

Pointer: #894 (`feat/tasks-actions`) overlaps this PR. The review that compares the two is here: https://git.kayg.org/kayg/calternal/pulls/894#issuecomment-76844 Recommendation **(c)**: keep #894's API, `version`, reorder and status-only move. Rebuild delete/duplicate (and later any line move) as v2 planners on the shared executor (#808). From this PR: the pulldown-cmark subtree extent, marker enumeration, the 256-byte rank cap, the group-membership refusal and the six `review799_*` probes. #894 has the same exact-byte guard gap as r1 P1 (old room/bulk path) and the same mixed-newline risk as r1 P2. After those pieces are ported to the v2 rebuild, close this PR. Keep the branch until then.
Author
Owner

Keeper proposal after reading #798, #799, #894 and all their review comments: gate #894 (cac156dd68c222da099343628a75abfa97a75504), the replacement following review 76844, rather than revive the held bulk/room implementations. #798 round 3 explicitly requires stop-and-simplify; #799 is held for the same executor design. Propose closing #798/#799 as superseded only after recording the missing promotion/physical-line-move scope and preserving/porting their review probes. Do not close #894 as a duplicate: it carries the reviewed replacement API and the executor rework. Neither earlier PR is approved for merge. No PR closed or merged. I will merge current dev into #894, run fresh gates, add crash/retry regressions and report remaining scope explicitly.

Keeper proposal after reading #798, #799, #894 and all their review comments: gate #894 (`cac156dd68c222da099343628a75abfa97a75504`), the replacement following review 76844, rather than revive the held bulk/room implementations. #798 round 3 explicitly requires stop-and-simplify; #799 is held for the same executor design. Propose closing #798/#799 as superseded only after recording the missing promotion/physical-line-move scope and preserving/porting their review probes. Do not close #894 as a duplicate: it carries the reviewed replacement API and the executor rework. Neither earlier PR is approved for merge. No PR closed or merged. I will merge current dev into #894, run fresh gates, add crash/retry regressions and report remaining scope explicitly.
Author
Owner

housekeeping #1009: needs-decision.

Explicit three-round hold; #808/#894 replace Tasks move/reorder execution. Preserve reorder/move probes and exact scope tests.

original head: 7656894724bc5689f4ae3807665c703c455107bd. against dev cd7f84432febfc63b788fbb9b9f9950452982d74, git cherry reports 47 unmatched and 0 equivalent patches. the landing audit lists each candidate missing commit and stable patch match in pr-799.md; unmatched patches can include superseded behavior.

left open, source branch unchanged. no rebase or new test claim for this decision lane.

housekeeping #1009: needs-decision. Explicit three-round hold; #808/#894 replace Tasks move/reorder execution. Preserve reorder/move probes and exact scope tests. original head: `7656894724bc5689f4ae3807665c703c455107bd`. against dev `cd7f84432febfc63b788fbb9b9f9950452982d74`, git cherry reports 47 unmatched and 0 equivalent patches. the [landing audit](https://git.kayg.org/attachments/fe3c09dc-dea3-47a0-92e2-b44a777083e5) lists each candidate missing commit and stable patch match in `pr-799.md`; unmatched patches can include superseded behavior. left open, source branch unchanged. no rebase or new test claim for this decision lane.
Author
Owner

Superseded by #808/#894 (Tasks writes v2). The branch and original tips are archived under archive/ (see #1009), so nothing is lost; useful regression vectors are noted there for the active lanes. Closing.

Superseded by #808/#894 (Tasks writes v2). The branch and original tips are archived under `archive/` (see #1009), so nothing is lost; useful regression vectors are noted there for the active lanes. Closing.
kayg closed this pull request 2026-11-07 21:21:07 +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!799
No description provided.