feat(869-c5): mosaic doctor surfaces wired-but-unactivatable lease enforcement #878

Merged
Mos merged 1 commits from feat/869-c5-doctor-activation-check into main 2026-07-23 18:38:22 +00:00
Owner

Part of #869 (Point-1 C5)

Summary

Adds a mosaic doctor health check for the #869 fail-closed brick scenario: the Claude Code enforcement hooks (mutator-gate.py gating PreToolUse, receipt-observer-client.py observing Stop) can be wired into ~/.claude/settings.json on a host where the activation half is absent (C1's leaseEnforcementActivatable() is false) and/or the broker supervisor is unhealthy (C3's checkBrokerSupervisorHealth()). That combination fails closed correctly but was previously silent — mosaic doctor did not detect it.

  • New packages/mosaic/src/commands/lease-doctor-check.ts:
    • detectEnforcementHooksWired() — pure detection of the mutator-gate/receipt-observer markers in a parsed settings.json.
    • runLeaseEnforcementDoctorCheck() — combines wiring detection with C1's leaseEnforcementActivatable() and C3's checkBrokerSupervisorHealth() (both imported read-only, not modified). Not wired ⇒ ok (no false alarm, activation/broker never even probed). Wired + activatable + broker-healthy ⇒ ok. Wired + (not activatable OR broker unhealthy) ⇒ a LOUD, actionable error citing #869.
  • packages/mosaic/src/commands/launch.ts: the doctor subcommand now runs this check before delegating to the existing mosaic-doctor bash audit script, printing [mosaic-doctor] [ERROR] ... (louder than the script's own [WARN] lines) and forcing a non-zero exit if the lease-enforcement check fails — even if the bash script itself is green. Silent on an ok result, matching this file's existing checkMosaicHome/checkFile conventions.

Test plan

  • Red-first unit tests in lease-doctor-check.spec.ts (11 tests): wired+not-activatable ⇒ error, wired+activatable+broker-unhealthy ⇒ error, wired+neither ⇒ error citing both reasons, wired+activatable+healthy ⇒ ok, not-wired ⇒ ok (and activation/broker probes are never even called), settings.json absent ⇒ ok, malformed settings.json ⇒ ok. Every dependency (settings read, activation probe, broker-health check) is injected — no real ~/.claude/settings.json or broker touched.
  • pnpm typecheck — pass
  • pnpm lint — pass
  • pnpm format:check — pass
  • pnpm --filter @mosaicstack/mosaic full vitest suite (1477 tests) — pass, including pre-existing C1 (lease-activation-probe.spec.ts) and C3 (broker-supervisor.spec.ts) suites, unmodified and still green.
Part of #869 (Point-1 C5) ## Summary Adds a `mosaic doctor` health check for the #869 fail-closed brick scenario: the Claude Code enforcement hooks (`mutator-gate.py` gating PreToolUse, `receipt-observer-client.py` observing Stop) can be wired into `~/.claude/settings.json` on a host where the activation half is absent (C1's `leaseEnforcementActivatable()` is false) and/or the broker supervisor is unhealthy (C3's `checkBrokerSupervisorHealth()`). That combination fails closed correctly but was previously silent — `mosaic doctor` did not detect it. - New `packages/mosaic/src/commands/lease-doctor-check.ts`: - `detectEnforcementHooksWired()` — pure detection of the mutator-gate/receipt-observer markers in a parsed `settings.json`. - `runLeaseEnforcementDoctorCheck()` — combines wiring detection with C1's `leaseEnforcementActivatable()` and C3's `checkBrokerSupervisorHealth()` (both imported read-only, not modified). Not wired ⇒ ok (no false alarm, activation/broker never even probed). Wired + activatable + broker-healthy ⇒ ok. Wired + (not activatable OR broker unhealthy) ⇒ a LOUD, actionable error citing #869. - `packages/mosaic/src/commands/launch.ts`: the `doctor` subcommand now runs this check before delegating to the existing `mosaic-doctor` bash audit script, printing `[mosaic-doctor] [ERROR] ...` (louder than the script's own `[WARN]` lines) and forcing a non-zero exit if the lease-enforcement check fails — even if the bash script itself is green. Silent on an `ok` result, matching this file's existing `checkMosaicHome`/`checkFile` conventions. ## Test plan - [x] Red-first unit tests in `lease-doctor-check.spec.ts` (11 tests): wired+not-activatable ⇒ error, wired+activatable+broker-unhealthy ⇒ error, wired+neither ⇒ error citing both reasons, wired+activatable+healthy ⇒ ok, not-wired ⇒ ok (and activation/broker probes are never even called), settings.json absent ⇒ ok, malformed settings.json ⇒ ok. Every dependency (settings read, activation probe, broker-health check) is injected — no real `~/.claude/settings.json` or broker touched. - [x] `pnpm typecheck` — pass - [x] `pnpm lint` — pass - [x] `pnpm format:check` — pass - [x] `pnpm --filter @mosaicstack/mosaic` full vitest suite (1477 tests) — pass, including pre-existing C1 (`lease-activation-probe.spec.ts`) and C3 (`broker-supervisor.spec.ts`) suites, unmodified and still green.
jason.woltje added 1 commit 2026-07-23 18:26:17 +00:00
feat(869-c5): mosaic doctor surfaces wired-but-unactivatable lease enforcement
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
e75e32386c
Part of #869 (Point-1 C5). Adds runLeaseEnforcementDoctorCheck(), which
detects whether the Claude Code enforcement hooks (mutator-gate.py /
receipt-observer-client.py) are wired in ~/.claude/settings.json and, if so,
reuses C1's leaseEnforcementActivatable() and C3's
checkBrokerSupervisorHealth() to determine whether activation could actually
satisfy enforcement right now. Wired-but-not-activatable/unhealthy reports a
LOUD [mosaic-doctor] [ERROR] (forces mosaic doctor to exit non-zero even if
the underlying bash audit script is green); not-wired or wired-and-healthy
both pass silently, matching this file's existing checkMosaicHome/checkFile
conventions.

Red-first unit tests inject every dependency (settings read, activation
probe, broker-health check) — no real ~/.claude/settings.json or broker is
ever touched.
Mos approved these changes 2026-07-23 18:38:20 +00:00
Mos left a comment
First-time contributor

Gate-16 APPROVE -- stamped by Mos (id-11)

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 C5, mosaic doctor activation-check); MS-LEAD prepared/relayed, Mos stamps+merges.

