Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cd6316d
test(readiness): reproduce delayed and absent Caido handshake
seonghobae Sep 8, 2026
6566305
test(application-service): restack HTTP readiness RED on canonical root
seonghobae Sep 8, 2026
c05d378
fix(application-service): require bounded HTTP protocol readiness
seonghobae Sep 8, 2026
59cc738
test(application-service): preserve TCP process-boundary fixtures
seonghobae Sep 8, 2026
236d1a6
fix(application-service): compose bounded HTTP readiness probe
seonghobae Sep 8, 2026
a07b3a9
docs(application-service): define protocol-aware readiness
seonghobae Sep 8, 2026
f81e401
docs(application-service): bind product readiness to protocol
seonghobae Sep 8, 2026
5f2a982
docs(adr): record protocol-aware readiness decision
seonghobae Sep 8, 2026
8a57791
docs(doctoring): record HTTP readiness causal evidence
seonghobae Sep 8, 2026
d098385
docs(gap): refresh live readiness and release authority
seonghobae Sep 8, 2026
3297216
test(application-service): harden HTTP readiness authority RED
seonghobae Sep 8, 2026
b481086
fix(application-service): validate HTTP readiness authority
seonghobae Sep 8, 2026
0819b66
docs(application-service): trace readiness review repair
seonghobae Sep 8, 2026
153293b
style(application-service): apply rustfmt to HTTP readiness
seonghobae Sep 8, 2026
dc1f1be
style(application-service): apply rustfmt to readiness tests
seonghobae Sep 8, 2026
84216db
test(application-service): cover malformed HTTP prefix
seonghobae Sep 8, 2026
4d738cc
test(application-service): restore rustfmt newline
seonghobae Sep 8, 2026
61ccfcd
docs(readiness): preserve gap evidence before owner repair
seonghobae Sep 17, 2026
16b5df4
docs(readiness): restore global gap owner boundary
seonghobae Sep 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/PRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ The runtime is deliberately not the authority for the consumer's business decisi
- Enforce CPU, RAM, PID, tmpfs, lease, readiness, and shutdown bounds.
- Create a per-sandbox internal DNS-disabled network and publish exactly one service to host IPv4 loopback on a random port.
- Invoke the application without a shell.
- Return an endpoint only after bounded readiness.
- Return an endpoint only after protocol-aware bounded readiness: TCP services require loopback transport reachability; declared HTTP services require a successful bounded HTTP response from the runtime-derived loopback endpoint.
- Return a versioned lease and cleanup receipt.
- Provide no request fields for credentials, arbitrary environment variables, broad host mounts, devices, privileged mode, host namespaces, runtime sockets, or arbitrary Internet egress.
- Provide no request fields for credentials, arbitrary environment variables, broad host mounts, devices, privileged mode, host namespaces, runtime sockets, arbitrary health URLs, or arbitrary Internet egress.

### Artifact-analysis foundation

Expand Down Expand Up @@ -110,7 +110,7 @@ The runtime is deliberately not the authority for the consumer's business decisi
- Existing artifact-analysis public Rust API remains available after DDD directory migration.
- Tag-only images and over-budget resource requests fail closed.
- Launch plan has no privileged/host-network/runtime-socket path and explicitly enforces P0 isolation flags.
- Process-boundary tests prove direct argv invocation, readiness gating, error cleanup, and explicit termination behavior.
- Process-boundary tests prove direct argv invocation, protocol-aware readiness gating, error cleanup, and explicit termination behavior; an HTTP declaration cannot become ready from TCP acceptance alone, and a non-2xx HTTP response is not readiness.
- Real rootless Podman E2E proves the effective security boundary before the capability is called release-ready.
- `contextual-orchestrator` integration occurs through its owner issue/ACL and a published runtime artifact; no direct consumer Podman calls.
- Wardnet verdict policy remains outside this repository.
4 changes: 2 additions & 2 deletions docs/TRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ The immutable image reference is appended before application argv, so applicatio
5. Inspect process seccomp/capability/LSM evidence and fail closed unless every implemented P0 isolation control is positively verified.
6. Query the requested port mapping only after isolation verification succeeds.
7. Accept only a single IPv4 loopback `127.0.0.1:<nonzero-port>` mapping.
8. Poll bounded TCP readiness using operator timeout/poll policy.
8. Poll protocol-aware readiness within the operator-owned timeout/poll budget: `tcp` requires a successful loopback TCP connection; `http` sends a bounded HTTP/1.1 request to the runtime-derived loopback endpoint and requires a final 2xx status-class response before readiness is accepted.
9. Return a lease only after effective-isolation checks and readiness succeed.

