Commit graph

49 commits

Author SHA1 Message Date
0xkite
00d7c47338
refactor(control): sol audit remediations — fail-closed recovery test, cut dead seam hooks, consolidate identifier grammar
Add the fail-closed recovery regression: reopening a store holding
durable observation intents must fail without the registered schema
table — neither a null channel host nor an empty one (no registered
schemas) can admit the frozen intents, so recovery is refused at the
session_registry_impl.hpp channel guard.

Cut speculative generality with no consumer: the channel_descriptor
on_exchange callback and its exchange_hook plumbing in
enqueue_observation_intent return when the wallet-bridge unification
lands; likewise channel_host::catalog() and channel_catalog_entry had
zero callers and no authorized RPC.

Consolidate the identical 128-byte bounded charset identifier and
64-hex digest grammar (previously duplicated in guest_channel.cpp,
session_registry_impl.hpp, and observation_intent_unix_server.cpp)
into src/control/channel_identifier_grammar.hpp without changing
semantics, and document the cached-replay vs registry-replay response
divergence plus that channel_id is registration metadata only
(registry admission matches by schema_id).
2026-08-29 16:15:17 -06:00
0xkite
4a487dafdb
feat(control): generalize the guest specialized-channel layer
Generalizes the PR #23 guest observation plumbing into a schema-agnostic
specialized-channel layer while keeping all harness policy out of core.

Generalized admission (F2/HIGH):
- New channel_descriptor/channel_host interface (include/glove/control/
  guest_channel.hpp): hosts register {channel_id, schema_id,
  body_validator, bounds{max_items, max_body_bytes, max_ttl_ms,
  max_skew_ms}, on_exchange} at registry construction; core keeps only
  structural invariants (identifier charset, digest hex, TTL/skew
  arithmetic, capacity, idempotency) and delegates body semantics to
  registered validators.
- The closed two-schema check in session_registry internals is removed:
  glove_observation_schema, glove_sxxx_proposal_* constants and the
  fixed SXXX digest move out of session_registry_impl.hpp. The Sage
  schemas are now registered by the harness adapter
  (apple_detail::sage_guest_channel_host) and gloved_main wires the host
  into the registry; schema strings appear only in harness-adapter and
  test-fixture registration examples.
- enqueue_observation_intent binds intents to the session's PARSED
  runtime_id; the hardcoded sage_guest_runtime equality checks are
  removed from session_registry.cpp, session_registry_recovery.cpp and
  valid_record_shape. Replay of a now-unregistered schema fails closed
  (open_or_create rejects stores carrying unadmitted intents), and
  enqueue without an admission table is rejected. The observation
  socket server takes runtime_id from configuration instead of
  hardcoding "sage-guest". The observation body hash domain becomes the
  harness-neutral "glove.observation-body.v1" (pre-merge delta; no
  on-disk compatibility is preserved).

Recovery fix (F1/HIGH):
- same_session_snapshot now neutralizes state, running_at_ms and
  policy_revision before comparing frozen intent/disposition snapshots
  against the bound session record, so lifecycle progression and policy
  revision advances never read as a binding crossing; every other
  frozen-field difference still does. Exposed for tests. Regression
  tests cover running->stopping and stopping->exited transitions plus a
  late post-exit disposition end to end (destroy/reopen), and a
  snapshot-identity unit test pins the neutralization (and proves
  non-neutralized fields still cross). Note: an empirical probe showed
  the previously-claimed failure does not reproduce under ordered
  journal replay because intent/disposition records freeze the session
  record they were appended from; the neutralization is applied as the
  defensive fix the memo requires and is now pinned by tests.

Hardening:
- F3: peer-uid verification (SO_PEERCRED / LOCAL_PEERCRED) on observation
  socket accepts, configurable expected uid, rejecting unexpected peers
  before any frame is read.
- F4: the replay cache is a bounded LRU (configurable capacity), so the
  old fixed 1024 cap can no longer permanently kill the channel; the
  durable registry remains the authoritative idempotency layer.
- F5: transient wait/accept errors (EINTR/EAGAIN/ECONNABORTED/EMFILE/
  ENFILE/ENOBUFS/ENOMEM) are retried inside serve_one_for with a bounded
  backoff ladder; only persistent or fatal errors surface. The Apple
  worker loop absorbs persistent failures up to a consecutive-failure
  bound and emits an audit event (new audit action "observation") on
  repeated failures instead of dying on the first hiccup.
- F6: env/mount names generalized to GLOVE_GUEST_OBSERVATION_SOCKET /
  GLOVE_GUEST_OBSERVATION_TOKEN_FILE and the in-container token path to
  /home/agent/.glove-observation-token (Apple runtime, docs).

