~0x64616E69656C
project 03 / R1 / host-informed response containment / 2026-10-23 – 2026-10-24

Held before delivery.
Not within budget.

A bounded HTTP/2 hold demonstrated additional synthetic pre-delivery containment. Iteration one failed its CPU budget; iteration two did not support evidence batching. R1 continues with more precise questions about efficiency and trustworthy host evidence.

EXECUTED / OVERALL FAIL — CPU COST
First iteration / 2026-10-23.
Functional containment: PASS in the scoped synthetic test.
Instrumented worker CPU: +22.1%; target: at most +10%.
No adoption follows from this result.
Iteration 2 / batching not supported ↓
R1 research ongoing / two executed iterationsHTTP/2 synthetic lab · HTTP/3 not tested
01 / QUESTION

Can better context
arrive in time?

Qualifying host evidence added a synthetic containment advantage while ordinary streams continued. The tested implementation missed its cost criterion. Those findings sharpen the ongoing A+B research question: what can still be prevented, and at what cost?

A + B / THE CORE DIRECTION

Observe the response.
Contain before delivery.

Gate A evaluates response-contract evidence and classifies output. Gate B holds selected INCONCLUSIVE sensitive output and acts on qualifying evidence before client delivery. A+B remain the central response-aware direction; B is the long-term objective.

R0 / PASS established retrospective metadata detection with stock nginx, without a new filter. R1 tested a separate experimental containment mechanism.

C / INDEPENDENT EMERGENCY ENFORCEMENT

Enforce at the host.

Gate C is a potential future boundary for preventing defined host-side harm independently of nginx. It complements A+B; nginx must not become a privileged host-policy controller.

A+B may consume trusted service-level host evidence. The synthetic result supports studying that bounded design, without establishing production readiness or reliable PHP-FPM request attribution. Host enforcement must remain effective even if nginx never receives its event.

Research history: the earlier Gate-C-centric R1 direction was rejected for project fit during a read-only architecture review. It was not a failed executed trial. The reset S2 design then reached DESIGN READY on 2026-10-23; the executed result reported here supersedes that planning status.
02 / SOURCE BOUNDARY

Before output starts.
Not after a receipt.

The nginx 1.31.7 source audit identified a pause after upstream headers were parsed and successfully processed, immediately before ngx_http_upstream_send_response(). A narrow patch in a disposable source copy implemented that explicit continuation.

01 / PARSE

Read complete upstream headers; distinguish upstream metadata, final output and client receipt.

02 / CLASSIFY

Evaluate the independent status, content-type and declared-length contract, sensitivity and configured service invocation.

03 / HOLD

In the hold arms, pause further upstream reads and writes. Retain the existing 4 KiB preread buffer; add no body chain or disk spill.

04 / LOCAL STATE

Consume bounded, authenticated worker-local host state without a synchronous verdict query. The lab used nonblocking Unix datagrams, at most four messages per callback and sixteen service slots.

05 / CONTINUE OR STOP

An explicit timer owns continuation. Existing nginx request finalization stops selected streams; cleanup cancels timers and live references.

06 / VALIDATE

An independent client checks decoded DATA, payload prefixes, completion and resets. Filter entry and server counters are not client receipts.

The source finding still matters: a header-filter return of NGX_AGAIN alone does not establish a safe hold. Stock proxy buffering is not a security decision window. The experiment used an explicit upstream gate, rather than assuming either behavior.
OUTPUT ORDER / OBSERVED

Filter entry is not delivery.

Auxiliary-filter registration was corrected after the first smoke run exposed bypassed observation callbacks. The qualifying intermediate S2-20 stops occurred before header-filter entry, and the client independently confirmed zero M bytes.

TERMINATION / SCOPED VALIDATION

Use the request lifecycle.

The existing upstream/request error-finalization path closed the selected HTTP/2 stream. The client observed reset code 2 / INTERNAL_ERROR, with O/U and later streams intact. No custom RST_STREAM frame or shared-connection close was used.

03 / RESPONSE CONTRACT

Three classifications.
No silent trust.

