# Fabric autonomy external-gate audit

Forge now has read-only, fail-closed audit harnesses for the autonomy work that cannot truthfully be
completed by repository code alone. Passing an audit means the retained evidence is internally exact
enough for the next governed service to review. It does **not** enable execution or declare a release
production-ready.

## Repository audit coverage

| Gate | Repository audit | What remains external |
|---|---|---|
| Evidence quality | Classifies retained facts as exact provider-verified, exact provider-observed, visual-observed, context-only, or unobserved. Only the first can pass the provider-write evidence gate, and only with typed target/arguments/postcondition. Recording may continue degraded; evidence cannot be upgraded by inference. | Trusted installed app builds and native channel evidence from the real recording environment. |
| Photoshop native integrity | Verifies installed-build attestations plus the session-bound native challenge/envelope protocol and degrades typed operations when proof is missing or invalid. | Build, sign, install, and trust the Photoshop native challenge/hybrid add-on and provision/rotate its build key. |
| Finder/browser/spreadsheet capture | Defines signed, session-bound observation-only envelopes and fail-open-for-recording/degraded source seams. Missing intervals stay latched and replay-blocked. | Build, sign, install, key, independently review, manifest, and qualify the Finder bridge, browser extension/CDP bridge, Office add-in, and any Numbers bridge. |
| Visual fallback | Validates separate consent, redacted evidence contracts, encrypted local-vault receipts, bounded analysis, and review-only/non-authorizing semantics. | Real macOS screen-recording/pointer permission, signed distribution, privacy review, and approved retention policy. Visual evidence can never replace exact provider proof. |
| Exact sandbox replay | Resolves the retained Task Workspace server-side; validates sealed plan binding, protected-target rejection, no-write receipt, exact human review, provider bindings, active commissioned graph, disposable-sandbox attestation, and rollback evidence. This durable packet intentionally does not contain live consent. | Authoritative disposable-sandbox attestation, fresh one-run live-control consent, and execution through the sandbox runtime. |
| Twenty-case corpus | Emits deterministic corpus identity and accepted case IDs; requires 20 distinct attributable cases and an independent review bound to that exact corpus. | Real approved tickets, physical outcomes, human acceptances, and an identified independent reviewer. |
| Specialist commissioning | Verifies Forge provenance, intact review-only boundary, disabled routing, typed workflow, pinned executable skills, and an exact approved production release loaded from the authoritative promotion registry. Caller-supplied promotion shapes are labeled untrusted and cannot pass. | Authoring/evaluation/certification/publication followed by explicit human commissioning. |
| macOS distribution | Read-only verification of archive/receipt identity, package verifier, Developer ID signature, accepted notary receipt, stapled ticket, and Gatekeeper assessment. | Approved signing identity, Apple submission, Security/SRE approval, and distribution. |

The harnesses are:

- `dashboard/autonomy_external_gate_audit.py`
- `tools/audit_macos_release.py`

Qualification packets bind the autonomy report, physical manifest, and skill registry with source
digests. Validation recomputes batch counts, item counts, bounded batch sizes, readiness totals, and
the zero-promotion invariant. When live sources are supplied, any source drift invalidates the
packet even if someone reseals the edited JSON.

The read-only status is reachable through:

- `GET /api/autonomy/qualification-batches`
- `GET /api/autonomy/external-gates`
- Capability Center → **Qualification review batches** / **External release gates**

These views expose missing evidence as `evidence_not_loaded`; they never create evidence or run a
qualification. Physical corpus release evidence is scoped per exact capability ID and exact
candidate digest. A single target-level Photoshop or Unity readiness row cannot cover multiple
capabilities.

Qualified-selection reanalysis now has bounded start/status/cancel services that re-read the signed
Task Workspace and accept only a server-resolved exact capability selection. The remaining product
gate is the authoritative selection/link receipt from Capability Center into the Learning Studio
UI. A completed Toolsmith review job or matching prose cannot choose the capability, activate it,
or authorize execution.

The physical readiness evaluator now emits `corpus_digest` and `accepted_case_ids` derived from its
exact input cases. These are evidence identifiers, not lifecycle authority.

## Independent Unity attestor operator setup

The attestor is a separately administered service or operator. It may inspect the completed Unity
qualification and disposable target, sign its own evidence, and publish a bounded JSON snapshot. It
must not hold Forge promotion credentials, and Forge must not hold its private key.

