README.md (7984B)
Handler library validation fixtures
library.tri is the normal native-library corpus, run by
test/handler_library.py. Its direct benchmark intentionally uses the lighter
production server route. The library consumer has more validation obligations.
The corpus also checks H.checkWith and H.checkRequest with transformed values,
nonempty success/rejection remainders, malformed truth flags, and divergent
unselected callbacks/payloads. Scripted requests check that rejected inputs stop
before dispatch and reply checks run after the observed request. Logger rejection
checks preserve labels and leave the sink uncalled.
equivalent.tri is compiled only by test/handler_costs.py, through a generated
workspace. That runner exposes private contract functions by inserting export
lines into temporary copies of handler_artifacts and handler_log. The
functions' bodies are unchanged; the application/library and direct comparison
both import those same copies. No test-only switches are added to lib/.
The full direct comparison has these boundaries:
| Boundary | Direct implementation | Library implementation |
|---|---|---|
| Per-request context | Proper-list check before entering the diagnostic label | Log.withContext |
| API digest | Server.bundleHashC; invalid input is an ordinary Result |
Artifacts.loadFrom |
| Request callback protocol | checkedInvoke, with B.anyC input |
H.checkedRequest |
| Adapter digest/path | Shared authenticated filesystem adapter | Artifacts.withFilesystem |
| Load reply | Exact shared Artifacts.loadReplyC |
Same contract |
| Initial logging event | Exact shared Log.eventC |
Log.emit |
| Decorated event | Same contract after context concatenation | Log.withSink |
| Logging storage | Explicit sequential source state, ordinary Result unit | recordLog through the test observer |
| Logging reply | Exact shared Log.replyC |
Log.emit reply check |
| Application policy | Redacted 404, invalid-digest 400, terminal logger failure | Demo GET consumer |
| Final observation | Execution Result containing all responses and logs | Same output |
Full-profile malformed-input/reply probes compare independently specified execution diagnostics AND read/log traces. These include invalid contexts, invalid digests, octets above 255, noncanonical naturals, improper byte lists, invalid Result envelopes/remainders, and ordinary read/log failures. The facade's mocked read service is deliberately separate from the real raw-reader boundary; permission-denial and raw invalid-digest controls exercise the latter.
Profiles are [API-digest body-bytes context-list event-shape sink-reply] flags.
Disabled contract callbacks use B.anyC or the test-local envelope-only contract.
This leaves callback/envelope plumbing in place rather than treating removal as
an isolated cycle count for a predicate. The all-off profile still checks digests
at the filesystem boundary and still checks service Result shape/remainder.
The raw-reader counterexample runs without IO permission: invalid path input must
be rejected before requesting filesystem access.
The profiles intentionally cease to satisfy particular library invariants; their counterexamples document that fact. They are never used as production substitutes or to update expected behavior of the full library. Handler lookup, lifetime, resource ownership, and security authority are not altered by this experiment.
Reproduction and measurement boundaries are in
Testing.
Generated measurements and investigation notes belong outside the repository's
docs/, not in this fixture guide.
Validator optimization controls
The cost runner also exposes byteC and bytesC in its temporary workspace and
checks batched results against Python-constructed structural domains. It covers
all canonical octets, canonical numerals through 1024, all tree shapes through
seven nodes, and mutations with invalid bits, redundant high zeros and improper
tails. Digest checks cover every octet at the first, middle and last positions,
length boundaries and malformed tails. Contracts must preserve both accepted
values and a nonempty supplied remainder, including first-error diagnostics.
validator_cases counts individual results separately from subprocess runs.
hashDemand supplies deliberately divergent terms as the 65th element/suffix,
and after an invalid first character. These must remain unforced. The process
guard bounds an accidental demand regression. These are rejection controls, not
claims that validation terminates on every arbitrary computation supplied as data.
The optimized octet scanner checks exact Boolean bits and canonical termination
through eight fixed continuation steps; it never calls unchecked arithmetic on input.
The byte-list contract scans without rebuilding the accepted list or creating a
Result for every successful element. This specialization is valid because the
octet contract does not transform values; it is not a replacement for general
listOf, whose transformation/proxy behavior remains necessary.
The digest predicate checks disjoint structural ranges for the sixteen lowercase
hex characters and uses fixed unary fuel at the 64-character boundary. The
explicit-length bundleHashBytes helper retains its numeric-counter interface.
Both the API check and the raw filesystem adapter check remain enabled.
Large response controls
validateLengths checks the specialized HTTP body-spine count; the Python
runner also checks the original general-purpose length against the same
independent expectations. Arbitrary small trees, malformed list tails, canonical
numerals used as lists, and lists crossing binary count boundaries are included.
length_cases is separate from octet/digest validation counts. lengthDemand
ensures elements are not evaluated, including before an improper-tail failure.
The specialized count preserves length's not a list Result on malformed
spines; it does not assert that elements are octets. Octet checks remain at the
artifact boundaries and host send encoding.
The HTTP count forces each successor's outer constructor before traversing the
next list cell. This avoids a per-element successor continuation chain and the
transformed list required by general listOf; general collection contracts and
base.length are unchanged. The body is still materialized, not streamed.
The stdout sink test checks both its Result and the actual rendered status line. A successful sink Result without the line is not accepted as a logging oracle.
Streaming upload demand boundaries
The opt-in handler_upload producer protocol uses native incremental staging,
not a source list of chunks. streamChunks tests the source facade with small
preconstructed chunks; it is not the memory benchmark. Native UploadTests
exercise canonical decoding, exact counts, owner/lifecycle rules, atomic rename,
permissions, abandonment and teardown. streaming_protocol.py exercises real
HTTP fragmentation, EOF, staging visibility and admission failure.
The streaming benchmark exposed retention in the handler interpreter itself:
lazy popped-frame tail projections and unused diagnostic label spines could
retain consumed request contexts. The interpreter now demands the popped tail's
outer list constructor and settles label list spines at host-IO boundaries.
It does not force label payloads or unselected continuations. Dynamic divergent
payload/continuation controls in library.tri verify those demand boundaries.
This changes evaluation demand for interpreter bookkeeping, not lexical handler
selection, forwarding, scope restoration, or ordinary Result semantics.
The bounded live test enforces both RSS and GC-sampled live-heap limits. A body protocol with small chunks but growing continuation history is not accepted as bounded merely because its native writer only retains one buffer.