VERDICT: APPROVE @ e75e32386c (Part of #869 -- Point-1 card, umbrella stays open, no Closes).

Independent review, all 8 PASS: (1) detectEnforcementHooksWired matches both hook markers (partial wiring=dangerous, tested); (2) check logic -- not-wired->silent ok; wired->error unless activatable AND broker-healthy; names each failing reason, cites #869/brick; no false-alarm, no silent-pass; (3) launch.ts scoped to doctor subcommand only (init/sync/bootstrap untouched); (4) C1/C3 consumed read-only (zero diff); (5) red-first 11 tests, injected fakes, both branches; (6) fail-closed locks untouched+green; (7) firewall clean; (8) CI terminal-green wp1987 (all 8 steps) + vitest 1477/1477.

Doctor loudly surfaces the wired-but-unactivatable brick state (reuses C1 probe + C3 broker-health) -- the operator-facing guard for the #828/#869 fleet-brick class.

6-CHECK re-verified by Mos @e75e32386c86e5c6ce294f0a17dc65b92c12eee5: open/not-merged/mergeable onto main 4422231b/base main; CI success @exact head; reviewed==CI==head; independent APPROVE author!=reviewer no REQUEST-CHANGES; body 'Part of #869'; queue clear.

## Gate-16 APPROVE -- stamped by Mos (id-11) 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 C5, mosaic doctor activation-check); MS-LEAD prepared/relayed, Mos stamps+merges. VERDICT: APPROVE @ e75e32386c86e5c6ce294f0a17dc65b92c12eee5 (Part of #869 -- Point-1 card, umbrella stays open, no Closes). Independent review, all 8 PASS: (1) detectEnforcementHooksWired matches both hook markers (partial wiring=dangerous, tested); (2) check logic -- not-wired->silent ok; wired->error unless activatable AND broker-healthy; names each failing reason, cites #869/brick; no false-alarm, no silent-pass; (3) launch.ts scoped to doctor subcommand only (init/sync/bootstrap untouched); (4) C1/C3 consumed read-only (zero diff); (5) red-first 11 tests, injected fakes, both branches; (6) fail-closed locks untouched+green; (7) firewall clean; (8) CI terminal-green wp1987 (all 8 steps) + vitest 1477/1477. Doctor loudly surfaces the wired-but-unactivatable brick state (reuses C1 probe + C3 broker-health) -- the operator-facing guard for the #828/#869 fleet-brick class. 6-CHECK re-verified by Mos @e75e32386c86e5c6ce294f0a17dc65b92c12eee5: open/not-merged/mergeable onto main 4422231b/base main; CI success @exact head; reviewed==CI==head; independent APPROVE author!=reviewer no REQUEST-CHANGES; body 'Part of #869'; queue clear.
Mos merged commit 76b86a246e into main 2026-07-23 18:38:22 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#878