# Phase 0.9B observer result contract Status: **HOST CONTRACT ONLY — NO TARGET IMPLEMENTATION**. This contract defines how a future observer result would be represented after startup, exit and output gates are separately proven. It does not establish those capabilities and does not authorize transfer or execution. ## Framing The preferred representation is bounded JSON Lines because every entry can be validated independently and a final entry can mark truncation or failure. Whether JSON Lines is feasible without unacceptable target dependencies remains unproven. Every future entry must contain: ```json { "schema_version": 1, "observer_build_id": "offline-bound identifier", "observation_id": "unique bounded identifier", "category": "firmware", "source": "exact source identity", "raw_value": null, "raw_error": "UNSUPPORTED_OR_UNPROVEN", "normalized_value": null, "confidence": "UNPROVEN", "persistent_mutation_performed": false, "retry_performed": false, "monotonic_offset_ms": null, "truncation": false, "fail_closed": true } ``` Allowed confidence values are `OBSERVED`, `PARTIAL`, `UNSUPPORTED`, `UNPROVEN`, `CONFLICT`, and `ERROR`. `raw_value` and `raw_error` are mutually exclusive. A normalized value may be present only when it cannot hide a raw discrepancy. The raw values from two firmware sources are always returned separately. ## Fixed limits No target constants are selected while the build is blocked. A future observation plan must bind all of these to finite positive values: - maximum complete output bytes; - maximum entry bytes; - maximum path bytes; - maximum observations; - maximum objects; - maximum processes; - maximum services; - maximum listeners; - maximum errors; and - maximum monotonic runtime. An exceeded limit produces one final bounded error when the output channel still works, sets `truncation=true` and `fail_closed=true`, performs no retry, and exits through the proven termination path. ## Per-category rules | Category | Success evidence | Required failure form | |---|---|---| | observer identity | offline manifest identity repeated unchanged | `UNPROVEN` if runtime self-binding is not available | | firmware | two separately sourced raw values and exact comparison | `UNPROVEN` for a missing source; `CONFLICT` for mismatch | | mount | only fields with exact ABI evidence | `UNSUPPORTED` for unproven layouts or semantics | | object metadata | literal authorized path, no-follow open, stable pre/post same-object metadata | explicit symlink, path, object-ID or size error | | SHA-256 | exact planned size, complete bounded read, stable post-read object | short read, read error, drift or hash mismatch | | rollback object | same rules plus a distinct available identity from live | backup missing or same-object conflict | | processes/services | bounded read-only snapshot with exact structures | `UNSUPPORTED` when service mapping is incomplete | | listeners | bounded read-only snapshot with exact owner mapping | `UNSUPPORTED` when API or ownership is unproven | | autoload | minimal fields from complete authoritative sources | missing source, parse error or incomplete-source `UNPROVEN` | No file content unrelated to the minimal autoload/retry decision may be returned. Secrets and full configuration contents are excluded. ## Filesystem contract A future target may read an object only when its compiled and audited path is: ```text authorized literal path -> open read-only + no-follow + close-on-exec -> fstat same descriptor -> validate regular object and planned size -> one bounded read stream -> fstat same descriptor -> compare identity and size -> no-follow path metadata comparison -> close ``` If no-follow is not source- and artifact-proven, the result is `PATH_SYMLINK_SAFETY_UNPROVEN` and the object is not hashed. No path is hardcoded by Phase 0.9B. The default observation plan contains no paths. Reads may affect atime, caches, audit records, counters or scheduling. Those volatile or unknown effects must be reported; this contract does not call them absent and does not authorize persistent writes. ## Terminal behavior Every future path, including output failure, deadline, unsupported query, parse error, read error, limit exhaustion and conflict, must reach the proven termination path. No retry, sleep-and-retry, callback, background thread, listener, process signal, service action or subprocess may occur. The host-only model in `tests/phase09b_observer_model.py` exercises these contract decisions without filesystem or network I/O. It is a guardrail, not PS5 code or hardware evidence.