Known Issues And Open Decisions
Open decisions from the 2026-06-10 seam review
Analysis provenance can embed internal editor UUIDs in exported output layers
- Where:
provenance_feature_id and start_feature_label in crates/gis_core/src/project_store.rs (~16435-16477).
- Behavior: analysis output properties (for example
source_network_id, reached-target input-id columns) fall back to the internal editor feature UUID when the source feature has no original GeoJSON id. Those properties then export verbatim. The doc comments make this an explicit exception to the “no editor IDs in exports” rule.
- Decision needed: accept and document FIDs as user-visible identifiers (they already appear in the UI in SF Mono), or substitute a per-run ordinal/label when the source has no id. No change made pending a decision.
- Where:
csv_escape in crates/gis_core/src/project_store.rs (~8210).
- Behavior: RFC-4180 quoting is correct, but values beginning with
=, +, -, or @ open as live formulas in Excel/Numbers. Neutralizing (prefixing ') would mutate user data in an interchange format; leaving it matches common GIS tool behavior (QGIS exports raw values).
- Decision needed: keep raw values (document the risk in the user guide) or neutralize on export. No change made pending a decision.
Deferred robustness notes (documented, low priority)
- Field calculation values are computed from candidate rows read before the commit transaction; a write landing between evaluation and commit (only possible through detached-task seams outside the actor) could persist a value computed from stale inputs. Bounded today by
LiveProjectService actor serialization.
- Markup export ships the full
gispad_markup style envelope by design (test-asserted). The schema reserves author/device fields that are always nil today; if they are ever populated, markup export needs a scrubbing step in the privacy scan.
gis_core_project_free_string and the Debug-only benchmark FFI entries in lib.rs are not panic-guarded (all 97 functional entries are, via ffi_result).
Accessibility-tree follow-ups from the 2026-06-10 UI suite triage
AeroIconButton exposes its accessibilityIdentifier on a wrapper Other element rather than the inner Button (for example workspace-labels-button, workspace-guide-button, location-control-button). UI tests now query via descendants(matching: .any); a cleaner fix is combining the icon button into a single accessibility element so VoiceOver doesn’t see a container plus an unnamed button.
- The hidden keyboard-shortcut buttons in
WorkspaceView.keyboardShortcuts carry .accessibilityHidden(true) but still appear in XCUITest queries as 1-pt buttons (for example a degenerate “Join” at the screen edge). Label-based firstMatch taps in UI tests must scope to the owning panel. If more collide, consider moving shortcuts to UIKeyCommand/.commands so they never materialize as views.
- Container
.accessibilityIdentifier(...) without .accessibilityElement(children: .contain) flattens every child identifier. Fixed 2026-06-10/11 on attribute-table-sheet, app-settings-overlay, join-pane, workspace-finder, field-calculator-pane, analysis-panel, multi-selection-mode-control, workspace-search-result-row, and workspace-bookmark-row; new panel containers must follow the contain-then-identifier pattern.
- Confirmation dialogs must capture their payload when the dialog content builds (
if let confirmation = model.pending... { Button { ... confirm(confirmation) } }). The isPresented binding’s set: { if !$0 { cancel() } } runs on dismissal before the button’s Task, so guard-on-pending confirm functions silently no-op. Bookmark and markup delete were broken this way (fixed 2026-06-11); layer delete already used the capture pattern. Audit any new confirmationDialog against this.
- XCUITest quiescence stalls (10+ minute synthesized-event timeouts) occur after camera animations while a location fix renders the puck. UI tests that navigate the camera should pin
GISPAD_UI_TESTS_LOCATION_UNAVAILABLE=1 unless they test location chrome.
- Label text-pixel assertions cannot pass under the in-memory UI-test fixture: label features flow only through the package-backed Rust
queryLabelViewport, which the fixture cannot serve. Label visual QA is physical-device scope.