Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ verified in their own repositories.

## Current compatibility

- package version: `0.4.11`;
- package version: `0.4.12`;
- session JSON schema: `7`;
- fingerprint schema: `6`;
- minimum Dart SDK: `3.9.2`;
Expand Down
4 changes: 4 additions & 0 deletions docs/integration/production-replay-acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Do not start the production cohort until every item is true:

- all behavioral replay-correctness PRs are merged to `main`;
- the navigation and interaction race matrix passes on the merged commit;
- the modal visual matrix, programmatic navigation matrix, navigation-origin
contract, and tap coordinate transform suites pass;
- the production dashboard deployment consumes `captureCoordinate` (canonical
marker projection) before Blend canary sessions rely on it;
- `flutter analyze` and the complete `packages/tugboat` test suite pass;
- `packages/tugboat/pubspec.yaml` and
`packages/tugboat/lib/src/sdk_version.dart` contain the same new version;
Expand Down
23 changes: 22 additions & 1 deletion packages/tugboat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
## Unreleased
## 0.4.12

### Added

- **Navigator and route-instance ownership** — every observed Navigator gets a
session-local opaque `navigatorId`; every pushed route gets a
`routeInstanceId`. Stacked anonymous modals stay distinguishable.
Install nested observers with `TugboatReplay.createNavigatorObserver()`.
- **Navigation origin contract** — `route_change` events carry
`navigationOrigin` (`interaction` | `automatic_or_unknown`) and optional
`causeEventId`. Only observer-time single-use pending-interaction claims can
bind a tap; timer/auth redirects never fabricate causality.
- **Versioned `captureCoordinate`** — taps retain legacy global `x`/`y` and add
a boundary-local / normalized / raster transform bound to the before-frame.
Outside-boundary and generation-mismatch cases emit an unavailable reason
instead of clamping.
- **Replay coherence characterization harness** — deterministic, advanceable
scheduler/capture test seams (`debugNow`, `debugDelay`, `debugExecuteCapture`,
`debugSeedFrame`) plus reusable helpers that reproduce known navigation/frame
Expand Down Expand Up @@ -38,6 +50,15 @@

### Changed

- **Tap/navigation causality fence** — tap settlement joins a route-capture
barrier only when that route explicitly claimed the same tap event.
Automatic redirects that overlap settlement, including successors of a
tap-caused route, remain independent and cannot donate their frame or route
event ID to the tap.
- **Frame-owned coordinate geometry** — frame provenance now retains the
capture boundary's logical rect and transform generation. Resizes, rotations,
and inset changes invalidate stale before-frame attachment and emit
`generation_mismatch` instead of projecting a current tap onto older pixels.
- **Replay capture contract documentation** — documents the implemented route/frame
attribution invariant separately from the still-open production acceptance
gaps for rapid modal chains, automatic navigation, and playback tap-coordinate
Expand Down
15 changes: 12 additions & 3 deletions packages/tugboat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ checkpoints around meaningful interactions, compact structural anchors, route
transitions, scrolling evidence, and optional viewport semantic maps. Capture
can be sent to the local exploration WebSocket, the HTTP collector, or both.

The current package version is `0.4.11`. Session JSON uses schema version `7`
The current package version is `0.4.12`. Session JSON uses schema version `7`
(readers still accept `6`), and structural fingerprints use fingerprint schema
version `6`.

Expand Down Expand Up @@ -39,8 +39,17 @@ MaterialApp(
```

Without `TugboatReplay.navigatorObserver`, pointer and scroll capture still
work, but route-change events and route-backed anchors are incomplete. Without
`wrapApp`, no capture controller, repaint boundary, or input/scroll listener is
work, but route-change events and route-backed anchors are incomplete. Nested
Navigators that must be attributed need their own observer instance:

```dart
Navigator(
observers: [TugboatReplay.createNavigatorObserver()],
// ...
);
```

Without `wrapApp`, no capture controller, repaint boundary, or input/scroll listener is
installed.

### Navigation and overlays
Expand Down
4 changes: 3 additions & 1 deletion packages/tugboat/lib/src/collector_mapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ Map<String, Object?> mapTugboatEventToCollectorEvent({
}

/// Immutable build identity required for Context Graph matching.
Map<String, Object?> collectorEventBuildIdentity(TugboatCollectorConfig config) {
Map<String, Object?> collectorEventBuildIdentity(
TugboatCollectorConfig config,
) {
return {
'appId': config.appInfo.appId,
'platform': config.deviceInfo.platform,
Expand Down
Loading
Loading