These were experiment-only decisions under a limited response contract. Matching metadata did not establish application safety.

Executed response decisions.
ClassMeaningHandling
ALLOWOrdinary response matches the contract.Normal delivery; limited contract only.
DENYPredefined metadata contradiction, such as expected 403 versus actual 200.Terminate before output without host evidence in RA/S2.
INCONCLUSIVESensitive response with matching metadata.Use configured service state; hold for 0 or a nominal 20 ms.
No alert is not an ALLOW: at the deadline, absence of an accepted positive alert released INCONCLUSIVE output as unverified. Missing, expired or disconnected evidence never proved safety. Accepted alerts stayed latched across disconnection and authenticated restart.

Messages carried synthetic invocation, session and sequence identifiers with HMAC authentication and sender credentials. Invalid authentication, stale, duplicate, out-of-order and unrelated updates were exercised. Unix datagrams provided no disconnect EOF or direct controller-liveness guarantee.

04 / EXECUTED METHOD

Four streams.
One shared connection.

One TLS 1.3 / ALPN h2 connection carried four concurrent harmless 8 KiB fixtures. The origin did not read the independent client oracle; host events were simulated trusted lab input.

Stream roles. Service S was alerted; T was unrelated.
StreamResponse classEvidence purpose
M / SSensitive, fixture-designated forbiddenCount forbidden client-received bytes.
L / SLegitimate sensitive, matching metadataCount collateral containment.
O / SOrdinary allowedCheck same-service continuation.
U / TOrdinary allowedCheck unrelated-service isolation.
M and L were indistinguishable to the module: service, sensitivity and metadata matched. Neither body content nor M/L identity selected the action. Blocking L was collateral containment; no PHP-FPM worker or request identity was inferred from timestamps.

Six matched comparison arms.

N and C used stock nginx; RA/S2 shared the experimental binary.
ArmEvidence / actionPurpose
NStock proxy deliveryUnmodified baseline.
RA-0Response contract; no hold or host stateMetadata-only intervention.
RA-20Response contract; nominal 20 ms hold; no host stateSeparate delay from host evidence.
CIndependent simulator revoked S output and aborted all its owned upstream socketsHost-only action without HTTP response selection.
S2-0Response contract plus authenticated host state; no holdEvidence already available at the gate.
S2-20Response contract plus host state; nominal 20 ms holdAdditional event-arrival window and its cost.

C actively stopped service output; it was not just an observer. It could not retract earlier delivery. A whole-connection stop would also sacrifice unrelated streams. RA-20 plus C, application-cooperative controllers and pre-compromise confinement were not comparison arms; this is not a universal host-only architecture ranking.

Twenty functional scenarios × six arms × three repetitions produced 360 cells and 1,800 primary functional requests. Eighteen fixed cost runs added 2,160 requests. Including 60 smoke diagnostics, 48 superseded reload requests and five interrupted flow-control requests, execution totaled 4,073 / 4,096 requests.

The retained accounting bounded rate at 64 requests/s, active streams at sixteen and simultaneous holds at four. Execution phases totaled 113.621 of 600 seconds, excluding offline build/analysis time. The five interrupted requests lack complete client records and were not credited to primary outcomes; corrected cells and preserved earlier attempts remained distinct.

05 / FUNCTIONAL RESULT

Held in time.
Collateral counted.

Functional containment — PASS, scoped. In all three qualifying intermediate S2-20 repetitions, host acceptance fell inside the hold: M and L stopped before header-filter entry, while O/U and the subsequent stream completed.

Forbidden M fixture bytes received by the client. Each entry occurred in 3/3 repetitions.
ArmEarlyIntermediateLate / prefix validatedAfter completion
N8,1928,1928,1928,192
RA-08,1928,1928,1928,192
RA-208,1928,1928,1928,192
C08,1922568,192
S2-008,1922568,192
S2-20002568,192
INCREMENTAL CONTAINMENT / PASS

Host evidence added a window.

N, RA-0, RA-20, C and S2-0 delivered the full M fixture in the corresponding intermediate cases. RA-20 had the same hold: delay alone did not explain S2-20's zero-byte outcome.

