Skip to content

fix(components): make archive cascade hydration- and failure-safe - #658

Draft
wibus-wee wants to merge 4 commits into
mainfrom
fix/archive-hydration-bounded-wait
Draft

fix(components): make archive cascade hydration- and failure-safe#658
wibus-wee wants to merge 4 commits into
mainfrom
fix/archive-hydration-bounded-wait

Conversation

@wibus-wee

@wibus-wee wibus-wee commented Sep 12, 2026

Copy link
Copy Markdown
Member

Related issue

Closes #574

Problem / pressure

Session Detail can expose Archive while the UI metadata projection contains only the root Session. Selecting lifecycle targets from that partial cache can archive the root while leaving a direct child Tab active.

Even after target discovery is corrected, a root-first sequence of independent metadata writes can recreate the same final state when a later child write rejects. LoroRepo has no cross-document rollback transaction, and terminal IPC previously ran before each metadata write.

Summary

  • Query the repository metadata snapshot before selecting archive targets; do not wait on global UI projection readiness.
  • Select only the root and direct parentSessionId children. openedBy* Sessions remain independent.
  • Commit child metadata first and root metadata last, making the root the final commit point.
  • On failure, compensate every attempted target to its prior isArchived and status; compensate the root before children so rollback failure still preserves root-archived implies children-archived.
  • Close terminals only after all metadata writes succeed. Terminal IPC is best-effort post-commit cleanup.
  • Abort a workspace switch before the first write; after the first write, finish or compensate against the captured runtime.
  • Describe the query result as the repository snapshot observed by the action, not an atomic or future-complete target set.

Visual explanation

flowchart TD
  A[Archive requested] --> B[Query repository metadata]
  B -->|query fails| X[Reject: zero writes and zero terminal closes]
  B --> C[Select root and direct child Tabs]
  C --> D{Workspace unchanged?}
  D -->|no| X
  D -->|yes| E[Write children first]
  E -->|failure| R[Compensate attempted targets]
  E --> F[Write root last]
  F -->|failure| R
  F --> G[Close selected terminals best effort]
Loading

Failure contract

Boundary Result
Query fails or workspace changes before the first write Reject with no metadata or terminal side effects.
Child write fails Root remains active; attempted child writes are compensated.
Final root write fails Root is compensated first, then children. No terminal closes occur.
Root compensation also fails after an accepted root mutation Children remain archived; the thrown error includes both write and rollback failures.
Workspace changes after the first write The captured runtime completes or compensates the entire write set.
Terminal IPC fails after commit Durable archive remains successful; remaining terminal closes are still attempted.

Test plan

  • vitest run tests/use-session-actions.test.ts — 39 tests passed, including real LoroRepo.getMeta().scan() archive integration and all failure/commit-point cases above.
  • vitest run tests/doc-meta-batch.test.ts tests/doc-meta-subscription.test.ts — 10 tests passed.
  • oxlint --quiet src/hooks/use-session-actions.ts tests/use-session-actions.test.ts — zero findings.
  • Prettier and git diff --check passed for all changed files.
  • pnpm run docs check reaches the checker but reports only pre-existing broken links into unavailable local submodules; this change adds no documentation error.
  • Full workspace typecheck is deferred to CI because this nested worktree intentionally has no dependency installation; borrowed dependencies are not version-aligned enough for a reliable workspace result.

Context handoff

Instructions for reviewing agents

  • Review focus: Verify direct-child discovery, child-first/root-last metadata ordering, compensation ordering, and the terminal post-commit boundary.
  • Decisions to challenge: Confirm the weaker transaction-free invariant is explicit and sufficient: root archived always implies every discovered direct child remains archived, including rollback failure.
  • Plausible failures / evidence gaps: The metadata query observes one repository snapshot boundary; concurrent child creation after that snapshot is outside [Bug] Archive can miss child Tabs before metadata cache hydration #574. Restore and archived-root deletion intentionally retain their current readiness behavior.

Authoring context

  • User goal / directives: Fix [Bug] Archive can miss child Tabs before metadata cache hydration #574 without the unbounded global metadata-readiness wait from fix: wait for metadata before archive cascade #577, then harden the archive commit against write failure.
  • Constraints / non-goals: Do not implement [Feature Request] Treat agent-opened sessions as supervised workers unless they are an explicit handoff #529 worker supervision or expand lifecycle ownership through openedBySessionId.
  • Risk-bearing decisions: There is no cross-document transaction. Ordering and compensation enforce the issue invariant, while rollback failures remain visible to the caller.
  • Destructive or irreversible behavior: Terminal cleanup begins only after durable metadata commit. A metadata failure performs compensation and closes no terminals.
  • Deliberately not done or tested: Concurrent child creation after the query snapshot, restore readiness, and permanent-delete readiness are unchanged.
  • Unknowns / confidence: Focused behavioral coverage includes production scan semantics, rejected writes before and after local acceptance, rollback failure, and both workspace-switch boundaries.

Discover archive targets from the repository metadata index before any state writes, while preserving rendered-root fallback and direct-child-only lifecycle ownership.

Closes #574

Model: gpt-5
@wibus-wee wibus-wee changed the title fix(components): query complete metadata before archive fix(components): make archive cascade hydration- and failure-safe Sep 13, 2026
Propose immutable lifecycle operations, durable recovery, and atomic metadata projection to replace archive snapshot compensation. Add the bilingual contract and decision note, implementation gates, and a reproducible dependency probe.

Validation: dependency probe, targeted Prettier, and diff checks pass. Full pnpm check and format cannot start because corepack is unavailable. Docs check retains 20 pre-existing links into missing submodules.

Model: gpt-5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Archive can miss child Tabs before metadata cache hydration

1 participant