P0 HTTP readiness deliberately uses TCP reachability because no consumer-supplied health path is accepted yet. A future typed HTTP health contract may refine this without accepting arbitrary URLs.
P0 HTTP readiness never accepts a caller-supplied URL, origin, host, or arbitrary health path. The probe is fixed to `/` on the runtime-owned loopback mapping, so consumer-specific authentication or bootstrap semantics remain outside this bounded context. A future typed application-specific health contract may version this boundary without turning arbitrary network destinations into runtime authority.

### Cleanup

Expand Down
12 changes: 9 additions & 3 deletions docs/adr/0006-isolated-application-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ This ADR remains Proposed while PR #1 is Draft and the exact candidate has not p

Chat/Agent systems sometimes need a real application process rather than an in-process tool function. Running such applications on the orchestrator host with ambient credentials, host networking, writable filesystem, or container-engine access creates an unacceptable authority boundary.

A loopback port accepting TCP is not sufficient evidence that an application declared as HTTP is ready for a consumer security bootstrap. The runtime therefore needs protocol-aware readiness while keeping consumer-specific login, authorization, and arbitrary health URLs outside the isolation bounded context.

## Decision

The first `application_service` infrastructure adapter is rootless Podman. A valid request must use an immutable OCI image digest and bounded service/resources. The adapter:
Expand All @@ -24,19 +26,23 @@ The first `application_service` infrastructure adapter is rootless Podman. A val
- disables restart and container logging in the P0 profile;
- applies CPU/RAM/PID and container lifetime limits;
- publishes one service port to random host port on `127.0.0.1` only;
- performs a bounded readiness check before returning a lease;
- performs protocol-aware bounded readiness before returning a lease: `tcp` requires a successful loopback connection, while `http` sends a fixed HTTP/1.1 request to `/` on the runtime-derived loopback endpoint and requires a final 2xx status-class response;
- never accepts a caller-supplied readiness URL, origin, host, or arbitrary path in the P0 contract;
- removes container and network on explicit termination and on partial-launch/readiness failures;
- returns an attested versioned lease and cleanup receipt.

The application request has no fields for privileged mode, host namespaces, devices, arbitrary mounts, environment variables, runtime sockets, or external network enablement.
The application request has no fields for privileged mode, host namespaces, devices, arbitrary mounts, environment variables, runtime sockets, external network enablement, or caller-controlled health destinations. Consumer-specific authentication/bootstrap remains consumer-owned and occurs only after the runtime has returned an attested ready lease.

## Alternatives

- **Consumer-owned Podman calls:** rejected because isolation policy would be duplicated and domain code would depend on infrastructure.
- **TCP reachability for HTTP readiness:** rejected because a listening socket can exist before the declared HTTP service is usable and can issue a lease that immediately fails consumer bootstrap.
- **Caller-supplied health URL/path:** rejected for P0 because it expands the runtime into an outbound-request authority and mixes consumer application semantics into the isolation contract.
- **Consumer login as runtime readiness:** rejected because login credentials and application authorization belong to the consumer, not the reusable isolation runtime.
- **Docker socket sidecar:** rejected because the socket is a high-authority control channel.
- **gVisor first:** deferred. gVisor is a planned stronger OCI backend but P0 first establishes the consumer-neutral contract and rootless lifecycle with broadly available Podman.
- **Kubernetes first:** deferred because a cluster is not required for standalone/local operation.

## Verification rule

Command-plan and fake-Podman process tests are necessary but not sufficient. Release claims about container isolation require a real rootless Podman E2E lane that checks effective filesystem, namespace, capability, resource, network, and cleanup behavior. gVisor/containerd/Kubernetes adapters require their own parity and security evidence.
Command-plan and fake-Podman process tests are necessary but not sufficient. Protocol readiness tests must prove that TCP-only acceptance does not satisfy an HTTP declaration, that a bounded 2xx response does, and that non-2xx/stalled responses fail closed. Release claims about container isolation require a real rootless Podman E2E lane that checks effective filesystem, namespace, capability, resource, network, and cleanup behavior. gVisor/containerd/Kubernetes adapters require their own parity and security evidence.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Application-service HTTP-readiness Gap owner repair

Reviewed 2026-09-17 KST against Draft PR #104 exact `4d738ccc52a3acb3d6ea621e306f628074c96122`, exact base `5c6a44bb2b35eb17d0315d72db242f4488c3c426`, and repository-wide Gap owner PR #121.

## Owner-boundary finding