Each S2 arm completed 156/156 primary O/U records exactly. C completed 141/156, with fifteen ordinary S disruptions in early/persistent-alert controls. Early C returned 502 bodies for M/L/O: zero M fixture bytes did not mean zero HTTP body bytes.

COLLATERAL CONTAINMENT / COST

Legitimate L was blocked.

S2-20 stopped L in all three core intermediate cases and eighteen alert-related L records across the full repeated controls; S2-0 stopped fifteen. These are fixture counts, not real-world false-positive rates.

Capacity tests separately produced twelve 503 responses per 20 ms arm, including legitimate sensitive traffic. These were load-shedding costs, not security successes.

CLIENT ORACLE

Validate decoded DATA bytes, exact fixture or prefix, status/type/declared length, END_STREAM and reset. Origin writes and filter counters were separate evidence; no timeout was credited as prevention.

LIFECYCLE CONTROLS

No-alert release, invalid/stale/unrelated state, disconnect/restart, cancellation, origin abort, replacement workers, capacity and constrained flow control were exercised. O/U and later streams progressed.

TIMING BOUNDARY

Intermediate emission actually occurred 10.586–12.701 ms after release. Accepted alert delivery took 0.114–0.317 ms in this simulator; neither number measures real collector detection latency.

256 bytes had already arrived.Late C/S2 termination stopped only the suffix after a client-validated M prefix. After completion, all 8,192 bytes remained delivered. Response suppression cannot undo origin-side effects.
06 / ITERATION 1 / COST FAIL

The CPU gate failed.
The threshold stays.

S2-20 used 157.019 ms of instrumented worker CPU against 128.600 ms for stock nginx across 360 cost requests per arm: +22.1%, exceeding the predeclared +10% target. Iteration one's overall acceptance result is FAIL; functional success does not qualify the mechanism for adoption.

Fixed no-alert cost phase: three 120-request runs per arm; 180 ordinary and 180 sensitive TTFB samples per arm.
ArmOrdinary TTFB p95 / p99, msSensitive TTFB p95 / p99, msWorker CPU, msCPU vs N
N4.895 / 5.9236.216 / 7.115128.600baseline
RA-05.345 / 6.3346.722 / 7.891131.673+2.39%
RA-203.931 / 7.04325.874 / 29.043161.298+25.43%
C4.480 / 5.1125.766 / 6.287123.662−3.84%
S2-04.707 / 5.8335.740 / 7.467124.536−3.16%
S2-203.797 / 4.64725.847 / 26.269157.019+22.10%

CPU sampled the owned worker's accumulated execution time, excluding startup, most shutdown and Python origin/client work. Regular-file evidence writes, gauges and filter callbacks were included. The controller was idle after its initial snapshot; active-controller CPU was not isolated. Three runs and nearest-rank percentiles do not establish production tails, general speedups or statistical equivalence.

S2-20 acceptance gates. CPU was not relaxed after measurement.
GatePredeclared targetObservedResult
Worker CPU vs N≤+10%+22.10%FAIL
Ordinary TTFB deltap95 ≤+1 ms; p99 ≤+2 ms−1.098 / −1.276 msPASS
Hold through scheduled continuation≤25 ms20.090–21.507 ms; p99 21.244 ms; n=570PASS
Retained request allocation≤32 KiB17,544 bytes per sample; n=582PASS

The 20 ms hold was a nominal deadline, not a demonstrated hard wall-clock bound. The 25 ms gate concerned hold plus scheduling, not absolute sensitive TTFB (p99 26.269 ms). Memory covered request/stream/upstream pools, including existing retained allocations; shared connection/TLS allocations and kernel buffers were outside that gauge. It was not per-stream RSS.

No optimization claim follows: RA-20 also exceeded the CPU target. These data do not isolate an additional idle-host-state penalty or the irreducible cost of S2. CPU-cost attribution is a possible next research question, subject to separate review and authorization. Improvement is neither established nor guaranteed.

R1 iteration 2 / 2026-10-24
Fewer writes. No justified change.

