Skip to content

fix(reliability): contain collaboration awareness host failures #370

Description

@seonghobae

Current authoritative state

Protected shipped truth remains exact main@3b38ead2d00f44eb578d0689087b9293b3dabe1e. Canonical single-writer Draft PR #167 / branch fix/collaboration-awareness-bounds-20260811 owns this boundary. Current exact Draft head is d8407c5fc65027233c880cae2d1f2d14d5261d91; the repair is active-PR truth only and is not shipped on protected main.

Fresh comparison from protected main reports this long-lived branch as diverged, 54 ahead / 29 behind, with merge base 50ac98cfa0ad9e8dd75f93ca437a5679fed4d804 and 19 awareness/docs/test paths. The protected-main commits after that merge base include release/control-plane authority outside this branch. Do not treat this branch tree as protected-main truth or destructively reconcile it while #118 owns the release boundary.

The validated Inkspan-owned failures are all inside the collaboration-adapter containment boundary: host-supplied provider.awareness and structural awareness members could throw caller-controlled/private values while Inkspan checked compatibility or acquired the scoped source; countRemoteCollaborators() could leak failures from host-owned clientID / getStates(); scoped-provider disposal could abort later listener detachments and leak a private host cleanup failure if one off(...) call threw; and direct scoped on(...) / off(...) operations could leak private host callback failures. Registration had an additional false-success defect because the wrapper was committed to Inkspan's local map before host registration succeeded, making a later retry return early even though the host never registered the listener. Provider transport, Yjs authority, persistence, auth, tenancy, credentials, durable audit, deployment and model policy remain host-owned.

Repair and executable contract

  • Test-first predecessor 7209a86d45908ab9bd9118591445ac6cf666cf49 added a provider whose first awareness read is valid and whose second read throws a private sentinel; that generation was superseded/cancelled, so no hosted RED is claimed.
  • Source repair eda95121085bfd42c14756002b7c531b88b008ae centralizes capability acquisition in readCompatibleCollaborationAwareness(). Provider awareness access and structural compatibility reads execute inside one fail-closed boundary and normalize failures to exact collaboration provider must expose a compatible Yjs awareness instance without reflecting the private value.
  • de6f54b44fa9b7f771784c9f6635a451374b3029 adds a structural-member regression whose clientID getter throws a private sentinel and proves the validator returns a stable module-owned payload-redacted error.
  • Test-only successor f07819b4252a0735cbe41619ef3c9117d5b7dc44 adds count-path regressions requiring hostile getStates() and clientID failures to return 0 without exposing the thrown value. Source repair 6a01457ad7a044405a100a5b563f1b718fe3d220 contains that host-owned count operation while preserving descriptor-safe remote identity validation.
  • Cleanup RED d14dcd5aa935e21a3e7d10c12797f5ee8863b1b4 requires a throwing host change detachment not to prevent update detachment, not to leak the private sentinel, and to leave repeated disposal idempotent. The production predecessor deterministically violates that contract; the immediate repair superseded hosted RED generation, so no hosted RED is claimed. GREEN a03c7d04a11f7d7c7274e466247b38057fc19bb7 isolates every host disposal off(...) attempt, continues remaining cleanup, clears local wrapper state and contains the private teardown failure.
  • Listener-operation RED commits be5e0a1a1d87a297160a259d3df24cca90c0ca47 and 3694bfaafc96501c0e164668a43870568ee74ce9 require exact module-owned registration/removal errors plus real retry behavior after host rejection. Their hosted generations were superseded/cancelled by the immediate narrow repair, so no hosted RED is claimed; the predecessor source deterministically fails because it inserts registration state before calling host on(...) and directly propagates host on(...) / off(...) exceptions.
  • Current GREEN d8407c5fc65027233c880cae2d1f2d14d5261d91 commits registration state only after successful host on(...), retains wrapper state after rejected host off(...), and normalizes those failures to collaboration awareness listener registration failed / collaboration awareness listener removal failed without reflecting the private host value.
  • Ordinary compatible awareness shapes, valid listener behavior, the established incompatible-shape diagnostic, WCAG cursor presentation, package behavior and standalone no-service operation remain unchanged. No provider lifecycle or transport authority moved into Inkspan.

Exact-current-head evidence

For unchanged current head d8407c5fc65027233c880cae2d1f2d14d5261d91 at the latest fresh refetch:

  • CI 32221759117: completed / success, including typecheck, exact 100% root test coverage, package consumer verification, demo build, Office Python 3.11–3.14, and Playwright 1.62.0 cross-engine clipboard evidence;
  • Security Scan 32221759122: completed / success;
  • SAST Semgrep 32221759109: completed / success;
  • formal submitted reviews: 0;
  • unresolved review threads: 0;
  • GitHub reports the Draft mechanically mergeable.

Repository exact-head technical success is not qualifying independent approval and does not replace separately applicable central workflows or live governance. Predecessor, pending, queued, in-progress, skipped, cancelled, absent, stale, status-only or model-only evidence remains non-passing.

Integration boundary

The behavior is repaired on active Draft #167 but is not protected-main shipped behavior. Keep this issue open until #167 integrates under then-live governance. Keep #167 Draft/unmerged while #118 owns the frozen v0.6.0 release boundary. Draft #228 separately owns direct CollaborativeCwlEditor.tsx host-awareness interactions and is complementary rather than a competing writer. Before any lifecycle transition refetch exact head/live base, ancestry/mergeability, formal reviews/threads, live governance and every applicable repository/central workflow. Do not create a competing collaboration-awareness writer, transfer predecessor evidence, self-approve, weaken gates, move protected main, fabricate release identity, or represent active-PR repair as protected-main behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: accessibilityAccessibility and assistive-technology supportarea: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: bugDefect or incorrect behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions