From 7ceac4372d38354ae345eb40bc31c1cdbd39e4e5 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 11 Oct 2026 18:31:04 +0200 Subject: [PATCH] Publish reviewed bounded JWT ready handoff and retained owner history Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade --- ...6-10-11-key39-producer-v3-net-refusal.json | 60 ++++++ ...26-10-11-key39-producer-v4-net-review.json | 67 +++++++ .../2026-10-11-key39-ready-v9-net-review.json | 89 +++++++++ ...-10-11-key39-ready-v9-net-work-record.json | 9 + .../keycape/openbao-negative-node-route.md | 90 ++++++++- .../keycape/openbao-negative-node-wrapper.py | 183 ++++++++++++++++++ .../k8s/keycape/openbao-negative-session.py | 58 +++++- .../k8s/keycape/test_openbao_node_route.py | 2 +- .../k8s/keycape/test_openbao_private_input.py | 2 +- .../k8s/keycape/test_openbao_private_ready.py | 165 ++++++++++++++++ workplans/ADHOC-2026-10-11.md | 50 +++++ 11 files changed, 770 insertions(+), 5 deletions(-) create mode 100644 docs/reviews/2026-10-11-key39-producer-v3-net-refusal.json create mode 100644 docs/reviews/2026-10-11-key39-producer-v4-net-review.json create mode 100644 docs/reviews/2026-10-11-key39-ready-v9-net-review.json create mode 100644 docs/reviews/2026-10-11-key39-ready-v9-net-work-record.json create mode 100644 sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py create mode 100644 sso-mfa/k8s/keycape/test_openbao_private_ready.py diff --git a/docs/reviews/2026-10-11-key39-producer-v3-net-refusal.json b/docs/reviews/2026-10-11-key39-producer-v3-net-refusal.json new file mode 100644 index 0000000..ab3fd5d --- /dev/null +++ b/docs/reviews/2026-10-11-key39-producer-v3-net-refusal.json @@ -0,0 +1,60 @@ +{ + "reviewer": "net-kingdom", + "formal_role": "native-consumer source owner only", + "disposition": "changes_requested", + "proposal_id": "KEY-WP-0039-T02/private-producer-handoff-v3", + "manifest_sha256": "569672ecdb3f1f5b46122183dc3b82e83ff168c07c87db7211ec26bc1ce6184a", + "compatible_consumer_manifest_sha256": "84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14", + "adapter_sha256": "faf63a3e9504dcbb46847a114275f83d508521e095410a47f92f02b86ba82b1b", + "launcher_sha256": "2a54568df541c38d43ca2482f037761770e6df206fb1cb88c1222ed7291f5e98", + "work_record": { + "task": "NK-WP-ADHOC-2026-10-11-T07", + "status": "done", + "actual_baseline_sha256": "6300d9d47a59a830dd32c4106441771f7227f094f351956502dbff11507b19bb", + "staged_refinement_sha256": "37d7eba09c3aa07d9efd369872f77f24522290a88aeaf149058bb84393da8cf0", + "preserved_v9_anchor_sha256": "90d34dd5520f998c269529c53de4ebb065328d3f6d8ae79cbb215b19344b1cf7", + "anchor_completed_before_formal_review": true + }, + "findings": [ + { + "id": "NET-PRODUCER-V3-F01", + "severity": "high", + "location": "scripts/openbao_negative_private_launcher.py:read_public/main", + "description": "main opens and reads caller contract before entering any total deadline. Actual CLI named FIFO contract stays blocked silently; offline subprocess terminated after 0.254s. Source contract acquisition has no finite bound, and bare open accepts nonregular paths. V2 reproduces too. This does not imply private bytes delivered.", + "required_change": "Bound initial contract acquisition and subsequent preparation with one nonrenewable hard elapsed budget; O_NOFOLLOW/O_NONBLOCK regular bounded stable public files should refuse FIFO/symlink/source races before private file access. Add actual CLI FIFO/stalled-read/oversize checks; preserve frozen V3." + } + ], + "coverage": { + "maker_tests_passed": 33, + "independent_paired_tests_passed": 9, + "actual_cli_fifo_counterexamples": 2, + "exact_pins_matched": 22, + "paired_execution": "Local fake SSH replaces transport only; actual pinned node wrapper and actual child main/source/window/ready/bounded-input run. Health function returns a fixture digest, native execute records only receipt boolean, Kubernetes function raises if invoked. No network or native operations.", + "cases": [ + "valid complete pair", + "wrong nonce zero private loads", + "extra marker key zero private loads", + "health failure zero private loads", + "expired envelope zero transport and private loads", + "changed source pin zero transport and private loads", + "child stdout suppressed; completion unknown", + "stalled marker zero private loads and local teardown", + "actual 4096 capacity partial pipe write; sticky unknown after teardown" + ], + "earlier_refusals_retained": [ + "a1ed14e6b2db1ae77c3fd638fd7e47b5bd50c25eebba418e31aba89bb4b7f88e", + "8353eb8aae11be8ce874887d6a5ca10bf37c6fba73c3f85f0644a7546dd7d33f" + ] + }, + "accepted_source_properties": [ + "Actual child-ready marker precedes private file loads/delivery in owner launcher graph. Marker binds fresh nonce/exact pins/health/window but is not authenticated authority.", + "Adapter enforces kernel identity distinct stdio/control/data pipes and nonresetting clipped delivery timer.", + "V3 propagates unknown private delivery into sticky consumer unknown before early return and local teardown.", + "Exclusive same-UID directory custody explicitly required; non-atomic stat/unlink and remaining copies acknowledged. Unsigned JWT decoded shape does not authenticate issuer." + ], + "native_executed": false, + "credentials_read": false, + "native_or_transport_admitted": false, + "founder_go_granted": false, + "task_closure_inferred": false +} diff --git a/docs/reviews/2026-10-11-key39-producer-v4-net-review.json b/docs/reviews/2026-10-11-key39-producer-v4-net-review.json new file mode 100644 index 0000000..f991b61 --- /dev/null +++ b/docs/reviews/2026-10-11-key39-producer-v4-net-review.json @@ -0,0 +1,67 @@ +{ + "reviewer": "net-kingdom", + "formal_role": "native-consumer source owner only", + "disposition": "approved", + "qualification": "Exact paired source agreement only; no transport, private custody, issuer authentication, native authorization or task closure inferred.", + "proposal_id": "KEY-WP-0039-T02/private-producer-handoff-v4", + "manifest_sha256": "d6f641dc1e4aae7d36658d4199d89af14d2fd7a4bd4e526856eb340234f2d33e", + "compatible_consumer_manifest_sha256": "84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14", + "adapter_sha256": "faf63a3e9504dcbb46847a114275f83d508521e095410a47f92f02b86ba82b1b", + "launcher_sha256": "46e57504b3185cc13f1656901a0ca02cc3887527cb09566e270f57b76099ab9c", + "work_record": { + "task": "NK-WP-ADHOC-2026-10-11-T07", + "status": "done", + "actual_baseline_sha256": "6300d9d47a59a830dd32c4106441771f7227f094f351956502dbff11507b19bb", + "staged_refinement_sha256": "ea3cd23484aecb9d2b5fe72356f279cd08d323f8cfd53f2af2d070018fae5391", + "preserved_v9_anchor_sha256": "90d34dd5520f998c269529c53de4ebb065328d3f6d8ae79cbb215b19344b1cf7", + "completed_before_formal_review": true + }, + "findings": [], + "corrected_findings": [ + { + "refusal_sha256": "38abf660701194f85934a076a0c01d3047e6bfe790e02ba1b0e4616e356634e6", + "finding": "NET-PRODUCER-V3-F01", + "verification": "Actual CLI FIFO, symlink and oversized public contract now refuse promptly; O_NOFOLLOW/O_NONBLOCK regular single-link stable source reads run under original main preparation deadline. Slow acquisition and default launch validation have hard elapsed bounds; acquisition plus launch cannot renew deadline." + } + ], + "coverage": { + "maker_tests_passed": 40, + "independent_tests_passed": 13, + "paired_handshake_tests_passed": 9, + "preparation_tests_passed": 4, + "exact_pins_matched": 23, + "paired_execution": "Local fake SSH substitutes transport only. Actual pinned node wrapper and actual child main/source/window/ready/bounded-input run; public health returns fixture digest and native execute records private-pair receipt boolean only. Kubernetes function raises if called. Unsigned synthetic tokens only.", + "cases": [ + "actual wrapper/child readiness and complete private delivery", + "wrong nonce zero token-file loads", + "extra marker field zero token-file loads", + "health failure zero token-file loads", + "expired envelope zero transport or private loads", + "local source mismatch zero transport or private loads", + "child output suppressed with consumer outcome unknown", + "stalled marker zero private loads and local teardown", + "actual 4096 capacity partial pipe with sticky unknown after teardown", + "actual CLI FIFO/symlink/oversize refuse before missing private paths", + "default caller slow validation bounded no spawn/private load", + "actual main slow acquisition bounded no spawn/private load", + "actual main acquisition and launch share original deadline" + ] + }, + "preserved_history": [ + "a1ed14e6b2db1ae77c3fd638fd7e47b5bd50c25eebba418e31aba89bb4b7f88e", + "38abf660701194f85934a076a0c01d3047e6bfe790e02ba1b0e4616e356634e6", + "8353eb8aae11be8ce874887d6a5ca10bf37c6fba73c3f85f0644a7546dd7d33f" + ], + "source_scope_conditions": [ + "Trusted owner launcher must launch admitted exact pinned child/wrapper/envelope over separately founder-admitted captured SSH peer/profile. Marker synchronizes readiness and does not authenticate authority or peer.", + "Exclusive same-UID private directory custody and no concurrent writer required. Stat/unlink is non-atomic; copied credentials may remain and no zeroization/remote cleanup is established.", + "Unsigned JWT decoded claims are shape checks only; issuer/client/agent admission remains owner/founder decision.", + "Unknown partial delivery remains sticky after local transport teardown. Native remote cleanup/acceptance requires separate owner evidence." + ], + "native_executed": false, + "credentials_read": false, + "actual_ssh_executed": false, + "native_or_transport_admitted": false, + "founder_go_granted": false, + "task_closure_inferred": false +} diff --git a/docs/reviews/2026-10-11-key39-ready-v9-net-review.json b/docs/reviews/2026-10-11-key39-ready-v9-net-review.json new file mode 100644 index 0000000..c1a369e --- /dev/null +++ b/docs/reviews/2026-10-11-key39-ready-v9-net-review.json @@ -0,0 +1,89 @@ +{ + "reviewer": "net-kingdom-owner (agent net-kingdom, codex)", + "decision": "approved", + "review_id": "NK-REVIEW-20261011-KEY39-READY-PROTOCOL-SOURCE", + "work_item_id": "NK-WP-ADHOC-2026-10-11-T07", + "reviewed_manifest_sha256": "84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14", + "reviewed_proposal_id": "KEY-WP-0039-T02/attended-lifecycle-v9-ready-input", + "reviewed_source_hashes": { + "sso-mfa/k8s/keycape/openbao-negative-session.py": "24b7b803e4eb7e6e7c0700a069dad0ec315ee7eb5538a88b9e56147f8fab5cdd", + "sso-mfa/k8s/keycape/test_openbao_negative_session.py": "01e23f2b4fc77824a161a57acb3a52d19aad846b3b6c0fd3abd81afa1dc2985c", + "sso-mfa/k8s/keycape/test_openbao_node_route.py": "1c57053be6e8472174e4034fdfbf34b3e1729f5e239b3a9af89d9e59a08d6cb6", + "sso-mfa/k8s/keycape/openbao-negative-node-route.md": "cad3e3dc481d45295cc014e48285e81614911dfb4a10523883f3044f6085f363", + "sso-mfa/k8s/keycape/test_openbao_private_input.py": "84277edb5bd7858885173dea802b6bdc4f0f0c7785d6e200ee9a98d8553891a1", + "sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py": "76ac013d1a676a0dfa58aea1ce87b0c3e72483ccd21f586a22c5475e9132f6c1", + "sso-mfa/k8s/keycape/test_openbao_private_ready.py": "8a7a033b1c509ba21397d1d74580c44f24592045b2b9de50fe87638607224277" + }, + "previous_review_sha256": "b2711c8ff72724751f9c10ce199fa3564b7893aa4c0377df0d3d1611d0a97eda", + "comment": "NetKingdom INTENT Principles 6/7 require bounded exposure and explicit owner responsibility. Exact v9 ready child/node-wrapper manifest 84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14 prepared/reviewed under completed same-trial NK-WP-ADHOC-2026-10-11-T07. Authored owner source agreement for concrete private synchronization and bounded relay. Raw marker or approval JSON is not authenticated authority/peer proof; exact trusted owner launcher/SSH source context and independent KeyCape/Platform reviews are prerequisites. No native, credential, launcher/transport admission or KEY39 closure inferred.", + "findings": [], + "validation": { + "supplied_lifecycle_tests": 46, + "retained_node_route_actual_main_tests": 12, + "retained_private_receive_tests": 7, + "new_ready_wrapper_tests": 9, + "retained_independent_tests": 21, + "unchanged_runner_tests_previously_verified": 17, + "all_passed": true, + "synthetic_offline_only": true, + "ready_protocol_checks": [ + "Distinct local writable pipe, marker exact keys/nonce/executor/envelope/health/window pins and child EOF", + "Actual duplicate stdout pipe alias refusal before marker", + "Wrong nonce/envelope pin produces no ready", + "Actual full pipe write interrupted at original remaining action deadline with signal restoration", + "Actual main health then marker received before first private read; no missing-ack private read", + "Wrapper validates all exact marker fields and typed bounded window; changed/extra fields refuse", + "Incomplete private local ready pipe without EOF interrupted under total bound", + "Wrapper mocked child launch uses local pass_fds and inherited private stdin, no SSH FD forwarding or token copy" + ], + "retained_main_test_adaptation": "Existing input-only sequencing/receive tests stub the new ready emitter; new ready tests exercise actual pipe emission and main ordering separately.", + "native_readiness": false, + "compatible_producer_exact_review_pending": true, + "source_original_baseline": "Current published v8, with original v5 and v6/v7/v8 frozen provenance retained" + }, + "coverage": [ + "Workstation bridge configuration routing metadata and actual -L implementation distinguish node/workstation listener", + "No node Pod DNS assumption; bounded founder foreground node-local gateway Service port-forward proposal and process-specific teardown", + "Public unauth GET only; strict active initialized/unsealed body and digest-only cluster identity evidence", + "Execute initial route refusal before native/Secret access; repeated route loss after dry-runs before first mutation", + "Separate recovery route gate before native/Secret reads; health identity must match exact envelope pin", + "No auth headers, private stdin or Kubernetes in public route-preflight mode; current-process diagnostic does not attest node placement", + "HTTP health shares all existing no-proxy/no-redirect/byte/total-timer/abort guards; slow-health real timer refusal", + "All earlier CAS/deadline/deletion/recovery/known-revoke/unknown-outcome regressions remain", + "Actual main failure tests, not only execute-function mocks: unavailable route and missing health pin prevent stdin.read; recover also consumes no stdin", + "Actual main success ordering verifies health before stdin before execution; original pre-input monotonic window is preserved", + "Source/role/authority revalidation follows private input; expired original monotonic window refuses before runner/native access", + "Actual main binary receive cap 65536 bytes, sized chunk reads and explicit EOF; exact two-token object with per-token UTF-8 byte limits", + "Linux main-thread total receive timer at most 15 seconds clipped to original wall and monotonic remaining budget; no renewal", + "Actual local pipe stalled/no EOF and complete JSON/no EOF regressions; fixed oversized/invalid/late failures before execution", + "Producer-side missing exact-child ready handshake retained as separate explicit native prerequisite; exporter write timeout is not treated as consumer read bound", + "Concrete required local child-ready FD/nonce/approved raw envelope pin before any private stdin read; aliases of all stdio endpoint identities rejected", + "Exact newline marker schema with public source/envelope/health/action-window bindings; hard emission/receive bounds and original action deadline preserved", + "Node-local wrapper constructs its own pipe and pinned Python child, validates ready under one preparation bound, forwards control line only, captures/refuses child output, performs bounded termination/capture-close cleanup", + "No SSH FD forwarding, token stdin read/copy, raw marker authority, raw credential output or warden silent-lane compatibility claimed", + "Independent KeyCape exporter/launcher coordination: newline control framing, no EOF wait on still-open SSHstdout, original producer budget only clips/no reset, no token-file access or delivery before valid exact ready" + ], + "native_prerequisites": [ + "Fresh exact source-reviewed KeyCape launcher/adapter matching ready schema/source/nonce/envelope/health/window, owning admitted captured SSH peer/profile before accepting marker and before any token-file read or write", + "Fresh exact source reviews by Platform and KeyCape", + "Founder exact source/runtime/route/window/cleanup decision", + "Actual same-node route preflight with owner-admitted route and independently confirmed provider identity", + "Exact envelope bao_health_identity_sha256 from current founder preflight; fresh owner role/policy/leeway observation", + "Admitted private human/coding-agent token producer remains separate gap", + "Current headroom/quiet window and actual native negative/revoke/restoration/cleanup acceptance" + ], + "authority_boundary": { + "source_preparation_only": true, + "native_actions": false, + "tunnel_opened": false, + "node_reachability_observed": false, + "owner_checkout_writes": false, + "credential_access": false, + "secret_reads": false, + "foreign_reviews": false, + "founder_approval": false, + "KEY39_task_closure": false + }, + "work_record_anchor_sha256": "f294f1cf152dd797b913f0f31a5b3f7939fa67de9871580b977c74001c40d168", + "retained_correction_history": "V8 receive bounds remain; producer v1 lacks consumer acknowledgment and fails stdio/race claims. Concrete v9 child/wrapper synchronization is a same-trial refinement; compatible KeyCape producer exact source review/admission remains separate. Earlier reviews/stages are unchanged." +} diff --git a/docs/reviews/2026-10-11-key39-ready-v9-net-work-record.json b/docs/reviews/2026-10-11-key39-ready-v9-net-work-record.json new file mode 100644 index 0000000..8045068 --- /dev/null +++ b/docs/reviews/2026-10-11-key39-ready-v9-net-work-record.json @@ -0,0 +1,9 @@ +{ + "repo": "net-kingdom", + "work_item_id": "NK-WP-ADHOC-2026-10-11-T07", + "original_path": "/home/worsch/net-kingdom/workplans/ADHOC-2026-10-11.md", + "original_sha256": "6300d9d47a59a830dd32c4106441771f7227f094f351956502dbff11507b19bb", + "staged_path": "/tmp/keycape-jwt-ready-v9-stage/net-kingdom/workplans/ADHOC-2026-10-11.md", + "staged_sha256": "90d34dd5520f998c269529c53de4ebb065328d3f6d8ae79cbb215b19344b1cf7", + "same_trial": true +} diff --git a/sso-mfa/k8s/keycape/openbao-negative-node-route.md b/sso-mfa/k8s/keycape/openbao-negative-node-route.md index 05db701..292dc7b 100644 --- a/sso-mfa/k8s/keycape/openbao-negative-node-route.md +++ b/sso-mfa/k8s/keycape/openbao-negative-node-route.md @@ -1,6 +1,6 @@ # KEY39 node-local OpenBao route prerequisite -Source-only successor `KEY-WP-0039-T02/attended-lifecycle-v8-bounded-input` of frozen +Source-only successor `KEY-WP-0039-T02/attended-lifecycle-v9-ready-input` of frozen v5. No native preflight, port-forward, login, Secret access or execution has run. Previous v5 source and every review remain unchanged. The new executor and health endpoint need fresh exact source-owner acknowledgments and a founder @@ -127,3 +127,91 @@ acknowledgment bound to that pipe session and window. The current producer v1 has no such protocol; the producer consumer review requests it. V8 supplies no handshake, launcher admission or native readiness and must not be piped to the old exporter as though its health-before-read check prevents early transmission. + +## V9 private ready protocol and concrete node wrapper + +The old producer v1 refusal remains history: a child checking health before +reading stdin cannot prevent an exporter from buffering or transmitting tokens +earlier. V9 execute therefore requires `--ready-fd`, `--session-nonce` and +`--ready-envelope-sha256` before it will read private input. The ready FD is a +locally inherited writable FIFO >=3 whose inode/device differs from every stdio +endpoint; stdout/stderr aliases, regular files and missing FDs refuse. + +After source/approval validation, original-window start and approved public +health, the child emits one <=4096-byte newline JSON marker to that private FD +and closes it. Emission has a total two-second cap clipped to the original +action window. Child stdout and stderr remain quiet. Exact marker fields are: + +```json +{ + "schema": "key39-private-input-ready/v1", + "session_nonce": "", + "proposal_id": "KEY-WP-0039-T02/attended-lifecycle-v9-ready-input", + "target": "sso/keycape", + "executor_sha256": "", + "envelope_sha256": "", + "bao_health_identity_sha256": "", + "valid_until_epoch": 0, + "receive_budget_seconds": 0 +} +``` + +Zeros/placeholders illustrate keys only and are never a valid marker. Epoch is +the exact finite nonboolean approved envelope expiry, still future; receive +budget is finite positive <=15 and clipped at emission to the original action +window. The exporter clips its already-running deadline to the advertised +budget and *current* approval remainder. It must not reset a deadline or demand +that a budget measured at emission equal the smaller remainder after transport. + +`openbao-negative-node-wrapper.py` is the concrete node-local relay. The trusted +launcher supplies nonsecret exact child/envelope paths and SHA256 pins, a new +nonce and exclusive receipt destination. Wrapper envelope must be owner UID, +mode0600, single-link regular file, stable bounded bytes; its child/wrapper +source paths must be included in the exact envelope's native source hash map. +This is reconstruction of the caller's review context, not authenticated human +approval: assertions in JSON cannot create a grant. The founder must separately +admit the exact source/profile, target and SSH peer under the applicable lane. + +The wrapper creates an **ordinary local pipe on the node**, starts the pinned +Python child with that write endpoint passed locally, and reads its bounded +marker plus EOF. The child's private stdin is inherited directly from the SSH +input stream: wrapper never reads, copies, logs or writes token bytes. No extra +file descriptor is forwarded by SSH or OpsBridge. Within one five-second total +preparation deadline, the wrapper validates all marker keys/nonce/pins/window and +forwards exactly one value-free marker line on its own stdout control pipe. +The admitted workstation launcher must own/capture that SSH stdout separately +from its private stdin data pipe, never display/tee/log it, validate the exact +marker and then allow the KeyCape adapter to load/consume caller files or write +ANY token bytes. The control stream stays open while the child runs; the +exporter stops marker reception at newline, not SSH EOF. Missing, partial, +wrong-nonce, stale, oversized or pin-mismatched markers mean zero token file +reads/writes and retained caller files. The old v1 adapter is incompatible. + +This wrapper emits control stdout and therefore **cannot run inside the +warden attended command lane that rejects all child output**. It requires a +separately admitted founder-owned direct SSH profile with no PTY, captured +stdin/stdout/stderr, pinned peer/host identity, exact wrapper/source/receipt paths +and no agent credential access. No such runtime admission is supplied here. +A bare marker, caller boolean or downloaded ready file cannot authenticate a +peer, source execution or founder decision. A trusted reviewed launcher owning +that transport and verifying the context is a prerequisite. + +The wrapper waits only through the original approval remainder plus 300 seconds +cleanup. Any child stdout/stderr is captured with bounded reads and refused, +never forwarded. Failure terminates the exact launched child with bounded five- +second TERM then two-second kill/wait fallback; capture closes have 20 ms caps. +No retry or replay occurs. Interruption, partial private delivery, emitted ready +followed by child death, unconfirmed revoke or interrupted native cleanup remains +unknown/pending owner reconciliation using the separately approved recovery +path. Wrapper exit zero is not owner/native acceptance; the child receipt still +requires actual owner acceptance. No persistent file/copy on the node is added +for token material, and Unix/Python memory cleanup is not secure zeroization. + +Human browser issuance and admitted coding-agent custody remain distinct owner +choices. Any new files must be produced by the pinned verified owner CLI under +continuous exclusive tmpfs custody after the separately admitted route preflight. +They must be prepared before launching this short-lived private receive window; +the child cannot wait for a five-minute browser login after emitting ready. +Fresh registered-client/MFA/custody evidence, exact independent KeyCape/Platform +reviews and the founder's complete route/transport/private-file/native decision +remain required. No native handshake, SSH, credential or route was exercised. diff --git a/sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py b/sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py new file mode 100644 index 0000000..f53ad40 --- /dev/null +++ b/sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +"""Founder-admitted node wrapper: private local child-ready pipe -> SSH control stdout. +No token read/copy, login, tunnel or approval authentication. Parent must capture +stdout over its admitted authenticated SSH peer; never use the silent warden lane. +""" +import argparse +import contextlib +import hashlib +import json +import math +import os +from pathlib import Path +import signal +import stat +import subprocess +import sys +import threading +import time + +SCHEMA='key39-private-input-ready/v1' +PROPOSAL='KEY-WP-0039-T02/attended-lifecycle-v9-ready-input' +TARGET='sso/keycape' +MAX_READY=4096 +MAX_ENVELOPE=65536 +READY_TOTAL_SECONDS=5 + +class Refused(Exception):pass + +def need(ok,code): + if not ok:raise Refused(code) + +def finite(value): + try:return type(value) in (int,float) and math.isfinite(value) + except OverflowError:return False + +def hash_bytes(raw):return hashlib.sha256(raw).hexdigest() + +def hex_pin(value):return isinstance(value,str) and len(value)==64 and all(c in '0123456789abcdef' for c in value) + +@contextlib.contextmanager +def deadline(seconds): + need(finite(seconds) and 00,'wrapper_control_write_failed') + offset+=written + +def run(args): + proc=None;read_fd=None;write_fd=None + try: + need(hex_pin(args.session_nonce),'wrapper_nonce_required') + with deadline(READY_TOTAL_SECONDS): + child=pinned_file(args.child,args.child_sha256,256*1024) + envelope_raw=pinned_file(args.envelope,args.envelope_sha256,MAX_ENVELOPE,private=True) + envelope=decode(envelope_raw) + need(envelope.get('proposal_id')==PROPOSAL and envelope.get('target')==TARGET + and envelope.get('disposition')=='approved' and envelope.get('founder_decision_id'), + 'wrapper_exact_owner_envelope_required') + need(envelope.get('source_hashes',{}).get(str(Path(args.child)))==args.child_sha256 + and envelope.get('source_hashes',{}).get(str(Path(__file__).resolve()))==hash_bytes(Path(__file__).read_bytes()), + 'wrapper_child_and_wrapper_pins_required') + expiry=envelope['valid_until_epoch'];maximum=envelope['maximum_session_seconds'] + need(finite(expiry) and type(maximum) is int and 420<=maximum<=900 + and 00,'wrapper_session_window_expired') + with deadline(remaining): + rc=proc.wait(timeout=remaining) + # Bounded captures: even accidental child output is never forwarded. + unexpected=proc.stdout.read(MAX_READY+1) or proc.stderr.read(MAX_READY+1) + need(not unexpected,'wrapper_child_output_refused') + return 0 if rc==0 else 1 + except BaseException: + return 1 + finally: + for fd in (read_fd,write_fd): + if fd is not None: + try:os.close(fd) + except OSError:pass + if proc is not None: + if proc.poll() is None: + # Unknown/partial native outcomes remain owner recovery, never retry. + try: + with deadline(5): + proc.terminate();proc.wait(timeout=5) + except Exception: + try: + with deadline(2): + proc.kill();proc.wait(timeout=2) + except Exception:pass + for stream in (proc.stdout,proc.stderr): + if stream is not None: + try: + with deadline(0.02):stream.close() + except Exception:pass + +def main(): + parser=argparse.ArgumentParser(description=__doc__) + for name in ('child','child-sha256','envelope','envelope-sha256','receipt','session-nonce'): + parser.add_argument('--'+name,required=True) + return run(parser.parse_args()) + +if __name__=='__main__':raise SystemExit(main()) diff --git a/sso-mfa/k8s/keycape/openbao-negative-session.py b/sso-mfa/k8s/keycape/openbao-negative-session.py index 6123fc8..d360df7 100644 --- a/sso-mfa/k8s/keycape/openbao-negative-session.py +++ b/sso-mfa/k8s/keycape/openbao-negative-session.py @@ -12,6 +12,8 @@ import hashlib import importlib.util import json import math +import fcntl +import stat import os from pathlib import Path import secrets @@ -28,7 +30,7 @@ import yaml CLUSTER = 'a553c742-0115-43d4-99a4-a5ca56fe0786' TARGET = 'sso/keycape' -PROPOSAL = 'KEY-WP-0039-T02/attended-lifecycle-v8-bounded-input' +PROPOSAL = 'KEY-WP-0039-T02/attended-lifecycle-v9-ready-input' IDS = ['openbao-probe-' + c for c in ['aud', 'sub', 'tenant', 'roles', 'scope', 'expiry']] ENVS = ['KEYCAPE_' + c.upper().replace('-', '_') + '_CLIENT_SECRET' for c in IDS] TEMP = 'keycape-openbao-negative-key39' @@ -44,6 +46,8 @@ HTTP_ABORT_SECONDS = 0.02 PRIVATE_INPUT_MAX_BYTES = 65536 PRIVATE_TOKEN_MAX_BYTES = 16384 PRIVATE_INPUT_TOTAL_SECONDS = 15 +READY_SCHEMA = 'key39-private-input-ready/v1' +READY_MAX_BYTES = 4096 class Refused(Exception): @@ -556,6 +560,49 @@ def recover(envelope, receipt): receipt.update(cleanup_verified=True, recovery_only=True) +def emit_private_ready(fd, nonce, expected_envelope_sha256, envelope_sha256, envelope, receipt): + # A value-free synchronization marker, never authentication or a grant. + require(type(fd) is int and fd >= 3, 'private_ready_pipe_required') + require(isinstance(nonce, str) and len(nonce) == 64 + and all(c in '0123456789abcdef' for c in nonce), 'ready_nonce_required') + require(expected_envelope_sha256 == envelope_sha256, 'ready_envelope_pin_changed') + validated = False + try: + current = os.fstat(fd) + require(stat.S_ISFIFO(current.st_mode) + and fcntl.fcntl(fd, fcntl.F_GETFL) & os.O_ACCMODE == os.O_WRONLY, + 'private_ready_pipe_required') + identity = (current.st_dev, current.st_ino) + require(all(identity != (os.fstat(other).st_dev, os.fstat(other).st_ino) + for other in (0, 1, 2)), 'private_ready_stdio_alias_refused') + validated = True + check_deadline() + marker = {'schema': READY_SCHEMA, 'session_nonce': nonce, + 'proposal_id': PROPOSAL, 'target': TARGET, + 'executor_sha256': digest(Path(__file__).read_bytes()), + 'envelope_sha256': envelope_sha256, + 'bao_health_identity_sha256': envelope['bao_health_identity_sha256'], + 'valid_until_epoch': envelope['valid_until_epoch'], + 'receive_budget_seconds': request_budget(PRIVATE_INPUT_TOTAL_SECONDS)} + payload = json.dumps(marker, sort_keys=True, separators=(',', ':')).encode() + b'\n' + require(len(payload) <= READY_MAX_BYTES, 'private_ready_oversized') + with total_timeout(request_budget(2)): + offset = 0 + while offset < len(payload): + written = os.write(fd, payload[offset:]) + require(type(written) is int and written > 0, 'private_ready_delivery_failed') + offset += written + check_deadline() + receipt['private_ready_emitted'] = True + except Refused: + raise + except Exception: + raise Refused('private_ready_delivery_failed') from None + finally: + if validated: + os.close(fd) + + def read_private_input(stream): # Complete private JSON plus EOF, within this original approved action window. # No unbounded read, text buffering, token logging or renewed deadline. @@ -730,6 +777,9 @@ def main(): ap.add_argument('mode', choices=['inspect', 'route-preflight', 'founder-preflight', 'execute', 'recover']) ap.add_argument('--envelope') ap.add_argument('--bao-addr', choices=sorted(BAO_ORIGINS)) + ap.add_argument('--ready-fd', type=int) + ap.add_argument('--session-nonce') + ap.add_argument('--ready-envelope-sha256') ap.add_argument('--confirm') ap.add_argument('--receipt', required=True) args = ap.parse_args() @@ -776,7 +826,9 @@ def main(): probe_ids_absent=True, probe_env_absent=True, temporary_secret_absent=True) else: require(args.envelope is not None, 'approval_envelope_required') - envelope = read_json(Path(args.envelope).read_text()) + envelope_raw = Path(args.envelope).read_bytes() + envelope = read_json(envelope_raw) + envelope_sha256 = digest(envelope_raw) require(Path(args.envelope).stat().st_mode & 0o022 == 0, 'approval_envelope_writable') signal.signal(signal.SIGTERM, lambda *_: (_ for _ in ()).throw(Refused('session_interrupted'))) if args.mode == 'recover': @@ -787,6 +839,8 @@ def main(): start_execution_window(envelope) transport = SessionTransport(envelope['bao_addr'], receipt=receipt) verify_bao_route(transport, envelope, receipt) + emit_private_ready(args.ready_fd, args.session_nonce, args.ready_envelope_sha256, + envelope_sha256, envelope, receipt) private = read_private_input(__import__('sys').stdin) execute(envelope, private, receipt, checkpoint=checkpoint, window_started=True) receipt['negative_and_cleanup_verified'] = True diff --git a/sso-mfa/k8s/keycape/test_openbao_node_route.py b/sso-mfa/k8s/keycape/test_openbao_node_route.py index 8617234..df99444 100644 --- a/sso-mfa/k8s/keycape/test_openbao_node_route.py +++ b/sso-mfa/k8s/keycape/test_openbao_node_route.py @@ -177,7 +177,7 @@ class NodeRouteTests(unittest.TestCase): events.append('execute');self.assertTrue(kwargs['window_started']) self.assertEqual(s.BUSINESS_MONOTONIC_DEADLINE,started['deadline']) with patch.object(sys,'argv',argv),patch.object(s,'SessionTransport') as factory, \ - patch.object(sys,'stdin') as stdin,patch.object(s,'execute',side_effect=execute), \ + patch.object(sys,'stdin') as stdin,patch.object(s,'emit_private_ready'),patch.object(s,'execute',side_effect=execute), \ patch.object(s,'k') as k: factory.return_value.health_identity.side_effect=health stdin.buffer.read.side_effect=private_read diff --git a/sso-mfa/k8s/keycape/test_openbao_private_input.py b/sso-mfa/k8s/keycape/test_openbao_private_input.py index f27644a..cdf9670 100644 --- a/sso-mfa/k8s/keycape/test_openbao_private_input.py +++ b/sso-mfa/k8s/keycape/test_openbao_private_input.py @@ -30,7 +30,7 @@ class PrivateInputTests(unittest.TestCase): receipt=Path(folder)/'receipt.json' argv=['session','execute','--envelope',str(path),'--receipt',str(receipt)] with patch.object(sys,'argv',argv),patch.object(sys,'stdin',stream), \ - patch.object(s,'SessionTransport') as factory,patch.object(s,'execute') as execute, \ + patch.object(s,'SessionTransport') as factory,patch.object(s,'emit_private_ready'),patch.object(s,'execute') as execute, \ patch.object(s,'k') as k,patch.object(s,'get') as get: factory.return_value.health_identity.side_effect=health factory.return_value.health_identity.return_value=r.PIN diff --git a/sso-mfa/k8s/keycape/test_openbao_private_ready.py b/sso-mfa/k8s/keycape/test_openbao_private_ready.py new file mode 100644 index 0000000..7a23c00 --- /dev/null +++ b/sso-mfa/k8s/keycape/test_openbao_private_ready.py @@ -0,0 +1,165 @@ +"""Synthetic ready FD/control transport tests; no SSH/native/credentials.""" +import importlib.util +from pathlib import Path +import fcntl +import io +import json +import os +import signal +import sys +import tempfile +import time +import unittest +from unittest.mock import patch + +spec=importlib.util.spec_from_file_location('routes',Path(__file__).with_name('test_openbao_node_route.py')) +r=importlib.util.module_from_spec(spec);spec.loader.exec_module(r);s=r.s;f=r.f +spec=importlib.util.spec_from_file_location('wrapper',Path(__file__).with_name('openbao-negative-node-wrapper.py')) +w=importlib.util.module_from_spec(spec);spec.loader.exec_module(w) +NONCE='a'*64 + +class ReadyTests(unittest.TestCase): + def setUp(self): + s.CLEANING=False;s.REQUEST_DEADLINE=None;s.BUSINESS_MONOTONIC_DEADLINE=None;s.CLEANUP_MONOTONIC_DEADLINE=None + def marker(self,envelope=None): + e=envelope or f.envelope() + return {'schema':s.READY_SCHEMA,'session_nonce':NONCE,'proposal_id':s.PROPOSAL,'target':s.TARGET, + 'executor_sha256':s.digest(Path(s.__file__).read_bytes()),'envelope_sha256':'b'*64, + 'bao_health_identity_sha256':e['bao_health_identity_sha256'],'valid_until_epoch':e['valid_until_epoch'], + 'receive_budget_seconds':15} + + def test_emit_exact_ready_marker_to_distinct_local_pipe_and_close_endpoint(self): + e=f.envelope();s.start_execution_window(e);read_fd,write_fd=os.pipe();receipt={} + s.emit_private_ready(write_fd,NONCE,'b'*64,'b'*64,e,receipt) + raw=os.read(read_fd,4097);self.assertEqual(os.read(read_fd,1),b'');os.close(read_fd) + obj=json.loads(raw) + self.assertEqual(set(obj),set(self.marker(e))) + self.assertEqual(obj['session_nonce'],NONCE) + self.assertEqual(obj['executor_sha256'],s.digest(Path(s.__file__).read_bytes())) + self.assertTrue(receipt['private_ready_emitted']) + self.assertNotIn('human_token',obj);self.assertNotIn('coding_agent_token',obj) + + def test_stdout_alias_pipe_fd_above_two_refused_without_marker(self): + e=f.envelope();s.start_execution_window(e);read_fd,write_fd=os.pipe();saved=os.dup(1);alias=None + try: + os.dup2(write_fd,1);alias=os.dup(1) + with self.assertRaisesRegex(s.Refused,'private_ready_stdio_alias_refused'): + s.emit_private_ready(alias,NONCE,'b'*64,'b'*64,e,{}) + finally: + os.dup2(saved,1);os.close(saved);os.close(write_fd) + if alias is not None:os.close(alias) + self.assertEqual(os.read(read_fd,4096),b'');os.close(read_fd) + + def test_nonce_or_envelope_binding_failure_emits_no_ready(self): + e=f.envelope();s.start_execution_window(e) + for nonce,pin in [('wrong','b'*64),(NONCE,'c'*64)]: + read_fd,write_fd=os.pipe() + try: + with self.assertRaises(s.Refused):s.emit_private_ready(write_fd,nonce,pin,'b'*64,e,{}) + finally: + try:os.close(write_fd) + except OSError:pass + self.assertEqual(os.read(read_fd,4096),b'');os.close(read_fd) + + def test_actual_full_ack_pipe_write_times_out_inside_original_window(self): + e=f.envelope();s.start_execution_window(e) + s.BUSINESS_MONOTONIC_DEADLINE=time.monotonic()+0.015 + read_fd,write_fd=os.pipe();fcntl.fcntl(write_fd,fcntl.F_SETPIPE_SZ,4096) + flags=fcntl.fcntl(write_fd,fcntl.F_GETFL);fcntl.fcntl(write_fd,fcntl.F_SETFL,flags|os.O_NONBLOCK) + try: + while True:os.write(write_fd,b'x'*4096) + except BlockingIOError:pass + fcntl.fcntl(write_fd,fcntl.F_SETFL,flags) + started=time.monotonic();handler=signal.getsignal(signal.SIGALRM) + with self.assertRaisesRegex(s.Refused,'request_total_timeout'): + s.emit_private_ready(write_fd,NONCE,'b'*64,'b'*64,e,{}) + self.assertLess(time.monotonic()-started,0.15);os.close(read_fd) + self.assertEqual(signal.getsignal(signal.SIGALRM),handler) + self.assertEqual(signal.getitimer(signal.ITIMER_REAL),(0.0,0.0)) + + def test_actual_main_health_ready_then_private_read_exact_order(self): + previous=signal.getsignal(signal.SIGTERM);read_fd,write_fd=os.pipe();events=[];received={} + try: + with tempfile.TemporaryDirectory() as folder: + e=f.envelope();path=Path(folder)/'approved.json';path.write_text(json.dumps(e));path.chmod(0o600) + pin=s.digest(path.read_bytes());receipt=Path(folder)/'receipt.json' + argv=['session','execute','--envelope',str(path),'--receipt',str(receipt),'--ready-fd',str(write_fd), + '--session-nonce',NONCE,'--ready-envelope-sha256',pin] + class Input: + first=True + def read(self,size): + if not self.first:return b'' + self.first=False + received.update(json.loads(os.read(read_fd,4096))) + self_test.assertEqual(received['envelope_sha256'],pin) + events.append('private-read') + return b'{"human_token":"synthetic","coding_agent_token":"synthetic"}' + self_test=self;stream=type('Stream',(),{'buffer':Input()})() + def health():events.append('health');return e['bao_health_identity_sha256'] + def execute(*args,**kwargs):events.append('execute');self.assertTrue(kwargs['window_started']) + with patch.object(sys,'argv',argv),patch.object(sys,'stdin',stream), \ + patch.object(s,'SessionTransport') as factory,patch.object(s,'execute',side_effect=execute),patch.object(s,'k') as k: + factory.return_value.health_identity.side_effect=health + self.assertEqual(s.main(),0);k.assert_not_called() + self.assertEqual(events,['health','private-read','execute']) + self.assertEqual(received['session_nonce'],NONCE) + finally: + signal.signal(signal.SIGTERM,previous);os.close(read_fd) + try:os.close(write_fd) + except OSError:pass + + def test_actual_main_missing_ack_fd_never_reads_private_input(self): + previous=signal.getsignal(signal.SIGTERM) + try: + with tempfile.TemporaryDirectory() as folder: + e=f.envelope();path=Path(folder)/'approved.json';path.write_text(json.dumps(e));path.chmod(0o600) + receipt=Path(folder)/'receipt.json';argv=['session','execute','--envelope',str(path),'--receipt',str(receipt)] + with patch.object(sys,'argv',argv),patch.object(sys,'stdin') as stdin,patch.object(s,'SessionTransport') as factory,patch.object(s,'k') as k: + factory.return_value.health_identity.return_value=e['bao_health_identity_sha256'] + self.assertEqual(s.main(),1);stdin.buffer.read.assert_not_called();k.assert_not_called() + self.assertEqual(json.loads(receipt.read_text())['reason'],'private_ready_pipe_required') + finally:signal.signal(signal.SIGTERM,previous) + + def test_wrapper_marker_pin_nonce_fields_and_window_failures_refuse(self): + e=f.envelope();marker=self.marker(e) + for key,value in [('session_nonce','c'*64),('executor_sha256','c'*64),('envelope_sha256','c'*64), + ('target','other'),('proposal_id','other'),('bao_health_identity_sha256','c'*64), + ('valid_until_epoch',True),('receive_budget_seconds',True),('receive_budget_seconds',float('inf'))]: + bad=dict(marker,**{key:value}) + with self.subTest(key=key),self.assertRaises(w.Refused): + w.validate_marker(json.dumps(bad).encode()+b'\n',nonce=NONCE,executor_pin=marker['executor_sha256'],envelope_pin='b'*64,envelope=e) + with self.assertRaises(w.Refused): + w.validate_marker(json.dumps(dict(marker,extra=True)).encode()+b'\n',nonce=NONCE,executor_pin=marker['executor_sha256'],envelope_pin='b'*64,envelope=e) + + def test_wrapper_ready_pipe_no_eof_is_bounded(self): + read_fd,write_fd=os.pipe();os.write(write_fd,b'{"incomplete":true}') + started=time.monotonic() + try: + with self.assertRaisesRegex(w.Refused,'wrapper_timeout'): + with w.deadline(0.015):w.read_ready(read_fd) + finally:os.close(write_fd);os.close(read_fd) + self.assertLess(time.monotonic()-started,0.15) + + def test_wrapper_pinned_node_child_launch_is_local_pipe_not_ssh_fd_forward(self): + with tempfile.TemporaryDirectory() as folder: + child=Path(folder)/'child.py';child.write_text('# synthetic child, never executed\n') + envelope=f.envelope();envelope['source_hashes']={str(child):w.hash_bytes(child.read_bytes()),str(Path(w.__file__).resolve()):w.hash_bytes(Path(w.__file__).read_bytes())} + env=Path(folder)/'approved.json';env.write_text(json.dumps(envelope));env.chmod(0o600) + args=type('Args',(),{'child':str(child),'child_sha256':w.hash_bytes(child.read_bytes()),'envelope':str(env),'envelope_sha256':w.hash_bytes(env.read_bytes()),'receipt':str(Path(folder)/'receipt.json'),'session_nonce':NONCE})() + class Process: + stdout=io.BytesIO();stderr=io.BytesIO() + def wait(self,timeout):return 0 + def poll(self):return 0 + def launch(command,**kwargs): + self.assertEqual(command[0],sys.executable) + self.assertEqual(command[1],str(child));self.assertNotIn('ssh',command) + self.assertEqual(kwargs['stdin'],sys.stdin.buffer) + fd=int(command[command.index('--ready-fd')+1]);self.assertEqual(kwargs['pass_fds'],(fd,)) + marker=self.marker(envelope);marker.update(executor_sha256=args.child_sha256,envelope_sha256=args.envelope_sha256) + os.write(fd,json.dumps(marker).encode()+b'\n') + return Process() + with patch.object(w.subprocess,'Popen',side_effect=launch),patch.object(w,'forward_ready') as forward: + self.assertEqual(w.run(args),0);self.assertEqual(forward.call_count,1) + self.assertNotIn('human_token',json.loads(forward.call_args.args[0])) + +if __name__=='__main__':unittest.main(verbosity=2) diff --git a/workplans/ADHOC-2026-10-11.md b/workplans/ADHOC-2026-10-11.md index 6945d94..3aca798 100644 --- a/workplans/ADHOC-2026-10-11.md +++ b/workplans/ADHOC-2026-10-11.md @@ -290,3 +290,53 @@ review remains live source feedback. Fresh exact independent KeyCape/Platform reviews, producer/launcher handoff and founder native authority remain required. No original source/stage/review changed, no owner checkout writes or native/ credential/Secret/tunnel operation; same completed T07, no duplicate workplan. + +T07 same-trial v9 concrete private-ready protocol preparation: exact source +manifest 84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14 follows published v8 while retaining v5/v6/v7/v8 and +producer v1 consumer-refusal history. Child emits bounded value-free nonce/pin/ +window-bound marker via distinct local inherited pipe only after exact source/ +approval/public-health and before private input; stdio aliases refuse. A node +wrapper creates that local pipe, launches pinned child/envelope, relays one +marker on captured SSH control stdout and never reads/copies private stdin. +No extra FD is forwarded by SSH/Bridge, no marker authenticates authority/peer, +and the output-suppressed warden lane is explicitly incompatible. Independent +KeyCape producer/launcher source is coordinated but not yet exact reviewed or +admitted; it must await marker before loading/consuming files or writing tokens. +Forty-six lifecycle, twelve route/main, seven receive, nine new ready/wrapper and +twenty-one retained independent tests pass offline; real pipe timeout/alias and +actual main ordering checked. No SSH, native child/health/tunnel, credential or +owner checkout action occurred. Fresh independent KeyCape/Platform reviews, +trusted founder SSH/launcher/private-file/native admission and real owner +acceptance remain necessary; same completed T07, no duplicate workplan. + +T07 same-trial independent NetKingdom consumer source review of exact KeyCape +producer V3 manifest 569672ecdb3f1f5b46122183dc3b82e83ff168c07c87db7211ec26bc1ce6184a paired with unchanged Net V9 manifest +84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14: completed source-only analysis and offline validation; +changes requested because actual launcher CLI contract FIFO acquisition blocks +before its preparation timer. V2 also reproduces and is preserved. Thirty-three +maker tests and nine independent actual local fake-SSH -> real pinned wrapper -> +real child-main handshake checks pass, with public health and native execution +explicitly mocked, synthetic unsigned tokens only. Wrong nonce/marker, health +failure, expired approval and source mismatch perform zero token-file loads; +quietness failure and real partial pipe delivery retain unknown consumer outcome. +V3 sticky unknown correction passes. Exclusive same-UID directory custody is +required; unlink is non-atomic and no zeroization/copy cleanup is proved. Prior +v5-v8 reviews, V9 own anchor and original producer refusal remain unchanged. +No KeyCape formal role, authenticated marker authority, native/source admission, +credential reads, SSH, tunnel, repository writes or workplan closure inferred. + +T07 same-trial fresh independent NetKingdom consumer source review of exact +KeyCape producer V4 manifest d6f641dc1e4aae7d36658d4199d89af14d2fd7a4bd4e526856eb340234f2d33e paired with unchanged Net V9 manifest +84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14: completed source-only qualified agreement. Actual +CLI rejects FIFO/symlink/oversize contracts before private reads, slow main +acquisition and default caller validation are bounded, and acquisition plus +launch retain one original preparation deadline. Forty maker tests and thirteen +independent checks pass, including nine actual local fake-SSH/pinned-wrapper/ +child-main handshake checks with fixture public health and native execution. +V1 and V3 refusals, V2/V3 FIFO counterexamples, V3 sticky unknown correction, +v5-v8 histories and V9 own preparation anchor remain unchanged. Exclusive +same-UID directory custody, admitted pinned owner launcher/SSH host profile, +private file allowance and exact founder native authorization remain required; +marker and unsigned claims authenticate neither authority nor issuer. No +credential read, native command, real SSH, owner checkout write or native/task +closure occurred. This source agreement does not approve transport or custody.