1. Generate an Ed25519 key pair outside Forge. Retain the private key in the attestor's approved
   secret manager; provide Forge only the Base64 raw 32-byte public key and reviewed attestor ID.
2. Publish a regular, non-symlink JSON file no larger than 4 MiB with schema
   `fabric.unity-disposable-attestation-feed.v1` and a `records` array. Mount that file read-only in
   Forge; replace snapshots atomically and retain their version/checksum in the attestor system.
3. Configure only `FORGE_UNITY_DISPOSABLE_ATTESTATION_FILE`,
   `FORGE_UNITY_DISPOSABLE_ATTESTOR_ID`, and
   `FORGE_UNITY_DISPOSABLE_ATTESTOR_PUBLIC_KEY`. No private-key variable exists.
4. For a completed `review_ready` Unity qualification, independently verify the disposable target,
   isolation, requested operation, readback, package identity, active Toolsmith session and restored
   session. Sign one exact `fabric.unity-disposable-target-attestation.v1` record bound to its Studio
   job ID, candidate digest and qualification-receipt digest with a short explicit expiry.
5. An authenticated Master submits only `{"job_id":"…"}` to
   `POST /api/admin/capabilities/unity-disposable-attestation/complete`. Caller-supplied records,
   stores, keys, or trust roots are rejected. A valid record removes the named evidence gap while
   the result remains `review_ready`, `review_only=true`, `production_ready=false`, and entirely
   non-authorizing.

For a local operator bootstrap, create the identity in a directory that the Forge service does not
own, then pin only its public outputs:

```bash
venv/bin/python tools/unity_disposable_attestor_operator.py bootstrap \
  --state-dir "$HOME/.local/share/forge-unity-attestor" \
  --attestor-id local-unity-disposable-attestor
venv/bin/python tools/forge_up.py configure-unity-attestor \
  --feed "$HOME/.local/share/forge-unity-attestor/attestations.json" \
  --attestor-id local-unity-disposable-attestor \
  --public-key-file "$HOME/.local/share/forge-unity-attestor/attestor-public-key.base64"
```

The bootstrap command is create-only and issues no evidence. The configuration command merges the
three public pins into the existing `runtime.env`, preserves emergency-stop and profile settings,
and rejects a private signing-key setting. A fresh service-manager boot is required after changing
the pins.

For the 2D Iconic Item capability, Forge exports one inert request from the exact completed durable
job. A different reviewer inspects the disposable Unity project and receipts, then uses the
attestor-owned key to append a short-lived signed record:

```bash
venv/bin/python tools/unity_disposable_attestor_operator.py export-iconic-request \
  --jobs-file /absolute/path/to/.studio_jobs.json \
  --job-id <completed-studio-job-id> \
  --output /absolute/path/to/iconic-attestation-request.json

# Run by the independent Unity reviewer, outside the Forge service identity:
venv/bin/python tools/unity_disposable_attestor_operator.py attest-iconic \
  --state-dir "$HOME/.local/share/forge-unity-attestor" \
  --attestor-id local-unity-disposable-attestor \
  --request-file /absolute/path/to/iconic-attestation-request.json \
  --reviewer-id <independent-reviewer-id> \
  --review-note "Disposable import, exact readback, clean console, and rollback reviewed."
```

The signed record remains nonproduction and non-authorizing. Within its expiry, an authenticated
Master submits only the completed job ID to the completion endpoint above. Forge resolves the
server-owned feed, verifies the pinned signer and exact digests, and closes only the independent
qualification gap. Production promotion is still a separate governed lifecycle decision.

An empty, correctly configured feed returns `unity_attestation_evidence_required`; that proves the
trust boundary is configured without fabricating evidence. Missing configuration returns
`unity_attestation_authority_unconfigured`; tampered, foreign, stale, duplicate, symlinked, or
binding-mismatched evidence fails closed.

## Explicit non-goals

- No benchmark cases are generated or duplicated.
- No reviewer receipt, consent, certificate, commission, or notary result is synthesized.
- No agent is enabled and no live-control lease is acquired.
- No package is built, signed, submitted, stapled, or distributed.
- No game asset, GOTM checkout, Git remote, or Perforce depot is changed.
