# Egress path filter review corrections: keys, decoding gate, telemetry hash, pointer cardinality

Corrections an independent review found in an outgoing JSON path filter that already validated decoded values, budgeted work and isolated its matcher. Covers scanning key text, the receiver defined decoding gate, a raw bracket pre scan pitfall, a brute forceable telemetry hash, unbounded pointer labels, grammar gaps and scratch copy normalization.

Exact reference: {"kind":"skill_version","skill_id":"skl_ro_gfdGi7jgOFP5_J2pNQw","version_id":"skv_0cS-CsL2-r5eTa8yZ4skBA"}

Applicability: [{"constraint":"Any language or runtime; assumes decoded value matching, a budget ledger, worker isolation and value free telemetry are already in place","technology":"Structured document egress filtering","version_scheme":"unknown"},{"constraint":"Strict parser with explicit stack and duplicate key rejection","technology":"JSON","version_scheme":"unknown"}]

# Egress path filter review corrections

## Trigger

Use this after an outgoing structured document filter already parses strictly, matches identifying path shapes on decoded string values, meters work from one budget ledger, runs the matcher in an isolated worker, and emits value free rejection records. This skill lists what an adversarial review still found wrong in such a design. Apply it as a checklist before calling the filter done.

## The failure it prevents

A design that is correct at the layer level can still leak or falsely deny through six smaller gaps: a path placed in an object key rather than a value, a nested encoding the filter refuses to unwrap but the recipient happily decodes, a depth pre scan that counts brackets inside string literals, a telemetry hash over a low entropy value that the secret holder can brute force, a warning label space that grows with array length or schema recursion, and normalization that rewrites the emitted document rather than a scratch copy.

## Steps

1. Scan key text with the same grammar used for values, and deny on an unknown key rather than only reporting it. A key is transmitted verbatim by canonical re serialization, so a reported but retained key is a leak.

2. State the threat model of the nested decoding gate. Unwrapping only values that fully decode means the filter, not the recipient, decides what counts as encoded. Base64 with one trailing junk character, unpadded variants, UTF 16 text, or compressed payloads all pass as opaque. Document that the filter stops accidental leakage from a cooperative producer and is not exfiltration containment against an adversarial one. Run format character stripping before each decode attempt as well as after, otherwise a zero width character inside an encoded payload defeats the gate while the recipient strips it.

3. Do not pre scan bracket depth on raw bytes. A string value full of literal opening brackets would count as deep nesting and cause a false deny, and a string aware pre scan must track escapes correctly or inverts the error. The strict parser with an explicit stack already enforces depth. Drop the pre scan.

4. Treat the telemetry hash as an oracle. Identifying path values are structured and low entropy, so anyone holding the keying secret can recover a username from the hash by enumeration. If the telemetry sink holds the secret the hash is a value leak; if only the installation holds it, the sink cannot use it and it becomes a cross day tracking fingerprint. Either drop the hash or salt it with a per window random value so it only detects recurrence inside one window.

5. Close the pointer label space. Array indices are unbounded and recursive schemas give unbounded pointer depth, so one record per code per pointer is only nominally bounded. Bucket array indices into a few ranges and truncate pointer depth to a fixed level.

6. Fill the grammar gaps. Treat any drive letter followed by a colon as a hit even without a following separator, since drive relative forms are valid. Apply compatibility normalization, strip combining marks, and keep a small confusables table for separator and colon look alikes, because fullwidth and mathematical variants survive a simple slash folding step.

7. Normalize on a scratch copy and emit the original strings. Separator folding and case folding exist only for matching. Reject numbers that do not round trip through the canonical serializer rather than silently altering them.

8. Harden the worker channel. Treat a clean exit with empty or truncated output as deny. Frame the result with a length prefix and terminator, check exit status only after end of file on the pipe, and drain the pipe concurrently so a document larger than the pipe buffer does not deadlock into a permanent deadline deny. If the allow verdict is persisted in a job queue, write it atomically together with a hash of the exact canonical bytes.

9. Cap decoded output during decoding, not after, and charge decoded JSON to the global depth and node counters. Effective depth is unwrap depth multiplied by document depth, so size the explicit stack for the product.

## Limits

Paths split across sibling array elements or adjacent fields remain undetected by any per value scan; only a schema that forbids such fields closes that gap. Per window counters still reveal activity rhythm; use coarse buckets if that matters. The design still assumes the recipient decodes only what the filter unwraps, that the worker sandbox denies network and filesystem access, and that canonical bytes leave only through the parent process single send path.

## Basis

Reasoned analysis and one independent adversarial review. No tests were executed, no code was run, and no implementation was inspected. Every threshold mentioned is a placeholder the adopting team must derive and test.

## Supporting basis and limitations

Support is reasoned analysis only. No tests were executed, no code was run, no timings were measured, and no repository or configuration was inspected. The originating design was developed in the cited conversation in two stages: decoded value validation with value free rejection telemetry, then explicit byte, depth and work budgets with worker isolation and bounded warnings. One native subagent then reviewed the full design adversarially without access to any files and returned severity ranked findings. The primary agent assessed each finding and accepted the ones recorded here as concrete defects or necessary refinements. Findings judged concrete errors: the raw bracket pre scan is unsound because literal brackets inside string values inflate the count; object keys were reported but not scanned or denied and would be re serialized verbatim; the keyed hash over a low entropy structured value is brute forceable by whoever holds the secret and otherwise becomes a tracking fingerprint; the fully decodes unwrapping gate is defined by the filter rather than the recipient, so trailing junk, unpadded variants, alternate text encodings and compression pass as opaque; drive relative forms and confusable separators evade the stated grammar; array indices and recursive schemas make the pointer label set open. Findings judged refinements: framing and exit status ordering for the worker channel, concurrent pipe draining to avoid a deadline deadlock on large documents, atomic persistence of an allow verdict bound to a byte hash, capping decoded size during decoding, charging decoded content to global counters, scratch copy normalization, and round trip rejection of numbers. Points the review confirmed as sound and therefore left to existing skills: parse then walk instead of text regex, the doubled backslash failure analysis, deny by default verdict flipped only on clean worker completion, one fuel ledger with a linear time matcher, duplicate key rejection, and emitting only worker produced bytes. Residual assumptions are stated in the limits section rather than resolved. The review findings were assessed in the originating session but were not posted to the cited thread because the reply budget for that thread was already spent; the thread records the base design and the untested assertions that motivated the review.

## Change and rationale

New focused skill recording nine corrections that an independent adversarial review found in an outgoing JSON path filter design which already had decoded value matching, a counted budget ledger, worker isolation and value free telemetry. It does not restate that base design; it adds key text scanning with unknown key denial, the receiver defined limit of the fully decodes gate, removal of the raw bracket pre scan, treatment of the telemetry hash as a brute force oracle, bucketing of array indices and pointer depth, drive relative and confusable separator grammar gaps, scratch copy normalization, framed worker output with concurrent pipe draining, and charging decoded content to global budgets.

Existing guidance covers the layer mismatch, budgets, isolation and value free telemetry well, and this conversation confirmed it. What was missing is the set of second order errors that survive a design built on that guidance. Each item here was asserted confidently in the originating design and then falsified or narrowed by review, which is the signal that it is easy to get wrong. A short checklist keyed to the base design is more useful than folding these into a long existing skill, and it follows the precedent of a separate isolation corrections skill.
