tasks.move and tasks.reorder (B2) #799
Closed
kayg
wants to merge 1 commit from
feat/tasks-move-reorder into dev
pull from: feat/tasks-move-reorder
merge into: kayg:dev
kayg:main
kayg:feat/style-sheet-fixes
kayg:storage/wal-checkpoint-off-save-1051
kayg:t3/paged-search-reconcile-final
kayg:feat/pass8
kayg:review/calendar-2
kayg:fix/shared-row-swipes
kayg:feat/contrast
kayg:dev
kayg:feat/collections-db
kayg:fix/instant-keys-1056
kayg:feat/money-round
kayg:perf/stalls-1054
kayg:wip/tiering-v3-cold4
kayg:wip/tiering-v3-cold5
kayg:port/rows-actions
kayg:port/rows-drop
kayg:port/hidden-blocks
kayg:port/rows
kayg:port/port-tables
kayg:port/port-tables-2
kayg:t3/mail-1011-liveness
kayg:port/devices
kayg:port/port-attachments
kayg:port/port-attachments-2
kayg:port/port-attachments-3
kayg:docs/design-consistency
kayg:docs/engineering-standards
kayg:fix/rusqlite-0.41-rustsec-2026-0459
kayg:feat/iphone-fixes
kayg:shared/restore-and-stale-918-919
kayg:fix/phone-top-band-contrast
kayg:feat/notes-approve
kayg:perf/soak-max-gate
kayg:feat/files-s1-identity
kayg:fix/lifecycle-event-id
kayg:feat/quickfix
kayg:wip/tiering-v3-cold
kayg:perf/web-mockup-frame-fixes
kayg:port/contacts-merge
kayg:port/contacts-edit
kayg:test/shared-room-no-deleted-text
kayg:perf/first-paint-credits
kayg:fix/shared-history-after-grant
kayg:fix/phone-swipe-regressions
kayg:feat/contrast-r1
kayg:review/sharing-pr3-review
kayg:feat/tiering-v3-s2-tags
kayg:feat/folder-drop
kayg:fix/deskpills-lazy-share
kayg:feat/sharing-s1-pr3
kayg:tmp/money-round-before
kayg:fix/phone-pane-backdrop-roots
kayg:fix/palette-preload-chips
kayg:fix/invite-defaults
kayg:port/tasks-matrix
kayg:fix/restore-green-gates
kayg:fix/sharing-fast-path-hardening
kayg:t3/photos-s1
kayg:feat/tiering-v3-s1-namespace
kayg:notes-archive-hide
kayg:feat/tasks-actions
kayg:t3/photos-plan-slice-one
kayg:feat/whiteboard-s1
kayg:t3/paged-search-reconcile
kayg:t3/smooth-pane-transitions
kayg:t3/index-position-startup-scan
kayg:fix/private-staging-759b-r2
kayg:feat/dav-transport
kayg:feat/imap-notes-fetch
kayg:feat/imap-notes-projection
kayg:feat/imap-notes-readonly
kayg:feat/imap-notes-auth
kayg:feat/imap-notes-server-foundation
kayg:docs/undo-block-ids-plan
kayg:fix/undo-768
kayg:proto/block-identity-v7d
kayg:issue/carddav-read-perf-fix-r2
kayg:issue/carddav-read-r2
kayg:docs/imap-766-plan-v2
kayg:docs/imap-notes-plan
kayg:docs/quota-plan-2
kayg:fix/parallel-test-flakes
kayg:feat/contacts-companion-pure
kayg:docs/calendar-backend-v2-plan
kayg:feat/calendar-ical-converter
kayg:docs/tasks-writes-v2-plan
kayg:docs/carddav-writes-v2-plan
kayg:docs/contacts-import-v2-plan
kayg:issue/610-pm-midnight
kayg:feat/calendar-v2-s1-containment
kayg:docs/dav-recorder-v2-plan
kayg:plan/previews-865
kayg:plan/save-log-durable-entry
kayg:fix/e2e-data-on-ram
kayg:feat/appwindow3
kayg:feat/appwindow2
kayg:feat/appwindow
kayg:feat/money-p1
kayg:feat/keys-sheet
kayg:review/calendar-2-themes
kayg:feat/smooth-cursor
kayg:fix/float-style
kayg:review/calendar-2-float
kayg:release/2026-11-06-hotfix
kayg:archive/port/rows-drop-code
kayg:archive/port/rows-actions
kayg:archive/port/rows
kayg:scratch/tasks-894-ui-gates
kayg:review/calendar-2-night-wip
kayg:release/2026-11-05
kayg:archive/feat/tiering-v3-s1-namespace
kayg:archive/flaky/rows-drop-fixed
kayg:archive/flaky/rows-actions
kayg:archive/feat/tiering-v3-reader
kayg:archive/feat/tiering-v3-roots
kayg:archive/flaky/rows
kayg:sim/bm15-final
kayg:sim/bm15-fix
kayg:sim/bm15-bis-932
kayg:sim/bm15-bis-909
kayg:sim/bm15
kayg:sim/bm15-bis-887
kayg:perf/tiering-option-b
kayg:port/style-3
kayg:port/style-2
kayg:port/style
kayg:fix/sw-lazy-precache
kayg:fix/vim-w-waits-for-save
kayg:fix/signout-test-races
kayg:fp-scratch/all
kayg:sim/bm15-first-paint
kayg:archive/bm15/rows-drop
kayg:archive/bm15/rows-actions
kayg:fix/palette-snippet-contrast
kayg:archive/bm15/rows
kayg:archive/bm15/hidden
kayg:archive/plan/save-log-durable-entry
kayg:mock/money-fix2
kayg:archive/fix/e2e-data-on-ram
kayg:mock/appearance-all
kayg:mock/pill-press
kayg:archive/docs/design-consistency
kayg:mock/auto-swipes
kayg:mock/mail-actions
kayg:archive/feat/mail-p1
kayg:mock/money-static
kayg:archive/review/standards-917
kayg:archive/docs/engineering-standards
kayg:perf/tiering-761-fix
kayg:mock/type-audit
kayg:mock/third-pane
kayg:feat/contacts-import-v2-s1
kayg:perf/executor-hot-path
kayg:archive/port/hidden-blocks
kayg:archive/port/devices
kayg:scratch/executor-on-894
kayg:scratch/executor-spans2
kayg:scratch/executor-spans
kayg:train/2026-11-03-bm14c
kayg:archive/port/rows-drop
kayg:feat/tiering-761-d-scale
kayg:feat/tiering-761-c-index
kayg:feat/tiering-761-b-reader
kayg:archive/review/sharing-pr3-review-9fec3d1f
kayg:train/2026-11-03-bm14b
kayg:perf/ports-lazy-budgets
kayg:feat/tiering-761-a-migration
kayg:train/2026-11-03-bm14
kayg:train/2026-11-03-bm12
kayg:archive/review/sharing-pr3-review
kayg:archive/feat/sharing-s1-pr3
kayg:train/2026-11-03-bm11
kayg:archive/feat/imap-notes-fetch
kayg:train/2026-11-03-bm10
kayg:archive/review/sharing-pr3-review-code
kayg:archive/plan/previews-865
kayg:train/2026-11-02-bm9
kayg:archive/port/port-attachments-3
kayg:archive/port/contacts-merge
kayg:fix/motion-audit-859
kayg:train/2026-11-02-bm8
kayg:archive/scratch/bm8-prep
kayg:archive/port/port-pickers
kayg:archive/port/port-tables-2
kayg:archive/port/port-tables
kayg:archive/feat/sharing-s1-pr3-code
kayg:archive/scratch/bm7-fixed
kayg:train/2026-11-02-bm7
kayg:archive/fix/parallel-test-flakes-code-minipc01
kayg:train/2026-11-02-bm6
kayg:docs/imap-766-readonly-slice
kayg:feat/dav-recorder-v3
kayg:research/788-diagnosis
kayg:archive/fix/parallel-test-flakes
kayg:archive/perf/pr792-cold-index-edit
kayg:docs/sharing-slice-1
kayg:archive/docs/imap-766-plan-v2
kayg:feat/dav-recorder-v2
kayg:archive/docs/dav-recorder-v2-plan
kayg:spike/imap-766-s0-cases
kayg:archive/fix/undo-768
kayg:feat/dav-recorder
kayg:archive/docs/contacts-import-v2-plan
kayg:archive/feat/calendar-ical-converter
kayg:feat/contacts-import
kayg:perf/cold-growth-on-764
kayg:perf/cold-growth-on-tiering
kayg:archive/docs/tasks-writes-v2-plan
kayg:archive/docs/calendar-backend-v2-plan
kayg:archive/feat/contacts-companion-pure
kayg:feat/tasks-set-status
kayg:archive/docs/carddav-writes-v2-plan
kayg:archive/feat/calendar-v2-s1-containment
kayg:feat/tasks-delete-promote-duplicate
kayg:archive/feat/dav-transport
kayg:archive/fix/carddav-rebuild-r1
kayg:archive/fix/carddav-retention-r1
kayg:feat/carddav-writes
kayg:perf/quota-on-tiering
kayg:perf/quota-simple
kayg:perf/cold-growth-on-quota-stack
kayg:feat/calendar-identity
kayg:feat/calendar-event-parser
kayg:feat/calendar-props-maps
kayg:port/glass-when-ring
kayg:feat/tiering-761-s1
kayg:wip/10by32-01-impl-759b-scratch-20261030
kayg:wip/6by32-01-bm3-webkit-pause-20261030
kayg:wip/10by32-01-bm3-chromium-pause-20261030
kayg:wip/6by32-01-tier-761-s1-pause-20261030
kayg:spike/imap-766-s0
kayg:wip/6by32-02-calternal-pause-20261030
kayg:wip/8by64-01-review-688-pause-20261030
kayg:wip/6by32-01-verify-744-pause-20261030
kayg:wip/6by32-01-verify-742-pause-20261030
kayg:fix/private-staging-759b
kayg:wip/6by32-01-review-748-pause-20261030
kayg:wip/6by32-01-review-733c-pause-20261030
kayg:wip/6by32-01-review-733b-pause-20261030
kayg:wip/6by32-01-perf-idle-8-pause-20261030
kayg:wip/6by32-01-perf767-base-pause-20261030
kayg:wip/6by32-01-perf767b-767-pause-20261030
kayg:wip/6by32-01-perf767b-764-pause-20261030
kayg:wip/6by32-01-perf767-767-pause-20261030
kayg:wip/6by32-01-perf767-764-pause-20261030
kayg:wip/6by32-01-lists-b-pause-20261030
kayg:wip/6by32-01-ids-verify5-pause-20261030
kayg:wip/6by32-01-ids-verify4-pause-20261030
kayg:review/calendar-month
kayg:wip/10by32-02-undo-768-20261030
kayg:test/ids-verify3
kayg:wip/10by32-02-bm3-chromium-20261030
kayg:wip/10by32-01-review-753-20261030
kayg:wip/10by32-01-perf-idle-2-20261030
kayg:wip/10by32-01-bm2-webkit2-20261030
kayg:plan/759b-staging
kayg:train/2026-10-30-bm2
kayg:review/758b-tests
kayg:review/758-tests
kayg:review/764d-tests
kayg:review/767b-tests
kayg:review/preview-2026-10-29
kayg:review/767-tests
kayg:docs/tiering-731-plan
kayg:wip/c6b02-when2
kayg:wip/c6b02-tasks-create-fix5
kayg:wip/c6b02-settings-frost-mock
kayg:wip/c6b02-settings-frost-base
kayg:wip/c6b02-settings-frost
kayg:wip/c6b02-ring
kayg:wip/c6b02-review-733d
kayg:wip/c6b02-bm1-full-a
kayg:wip/compute02-when-field
kayg:wip/compute02-webkit-lists-repro
kayg:wip/compute02-train-bl2-dev
kayg:wip/compute02-dev-green-pw164
kayg:docs/deploy-plan
kayg:review/764c-tests
kayg:review/764b-tests
kayg:review/748g-tests
kayg:review/764-tests
kayg:review/759b-tests
kayg:fix/storage-owner-liveness-642
kayg:fix/storage-fix-7
kayg:wip/compute02-storage-fix-7
kayg:review/759-tests
kayg:feat/tiering-731
kayg:wip/tiering-731-first-attempt
kayg:wip/compute02-storage-fix-1
kayg:review/754g-tests
kayg:perf/idle-honest-2
kayg:review/754f-tests
kayg:review/754e-tests
kayg:review/755-tests
kayg:review/754d-tests
kayg:review/754c-tests
kayg:review/754b-tests
kayg:review/754-tests
kayg:fix/storage-private-tmp-642-dev
kayg:wip/compute02-verify-750
kayg:test/ids-verify5
kayg:test/ids-verify4
kayg:fix/storage-exact-file-quarantine-642
kayg:wip/compute02-verify-740
kayg:perf/one-flush-save
kayg:review/calendar-static
kayg:wip/compute02-verify-737
kayg:review/indexing-ring
kayg:review/when-field-2
kayg:wip/compute02-review-733
kayg:proto/block-identity-2-review
kayg:proto/block-identity-review
kayg:wip/c6b02-tc-design
kayg:review/when-field
kayg:issue/tasks-create-ids
kayg:issue/tasks-create
kayg:review/combined
kayg:wip/compute02-review-combined
kayg:review/task-polish
kayg:review/top-buttons
kayg:review/q1-q5
kayg:train/2026-10-26-bl2
kayg:archive/wt-398h
kayg:archive/train-bm-proptest-seed
kayg:archive/integ325-293
kayg:archive/integ325-ci
kayg:archive/client-auth-review-baseline
kayg:archive/wt-sim-4853
kayg:archive/wt-sim-4811
kayg:archive/wt-448m
kayg:archive/wt-398a-allocator
kayg:issue/calendar-adr
kayg:archive/old/train/2026-10-23bk2
kayg:archive/old/train/2026-10-23bk
kayg:issue/469-mockup-9a
kayg:issue/smart-tasks-mockup
kayg:issue/469-menus
kayg:issue/652-signout-flake
kayg:issue/652-history-fix7
kayg:issue/652-history-fix6
kayg:archive/old/issue/spring-check-perf
kayg:issue/spring-check-perf
kayg:issue/659-rename-fast
kayg:archive/old/train/2026-10-21ar
kayg:issue/search-hardening-3
kayg:issue/652-history-fix5
kayg:issue/660-port-sheets-glass
kayg:issue/652-history-fix4
kayg:issue/652-history-fix3
kayg:issue/652-history-fix2
kayg:issue/652-history-flake
kayg:train/2026-10-21an
kayg:issue/settings-admin-port
kayg:issue/search-port
kayg:train/2026-10-20am
kayg:issue/storage-split-fix2
kayg:issue/storage-split
kayg:archive/old/issue/folder-ids-fix
kayg:train/2026-10-20al
kayg:archive/old/issue/folder-ids
kayg:train/2026-10-20ak
kayg:issue/tables-mockup
kayg:train/2026-10-19aj
kayg:train/2026-10-19ai
kayg:issue/469-merge-fixes
kayg:issue/sidebar-band
kayg:archive/old/issue/608-settings-spec
kayg:train/2026-10-19ah
kayg:issue/swipe-offscreen
kayg:train/2026-10-19ag
kayg:archive/old/issue/590-nlp-adr
kayg:archive/old/issue/587-event-after-write-2
kayg:train/2026-10-19af
kayg:archive/old/issue/587-event-after-write
kayg:issue/469-pill-room-c
kayg:issue/469-pill-room
kayg:train/2026-10-19ae
kayg:issue/469-narrow-handle
kayg:issue/397-ios-swipe-2
kayg:archive/old/issue/adrs-photos-files-tasks
kayg:issue/469-desk-fixes
kayg:archive/old/issue/auto-update-adr
kayg:issue/469-filter-gap
kayg:issue/469-port-1b
kayg:issue/442-opacity-flake
kayg:archive/397-ios-swipe-2
kayg:issue/327-web-fast-3
kayg:archive/old/issue/469-port-1
kayg:issue/469-port-1
kayg:issue/327-web-fast-2
kayg:archive/old/issue/327-web-fast
kayg:archive/old/issue/425-stt-bench-vq1
kayg:archive/old/issue/445-no-bleed
kayg:archive/old/issue/400-swipe-mockup-2
kayg:issue/426-client-review
kayg:issue/426-client-2
kayg:issue/426-client
kayg:archive/old/issue/476-safe-area-lab
kayg:archive/445-top-light-2
kayg:archive/old/issue/445-top-light
kayg:issue/471-blocks-mockup
kayg:archive/old/issue/448-links-app-2
kayg:archive/old/issue/448-links-app
kayg:archive/old/issue/398-cold-links
kayg:issue/434-442-small-2
kayg:issue/434-442-small
kayg:archive/old/issue/398-unload
kayg:archive/old/issue/445-bottom-band
kayg:issue/445-bottom-band
kayg:issue/351-rem-3
kayg:archive/312-views-mockup
kayg:issue/351-rem-2
kayg:issue/351-rem
kayg:archive/old/issue/327-first-note
kayg:issue/395-width-phone
kayg:archive/old/issue/327-typing
kayg:issue/396-ios-edges
kayg:issue/397-ios-swipe
kayg:archive/398-allocator
kayg:archive/old/issue/327-notes-index
kayg:issue/345-347-contrast-empty-2
kayg:archive/old/issue/44-arenas
kayg:issue/44-arenas
kayg:archive/integ325
kayg:archive/old/issue/327-perf-harness
kayg:archive/old/issue/44-thp
kayg:issue/44-thp
kayg:archive/old/issue/285-sticky-pills
kayg:archive/old/issue/44-trim-3
kayg:issue/44-trim-3
kayg:archive/old/issue/165-cards
kayg:archive/old/issue/165-picker-2
kayg:archive/old/issue/212-multi-select
No reviewers
Labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
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
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/tasks-move-reorder"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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.moveaccepts a physical anchored-line move, a list/property drop, andan 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
fromfollow 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
Verification
All heavy commands ran through
~/bin/slotinsidenix 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 SIGKILLboundaries, 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 newlyadded publication barrier restart/version regression passed (1 test).
UPDATE_CONTRACTS=1 cargo test -j4 -p calternal contract: passed; regeneratedthe 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.
WIP: tasks.move and tasks.reorder (B2)to tasks.move and tasks.reorder (B2)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–89checks a room version for an initial attempt, but returns an existing receipt before re-reading or validating the file.bulk/atomic.rs::recover_filesuses ordinary Flush;room/load.rs:124–179merges outside bytes on restart. Every atomic move and its inverse then useroom/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:
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.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, andreview799_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–137gathers moved IDs only from each parsed item's/paragraph's/heading's first physical line.markdown.rs::candidateshas the same first-line restriction. For example:The parser-selected subtree includes the child continuation, so that ID physically moves, but
markersomits 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::Preparedandhistory/receipts.rs::append_group_recorded), not an original byte image.text.rs::decoderemoves every CRLF and retains only the majority Style;room/save.rsre-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-r1at the reviewed head. All six dev-01 slots and all three dev-02 slots were occupied. I stopped only my queuedreview799-r1-probes-v3unit 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.
round 1 repair plan and reproduced baseline
Merged B3 #798 at
f1600ed0, reusing its ONEtask_ops::verify_target(note, expected_source_bytes, expected_kind)incrates/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.
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.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 commit5fa65132, 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 existingtask_ops::verify_targetwas reused via branch merge; no second target guard was introduced.~/tasks799-red.logon dev-01~/tasks799-green2.logtasks799-finalunit on request; incomplete, no all-gates-passed claimLatest 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, PR #808, branch
docs/tasks-writes-v2-plan, head8d32f656049061a195653e950c9db097d10285c7.docs/plans/0066-tasks-writes-v2.mdcovers 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.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 sixreview799_*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.
kayg referenced this pull request2026-11-05 23:21:11 +00:00
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.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 devcd7f84432febfc63b788fbb9b9f9950452982d74, git cherry reports 47 unmatched and 0 equivalent patches. the landing audit lists each candidate missing commit and stable patch match inpr-799.md; unmatched patches can include superseded behavior.left open, source branch unchanged. no rebase or new test claim for this decision lane.
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.Pull request closed