carlos / platform Public
Private launch context for maintenance consumers
Implementation supplement to the approved maintenance-exec.md6a81dac contract. This specifies the proposed Home operator invocation contract; it does not enable maintenance or replace any owner, guard, lease, containment, or release gate. Initial4605a54 supplement received independent Fable APPROVE. The caf47fb delta received REQUEST_CHANGES. This revision addresses its descriptor-lifetime, status, and verification findings; independent review remains pending. The worker launch path and all Home startup-adapter behavior described below are unimplemented: fd3 parsing, --db/context binding, fd4 handling, and the self-executable check. Home7e has an unmounted opened-DB connector, not this adapter. Before mounting, Home must separately amend and review its approved4770bc6 opened-DB contract to specify this startup ordering; this document does not silently change that contract.
Boundary
The reviewed worker launches a verified artifact under the existing trusted-platform/shared-UID exec model. A private inherited descriptor identifies a worker invocation to the app adapter. This is not a signature proving an arbitrary local process is CARLOS: a malicious process with the same UID and app keys already crosses that model's boundary. The descriptor must never be exposed through the console request, supplied argv, request environment, app HTTP, or a caller-selected path. An environment boolean is not invocation evidence.
Only after current-owner approval, immutable request/preflight/environment checks, matching lifecycle claim and guard/projection, continuous healthy lease, checked stop, existing-DB identity and strict containment setup may the worker construct the context. Durable executing state must precede spawning. The context is generated from those checked objects, not copied from request fields. It grants no authority on its own to a worker that has not passed those gates.
Descriptor layout and lifetime
Child fd0 receives the exact validated private JSON stdin. Child fd1 is the bounded private result channel. Child fd2 is /dev/null. Child fd3 is the read end of a newly created private pipe carrying the launch context. Child fd4 is the regular read-only artifact descriptor whose actual bytes the worker has already hashed and verified against the approved release. cmd.ExtraFiles contains exactly those two related descriptors, in that order, with no unrelated descriptors. The strict Linux path executes /proc/self/fd/4 after Go descriptor remapping, with no fresh pathname lookup or fallback; replacing the staged pathname cannot change the executed inode. The child must verify fd4 is an ORDONLY regular file, compare its device/inode with an opened /proc/self/exe descriptor, and stream the actual executable SHA256 against context.artifactdigest after validating fd3. It must then close both executable descriptors with checked errors BEFORE Home takes its opened-DB descriptor baseline. Failure refuses before any mutable DB open. The child does not reopen the staged artifact by pathname. The worker retains its own verified artifact descriptor throughout the attempt. Thus fd4 is a startup-only descriptor, never an additional regular file admitted into Home's database baseline. Go's descriptor remapping supplies fd3/fd4; the caller cannot set their numbers or substitute filenames. Each pipe/artifact descriptor set permits exactly one spawn attempt; a failed Start never calls a build closure a second time or reuses consumed pipes. The worker creates and owns os.Pipe pairs for stdin, stdout and fd3; it passes the corresponding *os.File ends to the child and supervises the other ends explicitly. It does not delegate these copies to exec.Cmd-managed goroutines or depend on Wait/WaitDelay to interrupt blocked IO. It writes the complete bounded context, then closes that endpoint. Parent descriptors close on every spawn/error/termination path. Child receives no deployment credentials beyond the already approved app environment.
Context and stdin writes run with cancellation and termination awareness, alongside bounded stdout capture, so a child that never reads cannot wedge the worker. The worker's deadline/lease supervisor stays independent of blocked pipe writes or output reads. Maintenance must use the reviewed strict cgroup preparation/start path and must never call cgroup.Manager.Start, whose ordinary path can build twice and fall back to spawn-then-move. The strict path has no ordinary Start fallback; process-tree death, including descendants holding pipes, is checked before any result or resume success. App input timeout/refusal never authorizes automatic retry.
The app adapter reads fd3 at most8KiB plus one overflow-detection byte, requires EOF, rejects truncation, and closes it. It reads stdin at most64KiB plus one overflow-detection byte and requires EOF. No context fallback to argv, environment booleans, files or HTTP exists. A missing/invalid context produces the app's fixed refusal without opening a mutable database. The worker bounds the entire attempt; the adapter must not wait indefinitely for context or stdin and performs these reads under its own bounded startup deadline.
This launch class is an exec-backed route using a kind=binary release: artifact_digest is the per-file SHA256 of the actual executed binary, not an archive or an unsigned version label. The retained fd pins the inode, not immutable content. Platform artifact writers must preserve those bytes for the full attempt. A same-UID process rewriting the inode is inside the stated trusted-platform boundary; this design does not claim protection against it. The child self-executable hash check detects a changed image before DB access, but cannot make arbitrary later same-UID writes safe.
Version1 context
A closed UTF-8 JSON object, with duplicate and unknown keys, trailing data, noncanonical numeric forms, invalid encodings and oversized fields rejected. Every listed field is required:
- version: integer1.
- account, app, host: exact validated route identity using the shared platform validators.
- requestid, attemptid: canonical base64url encoding of32 random bytes,43 characters each.
- requestdigest, recordidentity, artifactdigest, environmentenvelope_digest: lowercase64-character SHA256. Request digest binds immutable approved nonsecret metadata; record identity uses the guard's canonical identity; artifact digest binds the actual executed artifact; environment digest binds the randomized approved encrypted snapshot. These values are not substituted from live pointers after approval.
- guard_generation: positive integer through signed64-bit maximum, matching executing authority.
- input_sha256: lowercase64-character SHA256 of the exact stdin bytes. This private low-entropy hash is confined to the pipe and must not enter public receipts or logs.
- databasepath: exact absolute platform-owned existing path, valid UTF-8, at most1024 bytes, no NUL. databasedevice and database_inode: canonical unsigned64-bit decimal integers describing the already checked regular, nonsymlink file. Decode all integers exactly into their typed ranges; no float64-backed intermediate is allowed, including values above2^53. Zero identity is unsupported rather than a portable fallback. This class remains native Linux only.
- execution_deadline: exact UTC RFC3339Nano timestamp set by the worker for this attempt, no later than its operation timeout. The worker enforces a separate conservative monotonic lease safe-until deadline and terminates before loss of exclusive ownership. This timestamp is only an additional child refusal bound; it is not proof of current lease health and cannot extend a lease or operation.
No field says fenced, approved, owner, role, allowed action or maintenance=true. Those would turn the context into an unverified body assertion. The actual worker's construction gates establish transport authority. The app's role/origin/action restrictions come from its exact pinned private launch environment, whose snapshot digest is bound here; no caller-supplied environment overrides are permitted. These app-specific keys and their schema remain owned by Home's approved command design.
Home adapter binding
The fixed Home command accepts only its reviewed launch mode and platform-owned database selector. The fd3 context is authoritative for the DB path/device/inode; any --db selector must equal context.databasepath byte-exactly before opening. Caller-supplied argv cannot select a different database. Before mutation it verifies the exact signed Home input, its operation allowlist and the configured expected role/origin from the pinned environment, then compares the input byte digest with the context. It obtains Home operationid from that verified signed input and binds it to the context's distinct platform request/attempt IDs in its invocation/result metadata. Platform does not parse or rewrite Home's signed JSON. An explicitly approved retry may use a new transport attempt for the same Home operation; Home's existing transaction/idempotency rules return the committed result without repeating the mutation.
The adapter opens only the exact expected existing DB and verifies the opened file's actual path/device/inode identity before allowing its command engine to mutate. A synthetic actual-modernc experiment shows that a path check before/after open can miss a replacement that SQLite opened between those checks; passing /proc/self/fd/N alone is not accepted proof because SQLite can canonicalize it. Home's separate command-only connection proof must demonstrate the driver's actual writable main-file identity and every reconnect. No unsafe access to private driver structures or a guessed matching descriptor is permitted. It refuses missing databases, symlinks, replaced files, wrong role/origin/schema and unsupported identity checks; it never restores, seeds or initializes as a fallback. A private constructor creates the app's opaque invocation context only after those checks. Exported body structs cannot fabricate that context. The worker retains its lifecycle fence and lease while the app runs and independently rechecks DB identity afterward. Checking an input pathname alone is insufficient; the concrete SQLite/open-file sequence must demonstrate that the database actually mutated is the same checked file.
The app never persists the raw launch context or private input digest to public state or logs. Permanent platform receipts bind ciphertext digests and immutable nonsecret metadata. Existing Home private result/receipt storage keeps its established protection. Empty or malformed stdout, overflow, nonzero exit, timeout, lost lease or containment uncertainty produce no successful operation evidence.
Required verification before wiring
- Worker tests reject user-controlled fd/env/context substitutions; pre-execution failures spawn no child; immutable expected bindings change only through a newly approved request. Byte-exact signed input reaches stdin; private context/input/output never reach argv, public status, stderr, logs or receipts.
- Actual subprocess fixtures verify fd3 inheritance and fd4 as an O_RDONLY regular file with device/inode equal to the worker's retained, already-hashed artifact descriptor. Replacing the staged pathname before execve of /proc/self/fd/4 must still execute that verified inode, with no pathname fallback. Verify child fd4 and self-executable descriptor closure before the Home database baseline, refusal on mode/identity/hash/close failure, and worker retention through completion. Also verify no unrelated inherited descriptors, EOF, blocked-read/write cancellation, exact expiry behavior, output overflow and descendant-held pipes. Fixtures use synthetic keys/DBs and isolated credentials only. The existing /tmp/oficina-maintenance-execfd-proof/result.json is local descriptor/path-replacement evidence only; it proves no worker, cgroup, lease, Home adapter, or deployed execution behavior.
- Worker tests reject wrong approved request/artifact/environment/record bindings before constructing the context; Home has no independent expected randomized environment-envelope digest or platform record identity and must not pretend to check these against invented duplicate environment flags. Home tests reject missing/extra/duplicate/malformed context fields, wrong exact input digest, selector/context mismatch, actual opened DB identity and expired deadlines, with zero mutations. The adapter also streams a SHA256 of /proc/self/exe and compares context.artifact_digest, checking the actual running image without trusting a pathname. Actual file replacement/symlink races must fail against the opened DB identity. Exact replay under a fresh approved transport returns the same committed Home result.
- Whole worker plus consumer Fable review and full native/cross-platform CI remain required. Native Linux canary proves actual cgroup/systemd/lease/fence and verified artifact/config behavior. Neither this design nor a locally injected fd3 fixture is deployed proof or authorization for a live operator invocation.