Commit graph

4 commits

Author SHA1 Message Date
0xkite
5c48e5fd8a
fix(control): report start replay disposition, hard-cap jsonl audit journal, deterministic control tests
MEDIUM 1: session_runtime::start() now returns an explicit
fresh-launch vs replay disposition (session_start_result), and
handle_start_session sets outcome.applied only for a fresh committed
launch. An authenticated idempotent start replay therefore never gains
connection-scoped teardown authority: a broken pipe during a replay can
no longer stop an already-running guest. The control audit event for a
replayed delivery carries the replay disposition
(start_session:replay:<session>).

MEDIUM 2: jsonl_sink truncation now accounts for record delimiters
exactly, so current_bytes_ always tracks the physical file; only
newline-terminated complete records are retained (no blank or partial
lines, bounded read window); the cap is a hard cap (an oversized event
is dropped with a structured operator note; a pre-existing oversized
journal is bounded with a bounded read at construction).

MEDIUM 3: the broken-pipe degrade test now synchronizes through a
mutex-protected condition-variable gate handshake that proves the
dispatch is parked inside the blocked gate before the client resets,
records the start only after the dispatch completes, and the
mark_stopping test destroys every registry lock holder (runtime,
protocol, registry) before the independent registry reopen so the
nonblocking exclusive flock can actually be acquired.
2026-08-31 09:34:45 -06:00
0xkite
4c49af1660
fix(control): bind degradation to authenticated outcomes and bound the control audit journal
Closes the sol-audit blockers in dd7d3f3:

HIGH - degradation could not stop the guest. create() moved
config.runtime into the protocol and then stored the moved-from config,
so the degrade path always saw an empty runtime pointer and a guest
launched by start_session outlived its vanished controller connection.
The server now shares the live runtime with the protocol (copy on
compose, one owner of teardown authority), and a Linux-gated server test
drives the real create() -> handle_frame -> broken-pipe path and proves
the guest is torn down (fails on the pre-fix ownership bug).

MEDIUM - degradation was not bound to authentication/application. The
degrade path re-decoded the raw frame to extract start_session and its
session id, granting teardown authority with no auth/schema/deadline or
application evidence; a same-UID peer could reset the socket after
submitting a valid-shaped but unauthorized frame to trigger stop() on a
named session. handle_frame now emits structured
receipt_control_outcome metadata (authenticated / applied /
response_success / method / session_id) from the real dispatch, and
degrade_failed_delivery acts only on genuinely authenticated+applied
start_session outcomes; every other outcome records only the
connection-scoped audit event. The raw frame is never re-decoded.

MEDIUM - control-audit.jsonl guarantees. jsonl_sink::record() is now
bounded by an optional max_file_bytes policy with oldest-record
truncation (newest event always attempted); gloved configures the cap
(host::control_audit_max_file_bytes, 4 MiB) with a bound test.
record_control_delivery_audit() surfaces sink write failures as
structured stderr logs instead of discarding them (receipt-chain audit
guarantees stay fatal). The derived control-audit.jsonl path is
registered in all_configured_paths() so it cannot alias the receipt
journal, audit key, session store, or any other configured path, with a
config-distinctness test.

MEDIUM - tests missed the production failure mode. The degrade test now
constructs the real server through create() and drives a real
authenticated+applied start_session over the socket; the broken-pipe
test synchronizes on an observable (runtime recorded the applied start)
before the client resets, removing the reset-vs-write race; a protocol-
level test proves wrong-secret / expired-deadline / rejected / non-start
outcomes never stop the guest; the Linux executor test asserts the
durable mark_stopping ordering survives an independent registry reopen.

LOW - unified the duplicate wire::rpc_error / response envelope in
remote_protocol.cpp with receipt_wire.hpp (ODR hazard).

Validated: clang build + CTest 80/80 local; Ghost g++14.2 build and
CTest in a follow-up artifact. No push.
2026-08-31 08:19:39 -06:00
trvon
a8137db76b
feat(control): neutral guest channels, quarantine recovery, capability sealing, local-service proxy
Introduce the framed guest_channel_transport with shared deadlines and
std::jthread ownership, metadata-only retired-schema quarantine with
fail-closed integrity, stateless frozen-catalog validators with
capability pinned to zero, and the generic local-service proxy with
descriptor-pinned endpoints, alias-only guest sockets, audit-gated
delivery, and a Linux managed runtime capability derived only from a
registry-bound operational factory. Sage vocabulary is confined to
src/adapters/sage.
2026-08-30 20:28:41 -06:00
0xkite
0dafbed1e8
Initial Glove sandbox baseline 2026-07-19 21:06:11 -04:00