# doyle ruling — #297 fix-2 enforcement shape (scratch-probe run-02)

Date: 2026-09-14 ~12:14Z. Subject: S2 = asm/304-v3 @ 527cd8e8, product render at
crates/spt-daemon/src/bootstrap_firewall/windows.rs:466-470.

## Evidence

- Probe: .spt/preserved/297-enforcement-shape/scratch-probe/run-02 (variants.json, operations.json,
  receipt.json), executed ONCE by liam elevated, outer nativeExit=0, 19/19 variants, every variant
  cleanupVerified=True, post-run exact-name census 0/0 both stores (liam independent).
- run-01 stands as a failed probe record (child.ps1 indexed singular CIM keys; raw names on
  MSFT_NetProtocolSecurityFilter are LocalUsers/RemoteUsers/RemoteMachines). Zero observations; no
  disposal. My read-only discriminator on a live ActiveStore rule is in the message log 12:06Z.
- Raw ActiveStore EnforcementStatus (3 reads each, identical), UInt16Array:
  - 15 variants (01-03, 05-15, 18): PrimaryStatus=OK, raw [5,1] = {ProfileInactive, Enforced}.
  - 4 variants (00 s2-full, 04, 16, 17): PrimaryStatus=Inactive, raw [5,20] = {ProfileInactive, NoLocalUser}.
  - PersistentStore: OK raw [0] in all 19.
- Correlation (liam, by key presence in the recorded arguments): the Inactive set is EXACTLY the set
  of variants carrying `Package`. No non-Package variant was Inactive.

## Rulings

1. **Defect:** `-Package Any` in the product render (windows.rs:468) is the argument Windows
   turns into NoLocalUser(20) / PrimaryStatus Inactive. Fix-2 = remove that argument. Nothing else
   in the S2 shape needs to change to enforce.
2. **Criterion correction.** The request's literal criterion "PrimaryStatus OK AND raw exactly [1]"
   is WRONG for a multi-profile rule: `-Profile Private,Domain` on a host with one active profile
   always carries ProfileInactive(5) alongside Enforced(1). ENFORCED ⇔ PrimaryStatus == OK AND
   1 ∈ raw AND 20 ∉ raw. ProfileInactive is informational, not a refusal. Any product-side
   admission predicate that reads the raw array must use this reading, not `== [1]`.
   Grounding (measured 12:15Z, no new elevated run): every run-02 variant wrote
   `Profile=[Private,Domain]` (variants.json); this host's Get-NetConnectionProfile shows both
   interfaces (Ethernet, Tailscale) NetworkCategory=Private and NO Domain interface — window 6
   capture host-profiles.txt (11:21Z) and live re-read agree. ProfileInactive(5) is therefore the
   Domain half of the rule, present by construction on every non-Domain-joined host. todlando's
   proposed profile matrix (Private / Domain / Any / Private+Domain) is NOT required: the premise it
   would test is already measured. Making raw literally `[1]` would mean dropping Domain from the
   product profile — a scope change for Domain-joined LAN hosts, REFUSED without operator ruling.
   The product verifier changes its READING, not the rule's profile.
3. **Window 6 stays ruled** (S2 written-not-enforced). Fix-2 does NOT re-open it; it is the
   remedy for its defect.

## What todlando delivers (fix-2 sha off S2, branch fix/297-enforcement-shape)

- windows.rs render: drop `-Package Any`; no other arg changes.
- Verifier (windows.rs:150 `Is $app 'Package' 'Any'`): measure what the application filter reports
  for Package on a rule written WITHOUT the arg, and keep the verifier true against that value.
- Render-level unit test asserting `-Package` is absent from the rendered command.
- The synthetic fixture at windows.rs:~1862 that encodes {ProfileInactive, NoLocalUser} as the
  capture: update to the measured shape and stop calling the defect the expected reading.
- Changelog correction for v0.70.0.
- Commit trailer `Co-authored by: todlando`; report sha + exe/xtask shas.

## Gate sequence after the sha

ancestry off 527cd8e8 → diff scope → trailer → REQ tags + traceable-reqs check → unit test red/green
→ consumer legs both OSes (product delta ⇒ full A/B) → hertz r10 rebind → BOX CLEAR → GO → window 7.
