Locks the lease broker's ENFORCEMENT half (launch-runtime.py) and ACTIVATION half (execLeaseGatedRuntime() / C1's LEASE_ACTIVATION_CAPABILITY) as one versioned unit, closing the #828 version-skew gap that C1 made observable but did not itself enforce.
What changed
New packages/mosaic/framework/tools/lease-broker/activation_version_gate.py:
EXPECTED_ACTIVATION_CAPABILITY — the ENFORCEMENT-side expected activation-capability constant (mirrors, but is a separate declaration from, C1's LEASE_ACTIVATION_CAPABILITY in lease-activation-probe.ts).
default_probe_activation_capability() — fail-closed subprocess probe of the CLI's hidden mosaic __lease-capability subcommand (the same mechanism C1's TS-side probe uses).
assert_activation_capability_matches() — raises VersionCouplingError with an actionable, #869-referencing remediation message on any mismatch (version OR name) or on an absent/unreadable capability.
launch-runtime.py now runs this assertion first, before any broker registration, and denies with a dedicated exit code (65) distinct from its existing usage-error (64) and registration-failure (1) codes. Clear stderr message, non-zero exit, never a silent pass, never a dead gate.
This is additive alongside — not a replacement for — the existing fail-closed-on-absent-identity gate locked in runtime_tools_unittest.py; that suite stays green (matching-capability fakes were injected into its pre-existing calls so the new gate doesn't interfere with what it already covers).
Tests (red-first)
New packages/mosaic/src/mutator-gate/version_coupling_unittest.py:
Module-level: matching capability passes; absent capability fails closed; version mismatch and name mismatch both fail loud with actionable messages; reversed-direction drift (newer activation than enforcement expects) also fails.
Seam-level (LAUNCHER.main()): matching version proceeds to registration/exec; mismatch/name-mismatch/absent all deny with the dedicated exit code and never reach broker registration or exec.
Verified genuinely red-first: with launch-runtime.py's wiring reverted, the 6 seam-level tests fail (TypeError/AttributeError); module-level tests (testing activation_version_gate.py directly) are unaffected by that revert, as expected.
mutator-gate.acceptance.spec.ts updated to supply a fake CLI-capability-probe override (MOSAIC_LEASE_VERSION_PROBE_COMMAND) everywhere it drives launch-runtime.py as a real subprocess — mirroring the fake broker / fake runtime-binary test doubles already used throughout that suite — so the new mandatory gate doesn't depend on a real mosaic binary being on PATH in CI.
package.json's test:framework-shell now includes the new unittest file.
Scope / conflict-avoidance
launch.ts and lease-activation-probe.ts are untouched — no overlap with C2 (install-guard) or C5 (doctor), and C1's constant is consumed read-only.
pnpm run test:framework-shell (full chain) — pass.
pnpm exec vitest run src/mutator-gate/mutator-gate.acceptance.spec.ts — 20/20 pass.
pnpm test (full mosaic package) — 1015/1015 tests pass; 14 pre-existing suite-collection failures unrelated to this change (missing built dist/ for unrelated workspace packages — confirmed identical on a stash of this diff against the same checkout).
pnpm run lint (mosaic package) — clean.
Pre-push hooks (turbo typecheck, lint, root format:check) — all passed before the branch was accepted by the remote.
Part of #869 (Point-1 C4)
Locks the lease broker's ENFORCEMENT half (`launch-runtime.py`) and ACTIVATION half (`execLeaseGatedRuntime()` / C1's `LEASE_ACTIVATION_CAPABILITY`) as one versioned unit, closing the #828 version-skew gap that C1 made observable but did not itself enforce.
## What changed
- New `packages/mosaic/framework/tools/lease-broker/activation_version_gate.py`:
- `EXPECTED_ACTIVATION_CAPABILITY` — the ENFORCEMENT-side expected activation-capability constant (mirrors, but is a separate declaration from, C1's `LEASE_ACTIVATION_CAPABILITY` in `lease-activation-probe.ts`).
- `default_probe_activation_capability()` — fail-closed subprocess probe of the CLI's hidden `mosaic __lease-capability` subcommand (the same mechanism C1's TS-side probe uses).
- `assert_activation_capability_matches()` — raises `VersionCouplingError` with an actionable, `#869`-referencing remediation message on any mismatch (version OR name) or on an absent/unreadable capability.
- `launch-runtime.py` now runs this assertion first, before any broker registration, and denies with a dedicated exit code (`65`) distinct from its existing usage-error (`64`) and registration-failure (`1`) codes. Clear stderr message, non-zero exit, never a silent pass, never a dead gate.
- This is additive alongside — not a replacement for — the existing fail-closed-on-absent-identity gate locked in `runtime_tools_unittest.py`; that suite stays green (matching-capability fakes were injected into its pre-existing calls so the new gate doesn't interfere with what it already covers).
## Tests (red-first)
- New `packages/mosaic/src/mutator-gate/version_coupling_unittest.py`:
- Module-level: matching capability passes; absent capability fails closed; version mismatch and name mismatch both fail loud with actionable messages; reversed-direction drift (newer activation than enforcement expects) also fails.
- Probe-level: PATH-not-resolvable, override-command parsing, non-zero exit / malformed JSON / missing fields / boolean-as-version, timeout and OSError — all fail closed (`None`).
- Seam-level (`LAUNCHER.main()`): matching version proceeds to registration/exec; mismatch/name-mismatch/absent all deny with the dedicated exit code and never reach broker registration or exec.
- Verified genuinely red-first: with `launch-runtime.py`'s wiring reverted, the 6 seam-level tests fail (`TypeError`/`AttributeError`); module-level tests (testing `activation_version_gate.py` directly) are unaffected by that revert, as expected.
- `mutator-gate.acceptance.spec.ts` updated to supply a fake CLI-capability-probe override (`MOSAIC_LEASE_VERSION_PROBE_COMMAND`) everywhere it drives `launch-runtime.py` as a real subprocess — mirroring the fake broker / fake runtime-binary test doubles already used throughout that suite — so the new mandatory gate doesn't depend on a real `mosaic` binary being on PATH in CI.
- `package.json`'s `test:framework-shell` now includes the new unittest file.
## Scope / conflict-avoidance
- `launch.ts` and `lease-activation-probe.ts` are **untouched** — no overlap with C2 (install-guard) or C5 (doctor), and C1's constant is consumed read-only.
## Gates run
- `python3 src/mutator-gate/runtime_tools_unittest.py` — 25/25 pass (fail-closed lock intact).
- `python3 src/mutator-gate/version_coupling_unittest.py` — 15/15 pass (new, red-first-verified).
- `pnpm run test:framework-shell` (full chain) — pass.
- `pnpm exec vitest run src/mutator-gate/mutator-gate.acceptance.spec.ts` — 20/20 pass.
- `pnpm test` (full mosaic package) — 1015/1015 tests pass; 14 pre-existing suite-collection failures unrelated to this change (missing built `dist/` for unrelated workspace packages — confirmed identical on a stash of this diff against the same checkout).
- `pnpm run lint` (mosaic package) — clean.
- Pre-push hooks (turbo `typecheck`, `lint`, root `format:check`) — all passed before the branch was accepted by the remote.
Part of #869 (Point-1 C4). Locks the lease broker's ENFORCEMENT half
(launch-runtime.py) and ACTIVATION half (execLeaseGatedRuntime, C1's
LEASE_ACTIVATION_CAPABILITY) as one versioned unit, closing the #828
version-skew gap C1 only made observable.
- New packages/mosaic/framework/tools/lease-broker/activation_version_gate.py:
EXPECTED_ACTIVATION_CAPABILITY (enforcement-owned, mirrors but is
independent from C1's LEASE_ACTIVATION_CAPABILITY), a fail-closed
subprocess probe of the CLI's hidden `mosaic __lease-capability`
command, and an assertion that FAILS LOUD (VersionCouplingError with
an actionable #869 remediation message) on mismatch OR absence —
never a silent pass, never a dead gate.
- launch-runtime.py now runs this assertion first, before any broker
registration, and denies with a dedicated exit code (65) distinct
from its existing usage (64) and registration-failure (1) codes.
- Red-first tests: src/mutator-gate/version_coupling_unittest.py
(module-level match/mismatch/name-mismatch/absent-capability cases,
and seam-level LAUNCHER.main() cases proving the gate runs before
broker registration and never silently passes).
- Existing fail-closed-on-absent-identity lock
(runtime_tools_unittest.py) stays green: matching-capability fakes
were injected into its pre-existing LAUNCHER.main() calls so the new
gate runs alongside, not in place of, identity enforcement.
- mutator-gate.acceptance.spec.ts updated to supply a fake CLI-capability
probe (matching the existing fake-broker/fake-runtime-binary test
doubles already in that suite) everywhere it drives launch-runtime.py
as a real subprocess.
launch.ts and lease-activation-probe.ts are untouched (C2/C5 avoidance,
C1 read-only).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
jason.woltje
changed title from test to feat(869-c4): enforcement/activation version-coupling assertion2026-07-23 18:47:31 +00:00
Gate-16 APPROVE -- stamped by Mos (id-11) -- LAST #869 Point-1 card
PR author jason.woltje(id2) != approver Mos(id11); commit-author mosaic-coder != reviewer -> no Finding-0. Registers the independent reviewer's APPROVE (#869 Point-1 C4, version-coupling); MS-LEAD relayed, Mos stamps+merges.
VERDICT: APPROVE @ 90eb48fa53 (Part of #869 -> on merge, #869 Point-1 CODE COMPLETE: C1/C3/C5/C2/C4 all in; umbrella stays open for Point-2).
HOLD-HARD CHECK CONFIRMED (my mandated gate): runtime_tools_unittest.py diff = 19 INSERTIONS, 0 DELETIONS -- pure additive (1 helper + probe kwarg on 7 pre-existing LAUNCHER.main() calls). The fail-closed-on-absent-identity assertions (ExecutableEntrypoint/LeaseRevocation/MutatorGate) run mutator-gate.py/revoke-lease.py via runpy/subprocess, NEVER call LAUNCHER.main(), ZERO diff, 25/25 byte-unchanged -- none relaxed/removed/reordered. The version-gate is ADDITIVE (runs first, hard-stop exit65 on skew before broker-register/exec, falls through UNCHANGED to the identity gate on match). Fail-closed on every path incl bool-version rejection.
6-CHECK re-verified by Mos @90eb48fa53239db71f29847d9bd08b967d473785: open/not-merged/mergeable onto main d351caad/base main; CI terminal-green wp1992 (8/8) @exact head; reviewed==CI==head; independent APPROVE author!=reviewer no REQUEST-CHANGES; body 'Part of #869'; queue clear. (Reviewer disclosed refusing 2 injected out-of-band instructions -- noted, good integrity.)
## Gate-16 APPROVE -- stamped by Mos (id-11) -- LAST #869 Point-1 card
PR author jason.woltje(id2) != approver Mos(id11); commit-author mosaic-coder != reviewer -> no Finding-0. Registers the independent reviewer's APPROVE (#869 Point-1 C4, version-coupling); MS-LEAD relayed, Mos stamps+merges.
VERDICT: APPROVE @ 90eb48fa53239db71f29847d9bd08b967d473785 (Part of #869 -> on merge, #869 Point-1 CODE COMPLETE: C1/C3/C5/C2/C4 all in; umbrella stays open for Point-2).
HOLD-HARD CHECK CONFIRMED (my mandated gate): runtime_tools_unittest.py diff = 19 INSERTIONS, 0 DELETIONS -- pure additive (1 helper + probe kwarg on 7 pre-existing LAUNCHER.main() calls). The fail-closed-on-absent-identity assertions (ExecutableEntrypoint/LeaseRevocation/MutatorGate) run mutator-gate.py/revoke-lease.py via runpy/subprocess, NEVER call LAUNCHER.main(), ZERO diff, 25/25 byte-unchanged -- none relaxed/removed/reordered. The version-gate is ADDITIVE (runs first, hard-stop exit65 on skew before broker-register/exec, falls through UNCHANGED to the identity gate on match). Fail-closed on every path incl bool-version rejection.
Other criteria PASS: version-coupling constant matches C1 byte-for-byte; gate ordering + seam test correct; package.json chains C2+C4 tests (15/15 + 5/5); launch.ts + C1 probe zero-diff; scope 6 files.
6-CHECK re-verified by Mos @90eb48fa53239db71f29847d9bd08b967d473785: open/not-merged/mergeable onto main d351caad/base main; CI terminal-green wp1992 (8/8) @exact head; reviewed==CI==head; independent APPROVE author!=reviewer no REQUEST-CHANGES; body 'Part of #869'; queue clear. (Reviewer disclosed refusing 2 injected out-of-band instructions -- noted, good integrity.)
Ghost
merged commit a32ce4c8f9 into main2026-07-23 19:07:28 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of #869 (Point-1 C4)
Locks the lease broker's ENFORCEMENT half (
launch-runtime.py) and ACTIVATION half (execLeaseGatedRuntime()/ C1'sLEASE_ACTIVATION_CAPABILITY) as one versioned unit, closing the #828 version-skew gap that C1 made observable but did not itself enforce.What changed
packages/mosaic/framework/tools/lease-broker/activation_version_gate.py:EXPECTED_ACTIVATION_CAPABILITY— the ENFORCEMENT-side expected activation-capability constant (mirrors, but is a separate declaration from, C1'sLEASE_ACTIVATION_CAPABILITYinlease-activation-probe.ts).default_probe_activation_capability()— fail-closed subprocess probe of the CLI's hiddenmosaic __lease-capabilitysubcommand (the same mechanism C1's TS-side probe uses).assert_activation_capability_matches()— raisesVersionCouplingErrorwith an actionable,#869-referencing remediation message on any mismatch (version OR name) or on an absent/unreadable capability.launch-runtime.pynow runs this assertion first, before any broker registration, and denies with a dedicated exit code (65) distinct from its existing usage-error (64) and registration-failure (1) codes. Clear stderr message, non-zero exit, never a silent pass, never a dead gate.runtime_tools_unittest.py; that suite stays green (matching-capability fakes were injected into its pre-existing calls so the new gate doesn't interfere with what it already covers).Tests (red-first)
packages/mosaic/src/mutator-gate/version_coupling_unittest.py:None).LAUNCHER.main()): matching version proceeds to registration/exec; mismatch/name-mismatch/absent all deny with the dedicated exit code and never reach broker registration or exec.launch-runtime.py's wiring reverted, the 6 seam-level tests fail (TypeError/AttributeError); module-level tests (testingactivation_version_gate.pydirectly) are unaffected by that revert, as expected.mutator-gate.acceptance.spec.tsupdated to supply a fake CLI-capability-probe override (MOSAIC_LEASE_VERSION_PROBE_COMMAND) everywhere it driveslaunch-runtime.pyas a real subprocess — mirroring the fake broker / fake runtime-binary test doubles already used throughout that suite — so the new mandatory gate doesn't depend on a realmosaicbinary being on PATH in CI.package.json'stest:framework-shellnow includes the new unittest file.Scope / conflict-avoidance
launch.tsandlease-activation-probe.tsare untouched — no overlap with C2 (install-guard) or C5 (doctor), and C1's constant is consumed read-only.Gates run
python3 src/mutator-gate/runtime_tools_unittest.py— 25/25 pass (fail-closed lock intact).python3 src/mutator-gate/version_coupling_unittest.py— 15/15 pass (new, red-first-verified).pnpm run test:framework-shell(full chain) — pass.pnpm exec vitest run src/mutator-gate/mutator-gate.acceptance.spec.ts— 20/20 pass.pnpm test(full mosaic package) — 1015/1015 tests pass; 14 pre-existing suite-collection failures unrelated to this change (missing builtdist/for unrelated workspace packages — confirmed identical on a stash of this diff against the same checkout).pnpm run lint(mosaic package) — clean.typecheck,lint, rootformat:check) — all passed before the branch was accepted by the remote.testto feat(869-c4): enforcement/activation version-coupling assertioneaeb633d24to90eb48fa53Gate-16 APPROVE -- stamped by Mos (id-11) -- LAST #869 Point-1 card
PR author jason.woltje(id2) != approver Mos(id11); commit-author mosaic-coder != reviewer -> no Finding-0. Registers the independent reviewer's APPROVE (#869 Point-1 C4, version-coupling); MS-LEAD relayed, Mos stamps+merges.
VERDICT: APPROVE @
90eb48fa53(Part of #869 -> on merge, #869 Point-1 CODE COMPLETE: C1/C3/C5/C2/C4 all in; umbrella stays open for Point-2).HOLD-HARD CHECK CONFIRMED (my mandated gate): runtime_tools_unittest.py diff = 19 INSERTIONS, 0 DELETIONS -- pure additive (1 helper + probe kwarg on 7 pre-existing LAUNCHER.main() calls). The fail-closed-on-absent-identity assertions (ExecutableEntrypoint/LeaseRevocation/MutatorGate) run mutator-gate.py/revoke-lease.py via runpy/subprocess, NEVER call LAUNCHER.main(), ZERO diff, 25/25 byte-unchanged -- none relaxed/removed/reordered. The version-gate is ADDITIVE (runs first, hard-stop exit65 on skew before broker-register/exec, falls through UNCHANGED to the identity gate on match). Fail-closed on every path incl bool-version rejection.
Other criteria PASS: version-coupling constant matches C1 byte-for-byte; gate ordering + seam test correct; package.json chains C2+C4 tests (15/15 + 5/5); launch.ts + C1 probe zero-diff; scope 6 files.
6-CHECK re-verified by Mos @90eb48fa53239db71f29847d9bd08b967d473785: open/not-merged/mergeable onto main d351caad/base main; CI terminal-green wp1992 (8/8) @exact head; reviewed==CI==head; independent APPROVE author!=reviewer no REQUEST-CHANGES; body 'Part of #869'; queue clear. (Reviewer disclosed refusing 2 injected out-of-band instructions -- noted, good integrity.)