From 45a33b54df3ee368e69a00ce21ad7d5996f74979 Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Wed, 11 Nov 2026 13:44:49 +0400 Subject: [PATCH] Street Level: docs for the OPEN exception, panel freshness and what stops a request - SECURITY.md: OPEN also takes the link's point when the screen centre cannot be picked at all. - TOOLS.md: the panel's own link opens Street View only for a result issued in the last five minutes; an older one only arms. - Changelog: the hiding modes stop a request, collapsing the panel does not; failure cards are in the interface language. - CURRENT-STATE: a posted view without a point grounds its look-at too. --- SECURITY.md | 2 +- changelog.d/1113-show-street-level.md | 9 ++++++--- docs/CURRENT-STATE.md | 7 ++++--- docs/TOOLS.md | 6 ++++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 4316f522f..43ee7b6bd 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -132,7 +132,7 @@ God's Eye View's tools are also served to MCP clients: over stdio (`npm run mcp` - **What the panel's requests can reach.** In clients that display MCP Apps, the panel loads the app through the `panel_request` tool, which requests paths on the app's server. It is marked for the panel only and requires a key that each MCP server puts in its panel page, which keeps it from clients that list tools to the model without loading the panel. That key is not access control: any MCP client can read the panel page, key included, and then reach the app's files and data routes through `panel_request`, much as its other tools reach the data. Provider Settings, credential and model endpoints, `/mcp` and the development server's internal routes are refused to every caller. - **The panel carries the two browser keys.** The panel build (`npm run build:panel`) includes the same Google Maps key and Cesium ion token as the app, and they run inside the client's panel page, on the client's site. A key restricted by HTTP referrer must also allow that page, or the panel cannot load tiles. To keep the app's own keys narrower, build the panel with separately restricted keys in the environment of `npm run build:panel`. - **Embed mode is not framable by default.** `?embed=1` documents keep `X-Frame-Options: DENY` and `frame-ancestors 'none'` unless `GEV_EMBED_FRAME_ANCESTORS` names the pages that may frame them; a framing page can change what the app shows. Other documents can never be framed. -- **A plain link never loads a billed Street View panorama without a click.** A share link with `sl=google,,` flies there, switches to Google 3D and lights Street View, then stops: the panel is armed and the photo loads only when the visitor presses OPEN GOOGLE STREET VIEW (one lookup and one panorama load on the browser Maps key, no retries, no geocoding or server call). A view posted into the embedded app (the God's Eye View panel, or a page `GEV_EMBED_FRAME_ANCESTORS` allows), and the panel page's own opening link for a tool result issued in the last five minutes, are that client's own request and open the photo; freshness is judged only by the result's `issued_at`, so a result older than five minutes only arms, whether the panel was mounted again (reopening a conversation) or got it later on the same mount, while one re-sent or remounted within five minutes of issue opens the photo again; adding `?embed=1` to a published link does not lift the gate (in a frame the link only arms; the panel that holds OPEN is hidden there, so a posted view is the way to open a photo). The OPEN press uses the link's point only while the ground under the screen centre is within 1 km of it; with the sky in the middle it opens nothing. The armed lookup dies when its source is switched off, when its map leaves, or when any other photo opens or closes. A link pasted into an open tab follows the same rule, and a link's source switch and layer are never saved as the recipient's own preferences. A link that follows an entity ignores `sl`. Mapillary, KartaView and Panoramax links open their photo at once; none of them bills per image. +- **A plain link never loads a billed Street View panorama without a click.** A share link with `sl=google,,` flies there, switches to Google 3D and lights Street View, then stops: the panel is armed and the photo loads only when the visitor presses OPEN GOOGLE STREET VIEW (one lookup and one panorama load on the browser Maps key, no retries, no geocoding or server call). A view posted into the embedded app (the God's Eye View panel, or a page `GEV_EMBED_FRAME_ANCESTORS` allows), and the panel page's own opening link for a tool result issued in the last five minutes, are that client's own request and open the photo; freshness is judged only by the result's `issued_at`, so a result older than five minutes only arms, whether the panel was mounted again (reopening a conversation) or got it later on the same mount, while one re-sent or remounted within five minutes of issue opens the photo again; adding `?embed=1` to a published link does not lift the gate (in a frame the link only arms; the panel that holds OPEN is hidden there, so a posted view is the way to open a photo). The OPEN press uses the link's point only while the ground under the screen centre is within 1 km of it, or when the screen centre cannot be picked at all (no ground picking, or a globe with no size yet); with the sky in the middle it opens nothing. The armed lookup dies when its source is switched off, when its map leaves, or when any other photo opens or closes. A link pasted into an open tab follows the same rule, and a link's source switch and layer are never saved as the recipient's own preferences. A link that follows an entity ignores `sl`. Mapillary, KartaView and Panoramax links open their photo at once; none of them bills per image. ## Scope & expectations diff --git a/changelog.d/1113-show-street-level.md b/changelog.d/1113-show-street-level.md index 523fe5773..233a6bd16 100644 --- a/changelog.d/1113-show-street-level.md +++ b/changelog.d/1113-show-street-level.md @@ -8,8 +8,11 @@ View and leaves the load to OPEN GOOGLE STREET VIEW; embedded views open it, and so does the God's Eye View panel for a result issued in the last five minutes; a link whose source has no working key says so. A request stops - when the user navigates or hides the panel before its photo loads; a new - photo replaces the open one in place, so EXPAND stays. When nothing is found and a 360°, flat or SINCE filter is on, the - answer names the filter. An unavailable map stack now reports the + when the user navigates, or enters cockpit, clean view, recording or scene + playback, before its photo loads (collapsing the panel does not stop it: the + photo reveals it); a new photo replaces the open one in place, so EXPAND + stays. When nothing is found and a 360°, flat or SINCE filter is on, the + answer names the filter. Failure cards are in the interface language. An + unavailable map stack now reports the controller's own reason instead of always asking for a Cesium ion token (Said Turksever, @asturksever, #1113). diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 0e92438e5..0c3577644 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -5315,9 +5315,10 @@ a point, which defaults to where the camera looks (below 20 km, at a pitch steeper than -5° and within 10 km ahead; else the camera's own point, also for half a point). A `google` source brings `map: photoreal` and refuses another map; `street_level` does not combine with `follow`. -`show_in_gods_eye_view` measures a view's altitude from the terrain under the -camera (`services.terrain`) before taking the look-at point, and keeps the -view's own estimate without a terrain answer. Links carry +`show_in_gods_eye_view`, and the embedded app for a posted view with no +point, measure the view's altitude from the terrain under the camera +(`groundedLookAt` with the terrain heights service) before taking the look-at +point, and keep the view's own estimate without a terrain answer. Links carry `sl=,,`; the globe panel applies views through the action, and a plain link runs it once restored (one shot: the rewritten hash drops `sl`). A link that follows an entity ignores `sl`. diff --git a/docs/TOOLS.md b/docs/TOOLS.md index 1a95d2656..a6d501c8c 100644 --- a/docs/TOOLS.md +++ b/docs/TOOLS.md @@ -110,8 +110,10 @@ shows only on the Google 3D map, so a `google` source sets `map` to photos. Links carry it as `sl=,,`: once restored, the app runs `show_street_level`, which flies there and opens the nearest photo. A plain link with a `google` source only arms the panel for OPEN GOOGLE STREET -VIEW; a view posted into the embedded app, or the panel page's own opening -link, opens it, and `?embed=1` on a published link does not. Mapillary, +VIEW; a view posted into the embedded app opens it, and so does the panel +page's own opening link, but only for a tool result issued in the last five +minutes (an older one, such as a host remounting the panel, only arms); +`?embed=1` on a published link does not. Mapillary, KartaView and Panoramax, which do not bill per image, open at once. A link that follows an entity ignores `sl`.