Apple boundary: the soft lifecycle_operational() definition is unchanged;
the lifecycle-disabled lane now additionally asserts start_session/
stop_session deny with method_not_found and leave the registry untouched
(denial before side effects; the observation service only constructs
inside a lifecycle-gated start).

Docs: architecture.md and session-policy.md describe the guest
specialized-channel admission model and the peer-uid/env naming.

Validation (umask 0022):
- cmake --preset dev/asan/tsan + build + ctest: 100% (76/76) in each
  configuration; asan/tsan are warnings-as-errors builds.
- git diff --check clean; changed files clang-formatted with Homebrew
  llvm@22 against the repo .clang-format.
- No fuzz target exists for the queue/registry (fuzz/ covers plans,
  bundles, manifests, MCP codec, jsonpath only), so no fuzz corpus run.
- control_remote_validation_executor is a pre-existing load-sensitive
  sleep-race test; it flakes identically on the unmodified pr23-head
  baseline under CPU load (verified 1/6 both trees) and always passes
  isolated.

Files: 23 changed (+~1500/-~360), including new guest_channel.{hpp,cpp}.

Signed-off-by: 0xkite <me@hack4kites.dev>
2026-08-29 16:04:27 -06:00
velinussage
61762c1ce0 Add a closed SXXX proposal envelope 2026-08-29 13:37:15 -04:00
velinussage
05c3571b33 Expose expired observation intents for reconciliation 2026-08-29 01:48:49 -04:00
velinussage
0746fc3fcb Make observation disposition replay durable 2026-08-29 01:36:55 -04:00
velinussage
2fa18a2e97 Connect Sage guest observations to managed sessions 2026-08-29 01:32:19 -04:00
velinussage
4385e1b5ee Add per-session guest observation socket 2026-08-29 01:04:55 -04:00
velinussage
483400f887 Expose observation intents through host control RPC 2026-08-29 00:51:37 -04:00
velinussage
5c2d11a82e Add durable Sage observation intent queue 2026-08-29 00:34:21 -04:00
velinussage
ca8600a739 Complete Apple managed resource receipts 2026-08-28 22:52:09 -04:00
velinussage
583608c31b fix: close Apple lifecycle review gaps 2026-08-28 21:53:35 -04:00
velinussage
7f2118c325 phase-3 Add read-only Sage guest projection
Bind digest-addressed Sage bundles and immutable guest identity into the constrained Apple Container runtime.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 20:53:11 -04:00
velinussage
a9e659c7a5 phase-2 Fix macOS managed session lifecycle
Enable platform-neutral control dispatch and bind Apple Container projection evidence into authenticated terminal receipts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 19:43:02 -04:00
0xkite
3ba6ce46a1
fix(adoption): align snapshot digest ordering
Revalidation walked immutable payloads depth-first while planning hashed a flat lexicographic path sequence. Sort bounded descriptor-safe records before hashing so valid adopted Pi packages retain their canonical identity.
2026-08-23 21:19:23 -06:00
0xkite
d2884cdef9
test: add managed client adoption matrix 2026-08-23 09:18:59 -06:00
0xkite
e3efe3bffc
fix(test): isolate contained leak sanitizer 2026-08-23 08:33:33 -06:00
0xkite
ef7413232c
fix(test): scope leak tracing to parent 2026-08-14 18:40:38 -06:00
0xkite
e0faa4e6bc
fix(ci): isolate namespace test leak tracing 2026-08-14 17:50:56 -06:00
0xkite
fda02033a0
fix(ci): pin compatible macOS fuzzer LLVM 2026-08-14 17:03:08 -06:00
0xkite
ad02703151
fix(ci): require complete designated initializers 2026-08-14 15:27:14 -06:00
0xkite
434d86d9c2
fix(host): seal snapshots after publication 2026-08-14 14:16:33 -06:00
0xkite
afa46f901a
style: apply pinned clang-format baseline 2026-08-14 13:20:48 -06:00
0xkite
127fe80052
test(glove): register workerd supply-chain test in CTest
Register tests/scripts/test_fetch_workerd.py (30 network-free checks of the pinned workerd tool) as the workerd_supply_chain CTest entry, so the supply-chain verification runs in the normal ctest suite.
2026-08-13 07:01:38 -06:00
trvon
780664f3af
fix(validation): correct workerd socket probe
Check the actual hexadecimal port for 8787 and bound validator cleanup with a TERM-to-KILL fallback.
2026-08-12 12:29:12 -06:00
trvon
afecee2c90
feat(remote): add construction-only backend
Co-authored-by: trvon <git@trevon.dev>
Signed-off-by: trvon <git@trevon.dev>
2026-08-07 22:27:35 -04:00
trvon
22e7c2de50
fix(onboarding): harden setup plan
Derive runtime templates before setup validation so reruns preserve existing policy. Redact policy JSON by default to avoid exposing owner-local details.
2026-08-03 09:19:50 -04:00
trvon
c3a6c1b7d1
feat(adoption): harden Pi harness sessions
Bind Glove-owned Pi adoption snapshots to launch profiles and receipts while keeping host state out of private homes. Add an offline hostile-content policy and repeatable Linux service setup.
2026-08-02 18:10:55 -04:00
trvon
825a129fbd
feat(refinement): evaluate fixtures in sandbox
Model and PTY cannot self-report pass or failure. Glove now runs
each refinement-eval-v1 session through a declarative evaluator that
checks bounded fixture assertions (termination cause, exit code, max
latency, required and forbidden transcript literals) against audited
resource events, then binds the evaluated outcome inside the
authenticated receipt digest. Capability advances to version 1 with
the evaluator landed.
2026-07-31 16:07:43 -04:00
trvon
2ab53bcc35
feat(refinement): define evidence protocol 2026-07-31 14:08:28 -04:00
0xkite
497e703e70
feat(runtime): manage sandboxed agent sessions
Keep credentials and network access behind authenticated, audited brokers while binding launch adapters, immutable closures, recovery identities, receipts, and cleanup to the approved plan. Add Apple Container and Linux release lanes without weakening the outer sandbox.
2026-07-30 08:49:42 -04:00
0xkite
3f3e219cf8
feat(linux): broker audited agent egress
Keep agents in a route-less network namespace and pass only private-loopback connections over an inherited Unix descriptor channel. The host relay targets the per-run authenticated proxy, preserving exact allowlists and audit evidence without exposing host networking.
2026-07-29 17:33:13 -04:00
0xkite
36b6e4c030
feat(host): derive immutable runtime closure
Resolve safe shebang interpreters and exact package roots during staging so operators do not need broad manual grants. Credential homes remain outside the generated closure and unsupported interpreter shapes fail closed.
2026-07-29 17:33:02 -04:00
0xkite
eb7f5b1750
fix(host): recover missing runtime state 2026-07-29 17:32:44 -04:00
0xkite
bf53ba4a48
feat(host): guide managed harness setup
Detect and bind operator-installed harnesses through explicit, digest-bound runtime policy. Keep macOS and Linux shipping lanes capability-aware and fail closed when isolation evidence is absent.
2026-07-29 16:15:04 -04:00
0xkite
b96bc76a53
fix(runtime): harden managed host launches
Run the Linux service in a delegated user and mount namespace and preserve precise owner-local launch diagnostics while keeping remote denials generic.

