Comments and prose only, no code change (DECOUPLE-go-base-mentions.md sections B and C, outside
library/ and README.md): stack-demo's page-flow note becomes 'a normal host page', the share-link
and CORS comments say 'the live test host', embeddability.md's Traefik note says 'a self-hosted
reverse proxy' and drops the internal proxy file path, and how-to's hosting option becomes 'a Git
host you run (for example Forgejo)'. stack-demo.vue's @description feeds the generated tree, so the
landing regenerates the tree. Section A (QA widget), library/ and package.json are left to studio.
The gallery is going onto the DX-life research page, and nothing had tried
it on a page it didn't generate. From a second origin, a bare
<script> + <doxa-maps-spa> drew over the host's header, and 8 of 13 tabs
showed an error card.
Three causes, each fixed in the shell:
- No :host box. The layout root is position:absolute, so it anchored to the
viewport instead of the element. :host is now a positioned block with a
default height the host can override.
- A foreign page sets none of the globals a leaf page bakes. Every data call
hit the host's own origin and got HTML back. The manifest now publishes a
`runtime` block (apiBaseUrl + the public token every leaf already carries).
The shell fills window.MAP_APP_API_URL / window.MAP_TOKEN only when the page
hasn't set them, and forwards tk in profile-config.
- Nested elements resolved assets to <tree>/../assets, a sibling pool the
publisher doesn't ship (404 live). The shell now forwards an absolute
<tree>/assets. This also fixes the iframe mode, where Cities with Internet
and Gospel Resources were failing the same way.
Also adds a `tab` attribute (plus ?tab=) to deep-link into one map, and a
`tab-change` event for the host.
check:gallery-embed drives every tab in both modes from a second origin. It
passes here and fails on the previous tree (7 findings).
EMBED.md documents the contract. The Traefik template now sends CORS for the
whole tree: live manifest.json answers without Access-Control-Allow-Origin.
Three docs still told a reader to start a server on every interface: the
reference recipe for the share round-trip, the quoted scripts block, and
app-wrappers.md. Agents followed those recipes faithfully, which is how twenty
publicly bound http.server processes accumulated on this box. All three now
bind 127.0.0.1. check:quoted-scripts caught the second one on its own.
Also adds the gate-authoring constraint that just broke a build. Plugin and
library source is written for Vite, not Node, and fails two ways: the @map
alias is unresolvable (hit first), and import.meta.glob is undefined in 18
files including 11 of the 20 plugin index.js. A new check:facet-cascade
imported the dashboard config, reached library/colors/_registry.js
transitively, and threw -- while already wired into build:unlocked, so the
build failed for a reason unrelated to the code being built.
The counts in that section were measured, not estimated. A first draft said
"every plugin index.js" and the real number is 11 of 20; it also blamed the
glob when the first error is actually the alias.
States the two rules that follow: build:unlocked is only for gates that run
clean in plain Node with no browser and no network, and a gate gets run before
it gets wired in -- a broken gate in the build chain is worse than no gate,
because it goes red for the wrong reason and trains people to skip the step.
Records the other box constraints that have each produced a wrong answer:
Node 20 (no fs.glob), bfs find rejecting relative -newermt, no hardware WebGL,
and bunx not existing.
Driver 2026-09-21: 'a folder called deployment which will store the capacitor
folder, wordpress folder and tauri folder', and 'a folder called documentation
to store the contributing folder so docs are in one place'.
docs/ + contributing/ + CONTRIBUTING.md -> documentation/ (three doc homes into
one). capacitor/ + wordpress/ + src-tauri/ -> deployment/.
The public/ -> dist/ rename the Driver asked about is NOT here: after seeing the
measured blast radius (855 tracked files, 54 source refs, and public/ is the
served web-root four consumers point at) the Driver withdrew it - 'keep the
public folder the same'.
Path references were rewritten mechanically (258 across 87 files), but three
classes needed hand fixes because a prefix regex cannot see them:
- join(ROOT,'docs',...) in 10 internal scripts - a quoted SEGMENT, not a prefix
- tauri frontendDist '../public' -> '../../public', since src-tauri is now one
level deeper; check:tauri caught this exactly as the card predicted
- the WordPress contract test's dirname(__DIR__,2) -> 3, same reason
Also reverted one over-reach: the rewrite renamed a FINDING-CATEGORY label
'docs' in public-hygiene-check.mjs, which is a rule name in its own header, not
a path.
Verified: full build ALL GUARDS PASS, SRI consistent; check:tauri, check:mobile
(cap sync + webDir OK), check:wp-embed, quoted-scripts, capability-citations,
capability-exemplars, library-index, public-hygiene, parse and drop all pass.