Skip to content

Slices and critical path

Delivery status: see the delivery board for the PR order, what runs in parallel, the decision on #2934, each slice's acceptance criteria and the plan gaps found while starting delivery.

Part of the temporary reversible deletion plan. Each slice is one PR with its own tests and docs, written test first. Sizes are rough: S (a day or two), M (about a week), L (more than a week, or hard to review). Risky marks a slice that touches every path of something; those get a fresh-context verifier review before merge.

The earlier draft's purge slices (S8a search purge, S8b project purge) and stored-file clean-up (S12) are dropped: Chris decided on 5 October 2026 that nothing is ever erased. The anti-resurrection follow-up is dropped with them, because no document is ever removed.

1. The slices

ID Slice Contents Depends on Size Risk Criteria
S0 Deletion ADR ADR-024 "Reversible deletion lifecycle" (ADR-022 and ADR-023 were taken meanwhile): the decisions in decisions and risks, the data model, the restore window, in-flight work, statistics and rollout; marks the uncommitted ADR-014 draft superseded; notes in the integrated plan that X-DEL is being delivered and that searches now follow the same no-erasure rule — S — DL-R0-09
S1 Study marker and composite write guard (dark) Study.Deletion; the composite IAggregateWriteGuard<Study>; StudyDeletedException → 410 study-deleted and the hub reason; extend StudyWriteLockArchitectureTests; the id-load audit and the no-erasure architecture tests; extended honouring tests for every ADR-020 write path — M Risky (every Study write seam; mitigated because the predicate matches everything until a marker exists) DL-R0-01 to 03
S2 Project deletion state and access gate (dark) Project.Deletion; the gate in AuthorizationHandler (legacy and enforced paths) and the SignalR handler, with 410 for members and 404 for others; recovery-route policy; list and query filters; background-job rules (skips, plus reservation timeouts and Bulk PDF clean-up kept running; statistics scheduled maintenance made to skip); delegated-work gate denial — M Risky (every project route and list) DL-R0-01, 04 to 06
S3a Deletion operation store, ledger and runner (dark) pmDeletionOperation and pmDeletionLedger with indexes; the state machine and lease; the restore-window fields; the host-neutral DeletionLifecycleRunner; the recurring schedule and thin consumer; configuration and validation (including the production refusal of the minutes override); metrics and gauges. No creator yet — M — DL-R0-07, 08
S3b In-flight stage and upload cancel The Requested stage: the "belongs to the item" rule; new-work refusals at routes and job start; the wait set (recalculations, exports, other sweeps, out-of-scope jobs); the blocked alert; the shared BulkPdfUploadCancellation service extracted from the cancel route and used by both S3a M Risky (touches the Bulk PDF upload protocol) DL-R1W-01 to 04, 11, 14, 15
S3c Import cancel CancelSearchImportJobAsync (the Error claim with CancelledForDeletion); the parse's start and per-batch status checks; the runner-driven failure clean-up replay; cancel-versus-completion tests; late-admission tests S3a, #4062 merged M Risky (import saga and its fence) DL-R1W-05 to 07, 12, 13
S3d Bulk-update cancel The durable CancelRequest on the version 2 operation, honoured by StopReasonAsync, the lock and pre-lock phases and takeovers; the runner as a deletion-owned attempt; the search-scope test; version 1 cancel before apply; rollback, quarantine and late-admission tests S3a, #4062 merged M Risky (ADR-020 executor) DL-R1W-08 to 10, 12, 13
S4a Search delete (flag) Route behaviour and contract (202, DTO); the fence fixes (QuestionAnswers, operation-id key, client invalidation, admission after the waits); the sweep with the pending-free rule; unlink and link snapshot; release; SignalR event; generated client and minimal web handling; the legacy erasing methods stay as the flag-off branch until deletionLifecycle is retired (#4172; rollout §2), so S4a does not remove them S1, S3b, S3c, S3d (S0 merged or agreed) L Risky (bulk data movement and statistics) DL-R1S-01 to 04, 08 to 10; DL-R1W-16
S4b Search restore Restore route with the window rule; reverse sweep; re-persist of derived fields and deleted-question answer removal under the restore's fence; relink with the import-job entry (stage filters are never touched); reservation rule S4a L Risky (statistics drift) DL-R1S-06, 07, 08
S5 Search UI Delete dialog copy, "Deletion pending" and dates; Recently deleted section; restore; refusal messages; SignalR handling; E2E search specs; user-guide pages S4a (S4b for restore) M — DL-R1S-05, 11, 12
S6 Project delete and restore (flag) Routes and contract; in-flight work for the whole project (every cancel path); IsProjectDeleted writer through a statistics-owned call; restore with the window rule, kept rows served again, reservation release and backfill request; ledger; SignalR events S2, S3b, S3c, S3d M — DL-R1P-01, 02, 04 to 06; DL-R1W-16
S7 Project UI Delete dialog; Recently deleted projects for the owner; restore; the deleted page for members; E2E project specs; user-guide page S6 M — DL-R1P-03, 07
S8 Administrator restore GET api/admin/deletions and POST api/admin/deletions/{operationId}/restore with the application-administrator capability, audit and tests; restore-all for rollback; the runbook in docs/how-to/ S4b, S6 S — DL-R1A-01 to 04
S9 Staging configuration cluster-gitops: deletionLifecycle on project-management and the web; restore window S4a S — —
S10 Soak additions On PR #4010's branch: setup, traffic actions and drills of testing §5 S4a, S6, S8 M — Soak gate
S11 Production enablement cluster-gitops production values at the cut-over (deletionLifecycle on), with Chris's approval MVP accepted on staging S Production —

The integrated plan's canonical parts (R0 composite guard over canonical collections, per-Study project markers, claims and drafts in R2a, pools in R3a, the impact preview, C20 events, notifications) stay in that plan's tracker under T-AC-03; they are not slices here.

2. Critical path and parallel work

flowchart LR
  S0[S0 ADR] -.-> S4a
  P4062[#4062 merged] --> S3c
  P4062 --> S3d
  S3a[S3a Operation store] --> S3b[S3b In-flight stage and upload cancel]
  S3a --> S3c[S3c Import cancel]
  S3a --> S3d[S3d Bulk-update cancel]
  S1[S1 Study guard] --> S4a[S4a Search delete]
  S3b --> S4a
  S3c --> S4a
  S3d --> S4a
  S4a --> S4b[S4b Search restore] --> S5[S5 Search UI]
  S2[S2 Project gate] --> S6[S6 Project delete and restore]
  S3b --> S6
  S3c --> S6
  S3d --> S6 --> S7[S7 Project UI]
  S4b --> S8[S8 Admin restore]
  S6 --> S8
  S4a --> S9[S9 Staging config]
  S4a --> S10[S10 Soak additions]
  S5 --> MVP((MVP on staging))
  S7 --> MVP
  S8 --> MVP
  MVP --> S11[S11 Production]
  • Start in parallel: S0, S1, S2 and S3a. None depends on another.
  • Then in parallel: S3b, S3c and S3d, the three cancel paths, all after S3a; S3c and S3d also wait for #4062 (the late-admission guard) to merge. They touch different code (Bulk PDF, the import saga, the ADR-020 executor) and can be built by three people at once.
  • Critical path: S3a → (S3c or S3d, whichever finishes later; both gated on #4062) → S4a → S4b → S5 (S1 runs alongside and must land before S4a). This path restores search deletion, the most-used of the two, and carries the in-flight and statistics risk.
  • Second lane, in parallel: S2 → S6 → S7 restores project deletion; S6 also needs S3b to S3d.
  • S8 is small and follows S4b and S6.
  • Soak lane: S10 can be developed against S4a's contract and run once S4a, S6 and S8 are on the branch it tests.
  • MVP done when S5, S7 and S8 are merged, S9 is applied, the staging acceptance in testing §7 passes and the soak's deletion drills pass.

3. Review notes

  • S1, S2, S3b, S3c, S3d, S4a and S4b: a fresh-context verifier reads the diff against this plan and the criteria before merge.
  • S3c is reviewed by the import saga's owner and the FEAT-024 owner (its fence); S3d by ADR-020's owner and the FEAT-024 owner.
  • S4a, S4b and S6 touch statistics; the FEAT-024 owner reviews them against .claude/rules/materialized-stats.md and statistics.
  • S3b touches the Bulk PDF upload protocol; the Bulk PDF programme's owner reviews it against ADR-012, ADR-015 and ADR-017.
  • S2 and S8 touch the authority paths; the authority programme's owner reviews them (coordination with #3335 and #3884).
  • Every web slice follows the M3 contract and needs preview acceptance; every slice keeps the user guide in step, because stale user docs block the merge.