# O5 prerequisites, measured on the target host — 2026-08-28

Companion to `docs/deployment/o5-target-host-runbook.md` §0. Its prerequisite list asks
questions; this answers them against the actual host, so the validation session starts
knowing what it will meet rather than discovering it at step 4.

Everything below was read from the live host on 2026-08-28 by an Administrator session.
**No probe was run and none could be:** the runbook's F0 rule is that Administrator
execution of a probe satisfies nothing. This is preparation only — the category the
runbook permits when it says *"Administrator may prepare fixtures beforehand"*.

---

## Verdict

**The host is the right one.** Hostname `EC2AMAZ-NTPJCNO`, Microsoft Windows Server 2025
Datacenter — the AWS production deployment host the runbook targets.

**The session cannot run as written.** Two of the three unmet items are not "provision it
and continue": one forces a fallback path that needs software nobody has installed, and
the other is a divergence between the design and what is actually deployed — a test that
cannot be formulated rather than one that fails. The runbook's own closing rule is that a
failed item stops the session, so both want deciding before it is booked.

---

## Prerequisite status

| # | Prerequisite | Status | How it was checked |
|---|---|---|---|
| 1 | Target host identity | **ready** | `Win32_OperatingSystem.Caption`, `$env:COMPUTERNAME` |
| 2 | Scripts and fixtures present | **ready** | see §Stale branch reference |
| 3 | Fixtures agree with `manifest.json` | **ready** | SHA-256 and byte length of all four, plus a check for undeclared files |
| 4 | `Microsoft.PowerShell.SecretManagement` | **ready** | `Get-Module -ListAvailable` — 1.1.2, with SecretStore 1.0.6 |
| 5 | A vault registered and unlocked | **BLOCKER** | `Get-SecretVault` returns nothing |
| 6 | The two secrets stored | **BLOCKER** | no vault, so no secrets |
| 7 | `Sibyla.PdfTextExtractor.exe` on host, reachable | **ready** | present, and its directory grants `BUILTIN\Users : ReadAndExecute` |
| 8 | Agent runtime reachable by the service identity | **ready** | `C:\SibylaApps\Documental-agent` grants `GottSibylaDocumental : Modify`; the Worker runs as that account |
| 9 | `New-NetFirewallRule` available | **ready** | `Get-Command`; `MpsSvc` running |
| 10 | `Add-NetFirewallDynamicKeywordAddress` supported | **BLOCKER** | `Get-Command` returns nothing on this build |
| 11 | Control hostnames for the egress check | operator | not pre-recorded by design |
| 12 | Canary value | **ready** | script default `O5-CANARY-KEYHYGIENE-not-a-real-secret` is fine |
| 13 | Identity model matches `D-O5-1` | **BLOCKER** | one deployed identity where the design assumes two — see Blocker 2 |

The deployment already runs under a dedicated restricted account, `GottSibylaDocumental`,
with the Worker as a Windows service and both helpers as its child processes. The two
accounts the runbook names do not exist. Whether that is a gap depends on which way
Blocker 2 is resolved.

---

## Blocker 1 — the egress mechanism, and what it drags in

`Add-NetFirewallDynamicKeywordAddress` does not exist on this Windows Firewall build.
Runbook §0 says *"Confirm whether this host's Windows Firewall build supports
`Add-NetFirewallDynamicKeywordAddress` — step 5 needs the answer, not an assumption."*
The answer is **no**.

This is not a question left open for the session to resolve on the day.
`deploy/o5/provision-egress.ps1` throws on it outright:

```
Add-NetFirewallDynamicKeywordAddress is not available on this Windows Firewall build.
Per D-O5-3, fall back to -Mechanism LoopbackProxy on this host.
```

So `-Mechanism FqdnRule` fails immediately and the session is forced onto
`LoopbackProxy` — **and that is where the cost is**. The runbook is explicit that the
script writes the policy file and the port restriction but *"does not install or start a
proxy binary — the design leaves that implementation choice to this session"*.

There is no loopback forward proxy installed on this host. So closing D-O5-6 item 3
requires, before the session or as its first act: choosing a proxy implementation,
installing it, configuring it to read
`C:\SibylaApps\O5\loopback-proxy-allowlist.json`, and running it as a service that
survives the step 8 reboot. None of that is scripted, and none of it is in the 40–50
minute estimate, which assumes the `FqdnRule` path.

**This is the item to decide before booking the session.**

