Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fc259af
Harden merge workflows with routing integrity checks
trevorgerhardt Jul 21, 2026
d861c39
Expand Osmix functionality and supporting tests
trevorgerhardt Jul 21, 2026
6b2bc04
Clarify conflation safety boundaries and recovery behavior
trevorgerhardt Jul 21, 2026
4b1fd4a
Set accessibility-focused default conflation property keys
trevorgerhardt Jul 21, 2026
06cea37
Add filter-wide conflation decision actions
trevorgerhardt Jul 21, 2026
6106c6f
Remount map sources when dataset identities change
trevorgerhardt Jul 21, 2026
2944885
Handle pending conflation filter updates
trevorgerhardt Jul 27, 2026
9c7cdfc
Fix intersection topology and canonical OSM entity ordering
trevorgerhardt Jul 27, 2026
719dc09
Clarify merge workflow guidance and review stages
trevorgerhardt Jul 28, 2026
a2e7a91
Add accessible info tooltips to merge guidance
trevorgerhardt Jul 28, 2026
6142f20
Move conflation guidance into info tooltips
trevorgerhardt Jul 28, 2026
95df846
Add automatic merge progress and base OSM loading
trevorgerhardt Jul 28, 2026
b84a10b
Integrate live task feedback into merge progress
trevorgerhardt Jul 28, 2026
b7847c8
Allow skipping optional merge diagnostics
trevorgerhardt Jul 28, 2026
20541ca
Improve merge OSM file cards and loading tests
trevorgerhardt Jul 28, 2026
a5dc687
Contain merge workflow actions in responsive step footers
trevorgerhardt Jul 28, 2026
26eaa8d
Speed up Merge browser tests
trevorgerhardt Aug 5, 2026
66f5280
Stabilize fixture-heavy tests
trevorgerhardt Aug 5, 2026
d7ec2a7
Wait for Merge worker readiness
trevorgerhardt Aug 5, 2026
d601f04
Use the tracked Monaco fixture in CI
trevorgerhardt Aug 5, 2026
5f9b910
Run Merge browser projects in order
trevorgerhardt Aug 5, 2026
c7deefb
Improve merge workflow handling and coverage
trevorgerhardt Aug 11, 2026
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
24 changes: 24 additions & 0 deletions .changeset/safe-merges-route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
"@osmix/change": patch
"@osmix/router": patch
"osmix": patch
---

Preserve input topology during merges, conservatively reconcile compatible patch entities with the base,
validate routing-sensitive references, and insert multiple intersections in way order. Within-file duplicate
scans in the Merge app are now diagnostic only; regenerate older merged PBFs from their source inputs. Correct
the router priority queue so shortest-path searches visit lower-cost states first, and honor the one-way
direction implied by OSM roundabouts plus reverse one-way (`oneway=-1`) tags.

Restore the original 1-meter matching behavior as explicit, cross-dataset fuzzy conflation for imported data.
Callers select transferable properties independently from patch-network attachment; exact merge behavior
remains the default. Unique, high-confidence pedestrian and one-to-one-way matches can apply automatically,
while routing properties, motor roads, ambiguity, relation involvement, and uncertain geometry require review.
Grade conflicts, restrictions, protected tags, dangling references, way collapse, and base-topology rewrites
remain blocked. Add public candidate/evidence/decision APIs, restart-safe worker review sessions, CAR/WALK
topology diagnostics, and a dedicated Merge-app review step.

Add atomic, filter-wide conflation decisions with worker-computed previews. The Merge app can transfer
properties, attach networks, or reject every candidate matching the current filters across all pages, while
showing skipped ambiguity and overwritten decisions before confirmation. Accepted candidates now have a stable
summary and filter status, and complete bulk decision snapshots remain restart-safe.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ const mergedOsm = await merge(osm, patchOsm);
console.log(mergedOsm.id);
```

The high-level merge preserves each source dataset and only reconciles compatible entities across the base
and patch. If a PBF was produced by an older release that automatically deduplicated within each input,
regenerate it from the original source files rather than trying to repair rewritten routing topology.

Imported datasets with sub-meter coordinate offsets can opt into safe fuzzy conflation. The explicit
`conflation` configuration restores the historical 1-meter search while separating selected-property
transfer from patch-network attachment. High-confidence matches may apply automatically; ambiguous,
routing-affecting, relation-involved, or structurally uncertain candidates are reviewable or blocked. Exact
merge behavior and empty-merge identity remain unchanged when conflation is not configured.

### Use in a Web Worker

```ts check-docs monaco-pbf
Expand Down
99 changes: 99 additions & 0 deletions apps/merge/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ App-level helpers (`src/components/`):
long worker tasks.
- `Details`/`DetailsSummary`/`DetailsContent` — collapsible section; the
standard way to make a titled, togglable region.
- `InfoTooltip` — moves optional explanatory prose behind a compact,
keyboard-accessible information trigger. Keep essential labels and current
values visible.
- `MergeStepGuide` — the standard layered explanation at the top of each
numbered merge stage.
- `StepActions` — the full-width vertical action footer for Merge workflow
stages. It keeps long decision labels contained in the narrow sidebar.
- `ActionButton` — async button with spinner/transition handling.