One bounded follow-up tested a 4 KiB evidence-record buffer. It retained the same records, gauges, response contract, nominal 20 ms hold and independent M/L/O/U oracle. Batching reduced regular-file write calls, but did not demonstrate lower S2-20 worker CPU. The candidate is not retained.

Distinct smaller pilot: three 48-request cost runs per arm; 144 requests and 72 TTFB samples per role group. These figures do not replace iteration one.
Matched armWorker CPU, msCPU vs stockWorker write syscalls
Stock N53.239baseline720
Original S2-2068.898+29.41%1,656
Batched S2-2072.088+35.40%936

S2-20 write syscalls fell 43.48%; CPU was 4.63% higher in the aggregate, with mixed per-repetition effects. Three short repetitions do not establish a statistical regression or production cost. They do not support the intended CPU improvement. Both prototypes still exceeded the unchanged +10% gate. All cost-pair event counts matched; observation work was retained.

SECURITY REGRESSION / SCOPED PASS

The window remained.

Original and batched S2-20 each withheld all 8,192 M bytes in 3/3 intermediate repetitions. O/U and probes completed 105/105 primary regression records per variant. Late S2 alerts still left a validated 256-byte M prefix. Legitimate L remained collateral: three core intermediate resets, nine alert-related resets across repeated controls per variant.

Batched S2-20 retained 17,544 bytes per held request in the pool gauge and added 4 KiB of worker-global telemetry storage. Hold through scheduled continuation was 20.183–21.304 ms; capacity still produced twelve 503s per S2-20 variant, including legitimate traffic.

ATTRIBUTION / STILL OPEN

Write count is not CPU cost.

Timers, longer request lifetimes, pool scans, formatting and event-loop scheduling were not individually profiled. Batching added copying and flush dispatch; synchronous file writes remained. Source review also found that reaching the inherited 4,096-record cap could suppress a pending-buffer flush. The pilot did not reach that cap; this further limits the candidate.

Active simulator command CPU was measured separately: median 314.639 microseconds across 66 positive commands. This is not real collector cost or detection latency. No HPACK/G0A CPU offset or combined-stack benefit was established.

Iteration 2 / NO JUSTIFIED CHANGE: 1,866 total requests, including eighteen diagnostics, stayed within the 2,048 ceiling; all fixed HTTP phases completed without retries. This was a failed optimization attempt with tested containment preserved, not full R1 acceptance. The first iteration remains FUNCTIONAL PASS / OVERALL FAIL — CPU. Further attribution requires a separate R1 scope; no second tuning pass, real host enforcement or production integration followed.
07 / LIMITS + PROVENANCE

Containment observed.
Costs still unresolved.

Iteration one remains an overall FAIL under its acceptance criteria; iteration two remains NO JUSTIFIED CHANGE for batching. These outcomes narrow the next questions without closing the response-aware research direction.

IDENTITY + SIGNAL LIMITS

The host event was simulated.

No real collector detection accuracy or latency was established. Service/invocation association was trusted lab configuration, not verified PHP-FPM request attribution or hostile same-UID isolation.

Ordinary-class malicious output, matching-metadata harmful content and authorized-resource misuse remain blind spots. Origin-side effects remain outside response-abort protection.

PROTECTION + PROTOCOL LIMITS

No exploit or production claim.

No real exploit, PHP or production target was used. HTTP/3 / QUIC was not tested. Cache, retries, compression, redirects and early hints were excluded from R1; arbitrary output paths and adverse networks remain outside its proof.

No sanitizer campaign, adversarial event flood, slow-filesystem test or instrumentation-free benchmark was run. A synthetic functional PASS does not remove these limits.

What R1 has taught us

HOST STATE / NO DOMINANT COST IDENTIFIED

Matched RA-20/S2-20 comparisons did not identify idle local host-state checks as a dominant additional CPU cost. Active notifications, controller work and real collector costs need separate attribution; host evidence has not been shown to be free.

ORDINARY ALLOW / A SOURCE-IDENTIFIED CANDIDATE

