* test(#3566): pin per-install .gsd-runtime marker precedence in the isolation guard
Failing-first regression for #3566: resolveRuntimeIdentity must consult the
per-install marker (<install>/gsd-core/.gsd-runtime, written by every install
since #2297) above the host-wide ~/.gsd/defaults.json whose leakage #2840
exists to prevent. In-process block drives the marker through the same
_setInstallRuntimeMarkerForTests seam model-resolver.cts established.
* fix(#3566): read the per-install .gsd-runtime marker above host-wide defaults in the isolation guard
resolveRuntimeIdentity consulted ~/.gsd/defaults.json — the exact host-wide
file whose runtime leakage #2840 exists to prevent — and never the
per-install marker the installer has written for every runtime since #2297.
On a 2-runtime machine the guard confidently resolved the WRONG runtime and
silently went inert when that runtime declares no harnessIsolationFlag.
Precedence is now GSD_RUNTIME > config.json runtime > .gsd-runtime marker >
defaults.json, restoring #2840's design; the defaults rung stays last so
single-runtime and pre-#2297 installs keep #3045 BLOCKER 2 behavior.
* fix(#3566): apply the marker rung to the cursor subagent-start fallback; review fixes
Review finding (spec pass): hooks/gsd-cursor-subagent-start.js's
resolveFallbackIsolation mirrored the Claude hook's exact three-rung chain
and shared the bug — same rung inserted between config.json and the
host-wide defaults, same #2297-pattern seam, in-process regression +
negative controls.
Review finding (standards): dropped the one new raw-text assert.match on
the block reason (CONTRIBUTING test-output rule); the reason-naming
property stays pinned by the pre-existing #3045 row.
* chore(#3566): add changeset fragment
* chore(#3566): backfill changeset pr number
---------
Co-authored-by: sim <sim@local>