Issue #103 is a focused application-service readiness contract. It owns protocol-aware readiness semantics, the Podman readiness adapter, its focused tests, and the corresponding PRD/TRD/ADR/TRACEABILITY updates. It does not own the repository-wide live product/technical Gap ledger. Review `5229919282` found that the branch still changed `docs/product-technical-gap-baseline.md`; carrying that file forward could replay a 2026-09-09 repository snapshot over #121's newer owner graph.

The repair is migration-first. The protocol evidence and consumer-release rule that had also appeared in the global ledger are retained here and in the existing local PRD/TRD/ADR/TRACEABILITY before the global file is restored byte-for-byte to this PR's exact-base blob `bacb346f2ce4259a4f55bd3bece5e871b06d69db`.

## Retained causal and review evidence

The repaired causal RED `65663052ec30bc178adbe5ff4514f5409d10971f`, native CI `34255729573`, verify `102160927453`, proved that a runtime-owned loopback socket accepting TCP without an HTTP response could incorrectly satisfy `ServiceProtocol::Http`. The first production repair `c05d378cfc736e4257594d69bb06871893ef2d0f` split protocol semantics: `Tcp` remains connect-only; `Http` sends one bounded fixed-path request to the runtime-owned loopback mapping and requires a successful HTTP response class.

Legacy success fixtures that were plain TCP listeners were corrected to `Tcp` in `59cc738f1428d78eaf7a7999e65cc247307b990d`. A focused helper-coverage repair followed without widening readiness semantics. Exact predecessor `d098385045cefd8b337ba2bd0069107a01756b81`, CI `34259463376`, reached hosted GREEN for verify, coverage, branch coverage, and hosted negative rootless/AppArmor; its branch artifact and coverage details remain historical predecessor evidence only.

Code review then identified two narrower protocol-integrity defects: the fixed `Host: 127.0.0.1` omitted the runtime-selected non-default port, and status acceptance treated a prefix beginning with `2` as sufficient. Test-only `32972162bfee95112b2f79a3427ebe4815e24b39`, CI `34267331198`, branch job `102199888859`, executed the causal review RED: the captured request omitted `:<mapped-port>`, while malformed `HTTP/1.1 2x0 ...` and `HTTP/1.1 20x ...` were incorrectly accepted. The same focused binary retained TCP/no-response timeout, HTTP 204 success, and HTTP 503 non-readiness controls.

Minimum production `b481086cbd13a1e94cf8df09d49efb9fa3200e85` derives `Host: 127.0.0.1:<runtime-selected-port>` and validates a bounded HTTP/1.1 three-digit 2xx status prefix. It does not add caller-controlled origin/path, authentication, credential handling, egress policy, model/provider semantics, or new wire fields. RFC 9110/9112 basis and the exact contract distinction remain in `APPLICATION_SERVICE_HTTP_READINESS_TRACEABILITY.md`.

Exact predecessor `4d738ccc52a3acb3d6ea621e306f628074c96122`, native CI `34270054863`, had verify `102209085115`, production coverage `102209084826`, branch coverage `102209084792`, and hosted negative rootless/AppArmor `102209084617` GREEN. Dedicated positive-LSM `102209085130` was still queued and no qualifying approval existed. This hosted GREEN must not transfer after the ownership-only head movement.

## Consumer and release contract retained locally

The PR's PRD/TRD/ADR changes make the ownership boundary normative: consumers must consume an immutable released runtime contract/artifact; mutable PR heads, sibling source copies, direct foreign runtime calls, and cross-service SQL are not integration mechanisms. No GitHub Release is claimed by this branch. Protected integration and immutable version/package/SBOM/provenance/reproducibility/rollback publication remain prerequisites before a consumer version/digest bump.

Caido login/authentication and consumer bootstrap remain consumer-owned. The runtime readiness contract only attests the selected backend-neutral service protocol against the exact runtime-owned loopback mapping.

## DDD and decision

`application_service` owns protocol intent and lease/readiness semantics. `infrastructure::podman` owns the concrete loopback probe translation. `sandbox_execution` remains the reusable isolation owner. Requested protocol intent, successful readiness observation, and positive sandbox confinement are independent evidence dimensions.

Selected repair: preserve all focused source/test/PRD/TRD/ADR/TRACEABILITY changes, add this owner-repair record, and restore only the global Gap file to the exact base. Rejected alternatives are copying #121's latest ledger into this leaf, discarding review/causal history, retaining a second live Gap writer, or force-rebasing merely to remove the file.

After the docs-only movement, all current-head gates must be reacquired. Historical exact-head GREEN remains useful lineage evidence but is not merge/release authority for the moved head.
Loading
Loading