The prototype still allocates a request context, registers cleanup and records five evidence events for ordinary ALLOW traffic in this fixture. A narrow fast path is a concrete candidate, not an implemented or measured optimization. It must retain contract checks, metadata DENY and the required sensitive INCONCLUSIVE hold. A missing alert cannot become ALLOW.

HOLD + TELEMETRY / ATTRIBUTION OPEN

Event/timer suspension and continuation, evidence formatting, allocation gauges, observer callbacks and request lifetime remain incompletely attributed. Fewer write calls did not solve the held-path CPU problem. No single unisolated component is the proven cause.

Source-only candidate / AppArmor: iteration two reviewed a denied unauthorized write-open against a harmless protected canary file in the upstream AppArmor permission/audit path. A possible sequence is independent host policy refusal, trusted collection of the denial, authenticated service-level evidence reaching nginx, then Gate B suppressing additional sensitive output if the evidence arrives before delivery. The host denial must remain effective even if nginx never receives the event.

No actual AppArmor policy/canary enforcement experiment or real host collector ran; no end-to-end notification-latency bound was measured. A denial does not establish absence of earlier compromise or other damage. A stream reset cannot reverse a completed host operation or retract delivered bytes. This establishes neither PHP2Shell nor ransomware prevention.

Questions for the next R1 scope

Concrete research questions, not scheduled experiments or promised improvements.
QuestionEvidence needed
How much CPU belongs to ordinary observation versus hold/continuation?Matched attribution of observation, gauges and event/timer work without changing the security timing contract.
Can a narrow ALLOW fast path reduce overhead?Measured savings while preserving contract validation, metadata DENY and holds for sensitive INCONCLUSIVE output.
Can real host-enforcement evidence arrive soon enough?Trusted collection and service association, with end-to-end timing measured against actual client delivery.
How are missing, delayed or lost events represented?Explicit unknown/freshness state and loss accounting; silence must never certify safety.
How can independent host prevention coexist with less legitimate disruption?Verify the host denial independently, then measure additional response containment and collateral loss separately.

Any next experiment requires separate authorization and predeclared criteria. Narrower routes or shorter holds change coverage and need equivalent response-aware controls. No HPACK/G0A CPU offset, production protection or future result is assumed.

Iteration 1
2026-10-23 / EXECUTED / OVERALL FAIL — CPU COST; scoped functional PASS.
Iteration 2
2026-10-24 / NO JUSTIFIED CHANGE for batching; tested security/lifecycle regression subset passed.
Source baseline
nginx 1.31.7; all 523 archive files matched the stock and canonical inputs. Only the disposable experimental upstream source received the explicit gate.
nxTLS revision
a7986bd6f1d349772172fa62130432fee74eba40; no product source, decision or integration adopted.
Build provenance
Clang 21.1.8; matched TLS/HTTP/2 builds and identical existing static BoringSSL inputs at pin 594a44291086dcc7cef06cabec4c0b47afd674c0. BoringSSL was not rebuilt; this is matched-input provenance, not a fresh reproducible-build proof.
Evidence accounting
3,960 primary requests plus 113 diagnostic/superseded/interrupted requests = 4,073 total. The interrupted flow-control client error and superseded reload probes were preserved separately, corrected and not counted as primary successes.
Historical design
The source audit established the pre-output continuation boundary, filter-order concern and existing stream-finalization path. The reset design specified the six arms and cost gates before execution; it did not pre-establish safe containment.
Research status
Ongoing A+B research. Efficiency and real host-side evidence require separate investigation; neither iteration authorizes another experiment or product integration.
References
nginx development guide · proxy buffering semantics · HTTP/2 specification
Experiment outcomes, ongoing research: iteration one remains FUNCTIONAL PASS / OVERALL FAIL — CPU. Iteration two rejected the tested batching candidate with NO JUSTIFIED CHANGE. Neither outcome qualifies the mechanism for adoption or ends the A+B research direction.
More questions raised.
More answers earned.R1 demonstrated a bounded synthetic containment advantage, exposed implementation costs, rejected an unsupported optimization and identified more precise questions about efficiency and real host-side protection.