# BF35 / TX7.2.1 Collaborative Review Hardening implementation state

Date: 2026-08-22
Release: R14.28.16 Build Fix 35

## Objective

Harden BF34/TX7.2 collaborative Comments and Track Changes without changing the TX7 manuscript authority. `Y.Text` remains the only live collaborative text authority; review state remains shared metadata beside it and never becomes `.tex` content or Y.Text formatting attributes.

## Hardening completed

- Review anchors are now valid only when both encoded `Y.RelativePosition` endpoints resolve into the exact collaborative `Y.Text` named by `filePath`; cross-file/malformed anchors are rejected.
- Coalesced tracked-change metadata updates are wrapped in one Yjs transaction instead of emitting several partial metadata transactions.
- Review-store observer notifications are microtask-batched so one logical Yjs transaction produces one UI snapshot refresh.
- TX7 text protocol compatibility is separated from shared-review capability compatibility. BF35 advertises `shared-review-v1`, schema version 1, and relay rooms are partitioned by review capability version so BF34-era clients cannot silently join a TX7.2.1 review room without understanding pending review state.
- Review schema/capability metadata is stored in project meta, awareness identity, reconnect metadata and deployed collaboration health checks.
- Collaborative mutation transactions now carry `source`, `semanticKind` and `operationId` metadata for AI, citation, Paper Memory, TikZ, terminal, toolbar/research/project-tool edits.
- Undo/Redo review reconciliation is correlated through Y.UndoManager stack-item metadata containing exact tracked-change IDs and snapshots, replacing the earlier broad pending-change scan heuristic.
- Source conflict decorations now have an explicit conflicted class/style while retaining collaborator provenance color.
- Review UI adds `All / Comments / Changes` counts/filters and `Reject all by author` alongside existing bulk review operations.
- Live Learn documentation now states that Source comments and Track Changes are collaborative while Visual editing remains disabled during live collaboration.
- Dormant Visual-collaboration cursor/authorship APIs and CSS were removed; ordinary local Visual Review behavior remains.
- Collaborative review now has aggregate bounds for thread/change counts, reply bodies/counts and approximate active snapshot bytes, plus resolved-history compaction that always preserves pending changes and unresolved comments.
- The local-projection versus collaborative-live Review backend contract is explicit in `project-review-backend.ts` and exported through service-core.
- The formal browser soak contract now combines 10,000 manuscript edits with 500 tracked changes and 200 comment/reply/resolve operations plus reconnect convergence invariants.

## Preserved architecture

```text
CodeMirror
  ↕
y-codemirror.next
  ↕
Y.Text
  ↕
y-websocket

Project Y.Doc
├── files → Y.Map<Y.Text>
├── review-comments → Y.Map<Y.Map>
│   └── replies → Y.Array
├── review-changes → Y.Map<Y.Map>
└── review-events → Y.Array
```

Remote cursors remain owned exclusively by `y-codemirror.next` Awareness. Review metadata never uses the retired BF31 cursor/authorship CRDT path.

## Compatibility boundary

`COLLABORATION_PROTOCOL_VERSION` remains 7 for the manuscript transport. Collaborative Review compatibility is independently advertised as:

```text
reviewSchemaVersion = 1
capability = shared-review-v1
review capability version = 1
```

The signaling relay scopes live Yjs and payload-transfer rooms by the review capability version. A legacy client that does not advertise BF35 review capability therefore cannot silently participate in the same live review state.

## Review bounds and lifecycle

Current shared-review limits include bounded IDs/names/paths/timestamps/text, 8 KB reply bodies, 500 replies per thread, 2,000 comment threads, 5,000 change records and an 8 MiB approximate review snapshot ceiling. Resolved comments/changes are compacted to bounded recent history while pending changes and unresolved comments are retained.

Review state remains in the same Y.Doc and therefore continues to use the existing y-indexeddb, websocket reconnect and host outbound-drain lifecycle. There is no second review synchronization engine.

## Verification

Dependency-free results from the BF35 source tree:

- BF35 regression/source guard: 16/16 PASS.
- BF34 collaborative-review regression: 14/14 PASS.
- Historical R14.28.14 regression: 22/22 PASS.
- Runtime hardening: 101/101 PASS.
- Repository static release audit: 352/352 PASS.
- SaaS/product/security static audit: 43/43 PASS.
- Dependency-free native server/script Node batch: 86/86 PASS.
- Template/compiler requirements: 13/13 PASS.
- Frozen lock: 69 workspace importers and 1171 reachable snapshots PASS.
- Workspace dependency consistency: 68 packages PASS.
- Public barrels: 67 public entries across 68 workspace packages PASS.
- BF35 Typecheck Hotfix 1: conflicted-change restore captures narrowed `from`/`to` offsets before the Yjs transaction callback, preventing TS18048/TS2345 under strict `tsgo`.
- BF35 Lint Hotfix 2: Review status/type controls use `role="group"` before `aria-label`, satisfying Biome `lint/a11y/useAriaPropsSupportedByRole`.
- 24 changed TS/TSX files parse/transpile with TypeScript 5.8.3.
- Changed JS/MJS syntax and deployment shell syntax PASS.

Production installer evidence confirms dependency-backed custom validation and `tsgo`/mobile-entry typecheck pass through the BF35 Typecheck Hotfix 1. The next dependency-backed gate, Biome, then exposed one accessibility error on the Review item-type filter (`aria-label` on a generic `div`); Hotfix 2 adds the supported `role="group"` semantics and regression guard. Full dependency-backed Biome after Hotfix 2, Vitest, Vite production build, Playwright execution, the executable 10k/500/200 browser soak and deployed relay certification remain external gates until rerun in the installed production environment.