Accept validated v2 session plans without bypassing direct-write consent, and bind explicit native runtimes through the same managed launch and receipt boundary.
2026-07-29 12:47:23 -04:00
0xkite
d09032b30e
feat(supervisor): enforce native harness sessions
Bind runtime homes, mounts, and receipts to verified adapter context.\nReject malformed launch encodings before execution.
2026-07-28 11:00:17 -04:00
0xkite
82236d9501
feat(supervisor): generalize native harness launch 2026-07-28 00:16:04 -04:00
0xkite
67f0acf716
fix(control): implement authenticated health RPC 2026-07-22 13:26:48 -04:00
0xkite
3e9cd0680c
test(journal): inject append failures
Exercise partial-write plus disk-full and sync failures to prove rollback, retry, and replay behavior.
2026-07-21 22:25:05 -04:00
0xkite
6081eb8884
test(fuzz): cover untrusted parser boundaries 2026-07-21 22:23:45 -04:00
0xkite
8fecc3f142
fix(mcp): reject mismatched JSON-RPC IDs 2026-07-21 22:23:19 -04:00
0xkite
1bbe530fd5
test(linux): use runner-owned exec fixture 2026-07-20 21:08:57 -04:00
0xkite
ab65827506
ci: exercise privileged Linux containment 2026-07-20 19:57:18 -04:00
0xkite
55b0dc0725
ci: align macOS build with AppleClang 2026-07-20 19:06:08 -04:00
0xkite
8f50e47816
feat(host): manage the gloved user service 2026-07-20 16:50:26 -04:00
0xkite
11d603a1cf
Add host setup and project enrollment workflow 2026-07-20 10:30:29 -04:00
0xkite
0fe581b028
Add bounded path exposure and retained apply controls 2026-07-20 08:59:38 -04:00
0xkite
176d032723
feat: expose managed session readiness boundary 2026-07-19 22:01:13 -04:00
0xkite
0dafbed1e8
Initial Glove sandbox baseline 2026-07-19 21:06:11 -04:00