When to use what:
Expand All @@ -105,6 +112,98 @@ When to use what:
wizard options).
- **Card** for titled sections in the sidebar blocks.

### Merge step actions

Use `StepActions` for navigation and processing choices at the bottom of a
Merge workflow stage. Step footers remain vertical at every sidebar width:
buttons fill the available width, labels may wrap, and long OSM terminology
must not force horizontal scrolling.

Place secondary actions first and the primary forward action last. Back, skip,
and "without" alternatives use the outline variant; preview, continue, apply,
and download actions use the default variant. Keep compact header actions,
candidate toolbars, and other non-footer controls in their existing horizontal
groups. Do not relax the global button primitive's single-line behavior to fix
a workflow-footer layout.

## Merge workflow guidance

Every merge stage must explain itself where the user makes the decision. Keep
the explanation layered so that experienced users can scan the workflow while
new users can inspect the consequences before applying anything:

1. Show one plain-language summary at the top of the numbered step card, before
controls or results.
2. Follow it with a collapsed **How this step works** disclosure using
`MergeStepGuide`. Do not duplicate these disclosures at individual call
sites; add or revise the app-private guide registry instead.
3. In the expanded content, identify the inputs being read, changes that may
occur, invariants the step preserves, and its output. Include a warning only
when the user can make an irreversible or topology-affecting choice.
4. Reset the disclosure when moving between steps. Opening help must never
change a form value, review decision, workflow state, or worker operation.

Use the merge terms consistently:

- **Base OSM** is the authoritative existing dataset whose identity and
untouched geometry are preserved unless a same-ID patch update explicitly
replaces them.
- **Patch OSM** contains imported additions and updates.
- **Direct merge** adds patch-only entities and applies same-ID updates.
- **Exact reconciliation** combines different IDs only when their serialized
coordinates or ordered geometry and routing context agree.
- **Imported-data matching** is the optional proximity workflow. **Property
transfer** copies only selected tag values; **network attachment** rewrites
only accepted references in patch-created ways.
- **Intersection creation** connects compatible same-grade crossings while
leaving ambiguous and grade-separated crossings disconnected.
- **Review each merge stage** exposes previews and checkpoints. **Run automatic
merge** skips those checkpoints and uses only behavior explicitly configured
for the automatic path.

Labels must state what a control changes instead of relying on a placeholder.
Put concise supporting text next to unfamiliar controls and connect it with
`aria-describedby`. Humanize internal status and reason-code values in visible
copy, but do not change the stable values used by workers or saved decisions.

`Details` is the shared disclosure primitive. Its open-state styles target Base
UI's `data-panel-open` attribute. Disclosure triggers remain keyboard
accessible, and decorative chevrons are hidden from assistive technology.

### Explanatory diagrams

Use a compact SVG only when topology or data flow is materially clearer as a
picture. Merge diagrams follow these constraints:

- Provide a fixed `viewBox` and responsive `width: 100%`; never give the SVG a
fixed rendered width that can overflow the sidebar.
- Give each diagram an accessible name and description with React
`useId()`-backed `<title>` and `<desc>` elements.
- Use semantic foreground, muted, info, success, warning, destructive, and
border tokens. Never encode meaning by color alone: pair colors with labels,
shapes, or solid/dashed line styles.
- Set connector strokes to `vector-effect="non-scaling-stroke"` so they remain
legible at narrow widths.
- Avoid animation and `<foreignObject>`. SVG text must remain understandable at
both 320 px and 512 px sidebar widths.

### Browser test boundaries

Keep the real Monaco Merge journey focused on integration behavior that needs
an actual parsed OSM and worker-backed merge. Load each input once, verify its
real metadata, and advance through the workflow without repeating presentation
checks that can run against production components in the lightweight guidance
harness.

Use that harness for responsive geometry, long-label and long-filename
containment, accessible control names, and controlled action-state transitions.
Run the real Merge journey, guidance harness, and worker-runtime coverage as
ordered Playwright projects. This prevents additional Chromium contexts or
intensive Web Worker activity from competing with MapLibre rendering and PBF
parsing on a small CI runner. The real journey uses one app worker; the
dedicated worker-runtime project retains single-worker, multi-worker,
replication, recovery, and disposal coverage.

## Loading, progress & status

- Quick/inline waits: `Spinner`.
Expand Down
Loading
Loading