# Sub-slice C2 prompt — Sibyla.Deployment Slice 2, the eight Windows adapters (RED oracles before code)

*Written 2026-09-03 after the independent checkpoint review A2+B2 closed with both reviewers at
Critical 0, High 0, Medium 0, Low 0 on `49a8618` of `ops/sibyla-deployment-slice2-b2` (record:
`local/deploy/tests/Sibyla.Deployment.Tests/evidence/CHECKPOINT-A2B2-review.md`; evidence
`B2-red.txt` / `B2-green.txt`). Hand the fenced block to a fresh agent session; everything above
it is context for the owner.*

Why C2 is its own session: it is the first code that touches a Windows host. It runs only against
the disposable `ZZ.Sibyla.Probe.*` objects, elevated, with `Backup-WebConfiguration` taken first
and never restored by the harness, and it must be written against the accepted spec, B2's adapter
seams and the two reviewers' C2 notes with a clean context, its oracles typed before code, its
RED and GREEN evidence recorded before the checkpoint review C2+D2.

---

## The prompt

```text
You are working in D:\fileStorage\repos\GOTT.Apollo (Windows Server 2025, .NET SDK 10, PowerShell 5.1
for the module and the probes; this host is the production host, so every rule below is a safety rule).
Read these first, in this order, and treat them as the authority:

  1. docs/apollo-deployment-slice2-spec.md            — Slice 2 specification, revision 10, ACCEPTED:
                                                        sections 0.2 (assembly layout, allowed namespaces per
                                                        adapter folder), 2 (the facts the probes reproduce),
                                                        5.1 (every adapter rule: receipts, post-state digests,
                                                        rollback rules, drains, elevation, the mutex), 8, 9 row C2, 10
  2. docs/apollo-deployment-slice2-spec-review.md     — nine review rounds; every adjudication
  3. local/deploy/tests/Sibyla.Deployment.Tests/evidence/CHECKPOINT-A2B2-review.md
                                                      — the A2+B2 checkpoint: both reviewers' records, the two
                                                        revisions, and the C2 NOTES you must honour (below)
  4. docs/apollo-deployment-slice2-b2-prompt-260903.md — what B2 delivered and how
  5. local/deploy/ on branch ops/sibyla-deployment-slice2-b2 (head 111e4e7, reviewed snapshot 49a8618):
       src/Sibyla.Deployment.Execution/Adapters/AdaptersV2.cs — the seams you implement
         (IFileSystemAdapterV2, IAclAdapterV2, IProcessAdapterV2, IIisAdapterV2, IScmAdapterV2,
         ITlsAdapterV2, IHttpAdapterV2, IMutexAdapterV2, IRollbackRuleV2, IOperatorProviderV2,
         AdapterSetV2, AdapterCallV2), Runtime/RuntimeV2.cs (DeploymentRuntimeV2.CreateProduction
         wires an UnavailableAdapterV2 for every family today), Runtime/InvokersV2.cs (how the
         invoker calls you: a worker thread with a cancellation deadline and a drain time for every
         family, the calling thread and no deadline for the mutex pair)
       tests/Sibyla.Deployment.Tests: oracles/registry.v2.json (the 38 descriptors), Slice2/Execution/
         FakeHostV2.cs (the fake host and adapters: the behaviour the real adapters must match)
       tests/Sibyla.Deployment.Tests/evidence/B2-green.txt — the B2 state and the corrections
  6. docs/apollo-deployment-run-260903.md             — how production is deployed today (the hand path)
  7. docs/apollo-naming-shift-phase-d-260903.md       — the databases and roles (sibyla_*)

GOAL
Deliver sub-slice C2 of Slice 2 exactly as the spec's section 9 row C2 defines it: the eight adapters
in a new project Sibyla.Deployment.Adapters.Windows (net48 only), proven AT ADAPTER LEVEL through
PowerShell 5.1 probes run elevated against disposable objects named ZZ.Sibyla.Probe.*, wired into
DeploymentRuntimeV2.CreateProduction, with RED oracles before code and the evidence files of the
Slice 1 discipline. No entry point runs against a host in C2: -Execute stays refused before any
production object (D2 is the first live run, and only -ChecksOnly).

SCOPE OF C2 (spec section 9 row C2; sections 0.2, 2, 5.1, 8, 10)
  a. Sibyla.Deployment.Adapters.Windows, net48 only, exempt from the transferability rule, one folder
     per family with exactly the namespaces 0.2 allows (Adapters/FileSystem, Acl, Process, Iis, Scm,
     Tls, Http, Mutex); allowed assembly references per forbidden.v2.json (System.ServiceProcess,
     System.Management, System.Net.Http, Microsoft.Web.Administration 7.0.0.0 from the GAC, offline
     build as the 2026-09-03 spike); every S1 source ban, LangVersion 13.0 and the forbidden member
     names apply to it; System.Environment banned. The Cmdlets project references it; the module
     manifest lists it; local\deploy\build.ps1 builds it offline.
  b. The eight adapters against 5.1, row by row: snapshots with comparable digests, Apply/PublishTree/
     SetActiveInstall with MutationReceiptV2.PostState = the adapter's comparable post-state digest,
     Rollback with NoChange only when the live object equals the snapshot digest and PostState the
     snapshot's digest, Readback bound to a receipt's post-state, the per-family rollback rule
     (IRollbackRuleV2.CompareForResume) resume uses, typed refusals never thrown (Satisfied / Matches /
     Acquired = false), the cancellation token polled (never token.WaitHandle: the source is disposed
     when the call returns), the drain behaviour of 5.1 for pools and the service, elevation.
  c. The Mutex adapter: acquires and releases Global\GOTT.Apollo.Deployment.v1 on the CALLING thread
     (the invoker runs MutationKind.None intents synchronously and without a deadline), keeps the
     Mutex object alive across the two intents of one transaction, bounds its own wait at 30 s and
     answers Acquired = false (never throws), treats an abandoned mutex as acquired with
     Abandoned = true, makes Release idempotent (after Acquired = false too, and a second time after
     Health's forward release), never moves the wait to a Task or pool thread.
  d. The Process adapter: Process.Rollback(Service) is the single mechanism that restores a service
     the safety stop failed to stop or one running from another path (compare state and
     ExecutablePath; Running from another path is stopped and started), including the stop-timeout
     case; Process.Recycle is idempotent and starts a Stopped pool; the engine never runs the safety
     stop twice.
  e. IOperatorProviderV2 for the Windows identity, rendered within the section 8 allowed set
     (DOMAIN\user is fine; anything else pre-rendered); Observed texts of preconditions and readbacks
     limited to the compared values (a secret-shaped Observed fails the intent with REDACTION).
  f. The probe harness (PS 5.1 probes, spawned elevated by a runner that uses runas): builds the typed
     arguments through Execution's interfaces (ServiceNameV2("ZZ.Sibyla.Probe.Service") included);
     Backup-WebConfiguration first, NEVER Restore-WebConfiguration (restore is manual only; the
     harness removes its backup in finally); pre-clean of any ZZ.* leftovers (sites, pools, service,
     folders, zz-*.sibyla.probe http.sys entries, the probe thumbprint), clean in finally; after every
     run assert that applicationHost.config minus ZZ.*, the sslcert list minus *.sibyla.probe and the
     WebHosting store minus the probe thumbprint are unchanged, compared by hash and element path
     only, never printing attribute values (the legacy pools' environment carries a connection
     string). Probe objects: pools and sites ZZ.Sibyla.Probe.{Web,Api,Docs} bound *:8443:zz-{web,api,
     docs}.sibyla.probe (SNI, port 8443 free) with a self-signed certificate in WebHosting (the Http
     adapter pins that thumbprint when the harness says so, validates the chain otherwise); the
     service ZZ.Sibyla.Probe.Service from a stub host built by the test project (it loads a dll named
     as ExpectedModule for the pool probes) as NT AUTHORITY\LocalService, start Manual; folders
     C:\Apps\ZZ.Sibyla.Probe and D:\ApolloData\ZZ.Sibyla.Probe; the production mutex on purpose;
     HostOverride 127.0.0.1. A source-grep test proves no production .ps1, default or source under
     Core, Cmdlets, Execution or Adapters.Windows references ZZ. except Execution/Inputs/ServiceNameV2.cs.
  g. Oracles typed BEFORE any of the above (the RED step): per-adapter oracles = section 2's facts on
     the probe objects (what each snapshot, apply, rollback, readback and readback-after-rollback
     must observe and answer, digests included), the C2 rows every reviewer note below asks for
     (MUTEX-BUSY from a second process while a transaction is open; the 30 s bound; the lazy-NoChange
     refusal; Process.Rollback of a service running from another path and of a stop that timed out;
     Recycle of a Stopped pool; Observed with a secret-shaped text refused), and the amendments the
     B2 harness needs to run its semantics cases against the REAL adapters on the probe objects
     (record every amendment; never silently edit an existing row).

THE REVIEWERS' C2 NOTES (from CHECKPOINT-A2B2-review.md; each becomes an oracle row or a test)
  - Mutex ownership on the calling thread and everything under (c).
  - Rollback truthfulness under (b): the readback bound to a rollback receipt compares to that
    receipt's PostState, so a lazy NoChange would pass its own readback; only the adapter's rule
    stands between a lazy NoChange and a RolledBack that is not.
  - Process.Rollback(Service) as the single healer under (d); Recycle idempotent and starting a
    Stopped pool.
  - AdapterCallV2 carries neither MutationKind nor RequiresElevation: Read actions must never obtain
    writable handles (open ServerManager, registry keys and the certificate store read-only on those
    paths); elevation is never checked at runtime, so the operator provider verifies elevation once
    and a non-elevated run fails typed, not with an untyped ADAPTER-FAILED at PublishTree.
  - Poll IsCancellationRequested / ThrowIfCancellationRequested only.
  - HealedLater in the engine identifies the safety stop's healer as "a later Compensation entry of
    the same adapter in the Configure list": exact for the compiled order; if the phase table ever
    gains another Process compensation after the safety stop, the order oracle is revisited with it.
  - The reviewed engine reading of resume (section 6): only the recycle re-runs on its own failure;
    the safety stop runs again only when Scm.Rollback is retried.

PROCEDURE (Slice 1 section 9, unchanged; the lessons of B2 added)
  1. Branch ops/sibyla-deployment-slice2-c2 from ops/sibyla-deployment-slice2-b2 (head 111e4e7);
     git worktree under D:\fileStorage\repos\GOTT.Apollo-worktrees\ with a junction to the main
     checkout's local\secrets (never a copy). The A2 and B2 branches stay as they are, unmerged.
  2. Type the oracles (g) and the tests that read them. COMMIT THE RED STATE BEFORE THE FIRST LINE OF
     ADAPTER CODE. Run the suite: the new tests must FAIL (the probes against a scaffold that answers
     nothing) and the S1+A2+B2 suite (1215 tests) must stay green. Save evidence/C2-red.txt with the
     framed SHA-256 taken from a clean export of the RED commit (git archive + tar, then
     evidence/New-EvidenceFingerprint.ps1 over the export; never over the working tree). A behaviour
     test that passes on its first run is a HARD STOP.
  3. Implement (a)–(f) until green. Save evidence/C2-green.txt with the fingerprint taken the same way
     from the GREEN commit. Run the Api suite and local\test.ps1 once. A test written together with
     its fix is replayed against the pre-fix code (non-incremental build) and the transcript appended.
  4. Commit in small steps; push the branch. Do not merge: the independent checkpoint review C2+D2
     follows D2.
  5. Record: a dated entry in docs/apollo-discovery-and-plan-260826.md, the C2 row of the spec's
     section 9 with the evidence fingerprints, and memory.

HARD CONSTRAINTS
  - The spec is the authority. If code cannot be made to match it, stop and report the section; never
    fix the spec silently. Same for a B2 seam that proves wrong: record the change in the evidence
    and keep the B2 suite green.
  - Adapter proof only on the ZZ.Sibyla.Probe.* objects, elevated, with the backup and the
    unchanged-config assertions of (f). Never touch the production sites, pools, the service
    Sibyla.Worker.Documents, the legacy sites, GottSibylaWorker, gott_sibyla, win-acme, the Hermes
    configuration or crons. Never run -Execute against a host. A probe run, a hand-path run and a
    win-acme run (window 09:00–15:00 UTC) must never overlap.
  - Never read local\secrets, C:\ProgramData\Sibyla\secrets contents or D:\ApolloData\worker-claude.
  - Never add NoteProperty members; no records/init/required; no #if; the forbidden.v2.json member
    names stay absent (Held, Committed, Released, Verified, Active, Completed, Complete, …); the
    identifier "record" is a source ban even as a local; Environment. is a source ban; an iterator
    (yield) references System.Environment in its state machine, so build lists instead.
  - Evidence files are appended, never rewritten; the S1, A2 and B2 evidence files are never edited.
  - Editing: use the editor tool for source edits, never perl -pi (a stray perl with an empty program
    argument filled drive C: during B2); if perl or sed is ever used, check for leftover processes and
    line endings (git ls-files --eol) before committing; fingerprints only from clean exports.
  - Drive C: is small; keep temp files on D: (D:\fileStorage\tmp\<session>\).

RESOLVED OWNER RULING OUTSIDE C2
  - O1 of the checkpoint is closed: sibyla_api is the only current platform API role; apollo_api is
    historical and remains only in immutable applied migrations and evidence. SchemaHealthGrant was
    applied before Phase D and its Main grant followed the role rename by OID; a fresh database gets
    the canonical sibyla_api grant from db/channel-intake-api-role.sql through local/setup-db.ps1.
    Do not rewrite the migration or add a narrow follow-up in C2. D2 still records
    has_table_privilege('sibyla_api', '"__EFMigrationsHistory"', 'SELECT') = true on production.

REPORT
  The RED fingerprint (from the RED commit's export) and the failing tests it covered; the GREEN
  fingerprint and the counts (S1 585, A2, B2, C2, Api); every B2 seam or oracle row changed and why;
  the exact host objects created and removed by the probes and the three unchanged-config hashes;
  anything in the spec's 5.1 that did not survive contact with the host; what D2 needs.
```

---

## For the owner

- Start it as a new Claude Code session in `D:\fileStorage\repos\GOTT.Apollo` and paste the fenced
  block. Memory carries `apollo-deployment-slice2-b2` (with the checkpoint outcome) and
  `apollo-deployment-slice2-a2`.
- C2 creates and removes `ZZ.Sibyla.Probe.*` objects on this host, elevated, with a
  `Backup-WebConfiguration` taken first that the harness never restores; if a probe run dies, the
  cleanup is `finally`, and the restore, should it ever be needed, is yours by hand. Schedule probe
  runs outside the win-acme window (09:00–15:00 UTC) and never during a hand-path deploy.
- After C2 comes D2 (`-Execute -ChecksOnly` on the live hosts, after the hand-path deploy of the A2
  API with `/health/schema` and the `sibyla_api` privilege check), then the checkpoint review C2+D2
  with the two reviewers, then E2.
