Context
While testing the agent-driven policy management demo path, an experimental smoke
script (e2e/policy-advisor/mechanistic-smoke.sh) hangs waiting for a mechanistic
chunk that never arrives after an L7 deny.
Root cause: the DenialAggregator mpsc channel is wired into proxy.rs (L4
CONNECT denies) but not into l7/relay.rs (HTTP method/path denies). This is
not a recent regression. PR #326 introduced the aggregator and only plumbed
the L4 deny sites; the L7 enforcement module has never had the wiring.
Decision
Mechanistic chunk generation stays L4-only. L7 denies are the agent-authored
loop's job.
Rationale:
- L4 denies carry no semantic structure beyond
host:port. A deterministic
mapper produces the same proposal an LLM would. No tokens needed.
- L7 denies carry method, path, query, body. The whole pitch of the agent
loop is read the structured 403, draft the narrowest rule. A mechanistic
L7 mapper would either over-broaden ("allow any PUT to host") or hard-code
path templating and rot fast.
Work
- Retarget
e2e/policy-advisor/mechanistic-smoke.sh to exercise an L4
deny (CONNECT to a host not in the allowlist) instead of an L7 PUT. Assert
the mechanistic chunk appears under openshell rule get --status pending.
- Add a short note in
architecture/sandbox.md (or the closest existing
doc) describing the L4-mechanistic vs L7-agent split as the intentional
design.
- Verify (or add) a positive unit test that an L4 deny enqueues a
DenialEvent.
Known gap (track separately if it becomes a real complaint)
Sandboxes running without an in-sandbox agent get nothing in the proposal
inbox after an L7 deny — silent failure from the developer's POV. Two
possible mitigations if this ever becomes load-bearing:
- Emit a conservative L7 mechanistic chunk (method + host only, no path)
tagged "needs refinement"; agent-authored proposals dedup/supersede.
- Surface raw L7 denies in
openshell rule get under a separate
"observed denies" bucket, not as proposals.
Neither is needed today; both depend on whether real users hit it.
Out of scope
Context
While testing the agent-driven policy management demo path, an experimental smoke
script (
e2e/policy-advisor/mechanistic-smoke.sh) hangs waiting for a mechanisticchunk that never arrives after an L7 deny.
Root cause: the
DenialAggregatormpsc channel is wired intoproxy.rs(L4CONNECT denies) but not into
l7/relay.rs(HTTP method/path denies). This isnot a recent regression. PR #326 introduced the aggregator and only plumbed
the L4 deny sites; the L7 enforcement module has never had the wiring.
Decision
Mechanistic chunk generation stays L4-only. L7 denies are the agent-authored
loop's job.
Rationale:
host:port. A deterministicmapper produces the same proposal an LLM would. No tokens needed.
loop is read the structured 403, draft the narrowest rule. A mechanistic
L7 mapper would either over-broaden ("allow any PUT to host") or hard-code
path templating and rot fast.
Work
e2e/policy-advisor/mechanistic-smoke.shto exercise an L4deny (CONNECT to a host not in the allowlist) instead of an L7 PUT. Assert
the mechanistic chunk appears under
openshell rule get --status pending.architecture/sandbox.md(or the closest existingdoc) describing the L4-mechanistic vs L7-agent split as the intentional
design.
DenialEvent.Known gap (track separately if it becomes a real complaint)
Sandboxes running without an in-sandbox agent get nothing in the proposal
inbox after an L7 deny — silent failure from the developer's POV. Two
possible mitigations if this ever becomes load-bearing:
tagged "needs refinement"; agent-authored proposals dedup/supersede.
openshell rule getunder a separate"observed denies" bucket, not as proposals.
Neither is needed today; both depend on whether real users hit it.
Out of scope
validation_result(feat(policy): suggest L7 scoping for known REST hosts #1099).