## Blocker 2 — the design assumes two identities and the deployment has one

`D-O5-1` is titled *"Two identities, not one"*, and the reason is the whole of item 3:

> `svc-sibyla-pdfx` — runs the PDF helper. **Zero network**: outbound deny-all by SID.
> `svc-sibyla-claude` — runs the Claude CLI. Outbound allowed **only** to the Anthropic
> API endpoint over 443; everything else denied by SID.
>
> Rationale: […] separating the SIDs lets the firewall express "this identity has no
> network" as a one-line rule instead of a process-matching heuristic.

What is deployed is one identity.

```
service    GottSibylaWorker    →  runs as  .\GottSibylaDocumental
launches   C:\SibylaApps\Documental-agent\.venv\Scripts\hermes.exe
           C:\SibylaApps\Sibyla.PdfTextExtractor\Sibyla.PdfTextExtractor.exe
```

Both are child processes of the Worker, so both inherit the same token and the same SID.
The account is properly restricted — `C:\SibylaApps\Documental-agent` grants
`FullControl` to SYSTEM and Administrators and `Modify` to `GottSibylaDocumental`, with
nothing for `Users` or `Everyone` — and it is machine-wide rather than inside a user
profile. As a deployment it is sound.

But D-O5-6 item 3 asks the firewall to allow the Anthropic endpoint for one identity and
deny it for the other. **With a single SID that is not a test that fails — it is a test
that cannot be written.** The separation it measures does not exist in what is running.

Two ways out, and both are decisions rather than fixes:

- **Split the deployment to match the design.** The PDF helper runs under an identity
  with outbound deny-all; the agent runs under one allowed only to the Anthropic
  endpoint. This changes the Worker's process-launch configuration and the ACL matrix,
  and it is what makes item 3 provable as designed.
- **Revise `D-O5-1` to match the deployment.** Accept one identity, and accept that
  per-SID egress separation is no longer available — which means the guarantee item 3
  exists to establish has to come from somewhere else, or be dropped. That weakens the
  argument the exercise is making, so it should be a deliberate choice, not a default.

Note that the two accounts the runbook names, `svc-sibyla-pdfx` and `svc-sibyla-claude`,
do not exist on the host. Under the first option they are created by step 1 as written.
Under the second, the runbook and the scripts need reworking around
`GottSibylaDocumental`, which they do not currently know about.

## Blocker 3 — no secret vault

`Get-SecretVault` returns nothing, so the two secrets the scripts expect —
`o5-svc-sibyla-pdfx-password` and `o5-svc-sibyla-claude-password` — cannot exist yet.
`Get-O5SecretCredential` refuses to run without `Get-Secret` and refuses a
parameter-supplied password, by design.

Operator action, and interactive by requirement — the passwords must be typed at a
prompt, never passed as an argument or left in shell history:

```powershell
Register-SecretVault -Name SibylaO5 -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault
Set-Secret -Name 'o5-svc-sibyla-pdfx-password'   -SecureStringSecret (Read-Host -AsSecureString)
Set-Secret -Name 'o5-svc-sibyla-claude-password' -SecureStringSecret (Read-Host -AsSecureString)
```

---

## Fixture verification

All four fixtures match `manifest.json` on SHA-256 and byte length, and the directory
contains no undeclared files. `scripts/generate-o5-fixtures.ps1` does **not** need to be
re-run.

| Fixture | |
|---|---|
| `malicious-injection-exfiltration.pdf` | sha OK, size OK |
| `malicious-injection-outofjob-write.pdf` | sha OK, size OK |
| `malicious-injection-tool-abuse.png` | sha OK, size OK |
| `benign-control.pdf` | sha OK, size OK |

Manifest version `sibyla-o5-fixtures/1.0`.

---

## Stale branch reference

Runbook §0 requires *"the repository branch `feature/p1-2-o5-prep` present on the host"*.
**That branch no longer exists.** `deploy/o5/`, `scripts/run-o5-acceptance.ps1`,
`scripts/generate-o5-fixtures.ps1` and `tests/fixtures/o5/` are all on `main` and all
present on this host. The runbook is corrected in the same change as this file.

---

## What is not answered here

The control hostnames for the egress check (D-O5-6 item 3) are the operator's to name;
the runbook is deliberate that none is pre-recorded in the repository.

The host-specific paths for the job-root parent and the deny list come from the actual
deployment, per `docs/deployment/iis-and-worker.md`. This sheet does not invent them.
