[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7E6DPQTDJSW02J27MPRSKZX":3,"skill-same:01M7E6DPQTDJSW02J27MPRSKZX":109},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":20,"linkOnly":21,"markdownContent":22,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":14,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":30,"ownerDescription":31,"updatedAt":32,"install":33,"resources":46},"01M7E6DPQTDJSW02J27MPRSKZX","scala-http-server-semantics",null,"Use when changing or reviewing HTTP server\u002Fclient semantics in Scala libraries (http4s Ember HTTP\u002F1 framing and connection reuse, http4s URI path segments, Cask route-trie validation and 404\u002F405 dispatch, ZIO HTTP pooled-channel handoff, middleware execution boundaries and error disclosure, Play CORS\u002FCSRF filter policy) by treating behavior as an explicit matrix of observable outcomes. Covers protocol and policy decisions at the request\u002Fconnection boundary; effect cancellation, stream scoping, binary compatibility and hot-path cost belong to the sibling merged skills.","w0rxbend\u002Fdot-agents","w0rxbend","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F8176996?v=4","01M7E4XY3Y871Z2NFBXF3H3T8F","Oleksandr B.","01M7E4XY51E6NSG05FXR36H9RV",0,"MIT","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: scala-http-server-semantics\ndescription: Use when changing or reviewing HTTP server\u002Fclient semantics in Scala libraries (http4s Ember HTTP\u002F1 framing and connection reuse, http4s URI path segments, Cask route-trie validation and 404\u002F405 dispatch, ZIO HTTP pooled-channel handoff, middleware execution boundaries and error disclosure, Play CORS\u002FCSRF filter policy) by treating behavior as an explicit matrix of observable outcomes. Covers protocol and policy decisions at the request\u002Fconnection boundary; effect cancellation, stream scoping, binary compatibility and hot-path cost belong to the sibling merged skills.\nlicense: MIT\n---\n\n# Scala HTTP server semantics as a behavior matrix\n\nSeven historical cases from http4s, Cask, ZIO HTTP and Play share one failure shape. Refactor keeps one visible signal\ngreen (status code, empty body, successful startup, passing replacement test) but silently changes another HTTP\ncontract dimension (unread socket bytes, segment boundaries, lost duplicate registration, borrower admitted too early,\nprotected handler still ran, stack trace shown to wrong request, token cookie behind public cache).\n\nEach case derived from pinned 2019-2024 source and maintainer PR review history, then audited. Evaluated by source\ninspection and model-based review; **no upstream build, test, socket, or browser probe was executed** during research.\n\n## When to Use\n\n- Diff changes HTTP\u002F1 response framing, HEAD\u002Fno-body handling, drain\u002Fremainder metadata, or pool reuse decisions.\n- Diff changes URI path parsing, rendering, segment constructors, normalization, or String-to-Path equality.\n- Diff changes route registration, route-trie construction, ambiguity validation, or missing-path\u002Fmissing-method status.\n- Diff changes pooled-channel completion, close listeners, body last-message callbacks, or request-scope finalizers.\n- Diff moves middleware relative to route selection or protected handler, or changes fallback between routes.\n- Diff changes exception\u002Fcause-to-response rendering, debug flags, or where disclosure policy is stored and read.\n- Diff changes CORS origin-to-header decisions or CSRF token\u002Fshared-cache predicates, their config readers, or tests.\n- Same shapes in another Scala HTTP stack (Akka\u002FPekko HTTP, Finagle, Tapir interpreters, sttp backends); apply\n  transferable checks only and rediscover library facts from source.\n\n## When Not to Use\n\n- HTTP\u002F2 framing, request-smuggling diagnosis, complete URI\u002FRFC conformance audits, full CSRF\u002FCORS security design,\n  or browser\u002FCDN behavior claims.\n- General effect cancellation, `Resource`\u002F`Scope` finalization or outcome-sensitive concurrency without HTTP\n  ownership question: use `scala-effect-cancellation-finalization`. Stream scoping and sink cardinality:\n  `scala-stream-resource-scoping`. Public API\u002Fbinary compatibility and law-backed instances:\n  `scala-library-compatibility-laws` or `scala-library-contracts`. Hot-path cost and diagnostic modes:\n  `scala-runtime-diagnostics-hot-paths`. Macro\u002Fcompiler refactors: `scala-compiler-macro-refactoring`.\n- Choosing library for new project; use `scala-oss-library-review` router.\n- Converting target's effect model. No case justifies moving Cask, Play, http4s or ZIO HTTP to Cats Effect, ZIO,\n  FS2, Future or Ox; keep local runtime, syntax and build tool.\n- Approving or rejecting intentional, documented policy change as if regression (see False positives).\n\n## Prerequisites\n\n1. Identify library, exact source SHA or version, Scala cross versions, effect runtime version, transport (Netty,\n   Undertow, Ember\u002FFS2, Akka\u002FPekko), JDK, and build tool. Historical anchors differ per case and are **not** current\n   targets (see Version fences).\n2. Trace each touched operator to definition and callers; names like `Drain`, `middleware`, `isCached`, `Invalid` or\n   `normalize` do not establish semantics.\n3. Load relevant case reference(s) from routing table before writing findings.\n\n## Shared model: invariants that recur across cases\n\nCase names in parentheses are files under `references\u002F`.\n\n**I1. One green signal is not the contract; enumerate observable dimensions.** Record each dimension independently\nbefore and after change.\n\n- Framing: body exposed to callers, bytes buffered after framing, bytes still unread on socket, connection\n  disposition. Empty public body establishes none of other three (`http4s-http1-bodyless-connection-framing`).\n- Middleware rejection: status, protected-handler execution count, response body\u002Fheader content\n  (`zio-http-middleware-execution-boundaries`).\n- Error rendering: status, generated body presence, stack presence, serialization validity\n  (`zio-http-request-local-error-disclosure`).\n- CORS: ACAO, ACAC, Vary, status, on normal and preflight paths; CSRF: token-cookie outcome with token-creation\n  eligibility held constant (`play-cors-csrf-policy-matrix`).\n- Routing: construction success, selected endpoint, wildcard bindings, remaining segments, 404 vs 405\n  (`cask-route-trie-validation-order`).\n\n**I2. Absent, unknown and empty are distinct states; never collapse them.**\n\n- `None` (cannot establish reusable completion) vs `Some(Array.emptyByteArray)` (boundary known, nothing buffered);\n  `getOrElse(empty)` erases this (`http4s-http1-bodyless-connection-framing`).\n- Play CORS: configuration `null` -> `Origins.All`; case-class default `Origins.None`; literal origin string `\"null\"`;\n  list containing `*`. Four meanings (`play-cors-csrf-policy-matrix`).\n- Play CSRF: absent `Cache-Control` returns `false` from historical shared-cache predicate; that is not proof response\n  is uncacheable (`play-cors-csrf-policy-matrix`).\n- ZIO HTTP: unmatched input vs selected handler's typed failure vs defect\u002Finterruption are distinct fallback\n  categories (`zio-http-middleware-execution-boundaries`); `Invalid` never authorizes reuse\n  (`zio-http-channel-handoff-completion`).\n- http4s: encoded segment text vs decoded segment text vs whole path (`http4s-uri-segment-representation`).\n\n**I3. No lossy conversion before the decision needing the lost information.**\n\n- Cask PR 52: `values.map(_._2).flatten.toMap` dropped duplicate same-method registrations before trie validation;\n  PR 70 keeps sequence, validates per method group, and calls `map(_.toMap)` only after construction\n  (`cask-route-trie-validation-order`).\n- http4s: decoding `\u002Fa%2Fb` to `\u002Fa\u002Fb` before splitting turns one segment into two\n  (`http4s-uri-segment-representation`).\n- ZIO HTTP #1916: `HandlerMiddleware` evaluates `route.run(in)` before applying aspect; transforming request first\n  can turn unmatched input into match (`zio-http-middleware-execution-boundaries`).\n\n**I4. Decide before effecting, and decide at the right scope.**\n\n- Rejection branches before invoking protected handler; status-only rewrite after execution is not rejection\n  (`zio-http-middleware-execution-boundaries`, #542).\n- Path resolution precedes method resolution: no path -> 404, path without effective method -> 405 under Cask's\n  default policy (`cask-route-trie-validation-order`).\n- Ambiguity validation is method-scoped, not path-scoped (`cask-route-trie-validation-order`).\n- Disclosure policy is request-local (FiberRef in #3050); global `Ref`, route-keyed map, or construction-time capture\n  is not equivalent optimization (`zio-http-request-local-error-disclosure`).\n- Play keeps CORS decision helper `private[play]` and deprecated `isCached` bridge forwarding to\n  `isCacheableBySharedCache` (`play-cors-csrf-policy-matrix`).\n\n**I5. Handoff only after previous owner can no longer act; cleanup must run even if consumer never pulls.**\n\n- Reusable HTTP\u002F1 connection starts next exchange at known message boundary and retains legitimate buffered\n  next-message bytes. If alignment is unknown, retire connection; do not guess\n  (`http4s-http1-bodyless-connection-framing`).\n- #4348 moved processing from body-stream finalizer to enclosing response `Resource` release: body finalizer does not\n  run for unconsumed body (`http4s-http1-bodyless-connection-framing`).\n- ZIO HTTP #2924 order: remove reader -> publish completion (`onLastMessage`) -> deliver final body callback.\n  #2610: prior-request damage is cleaned up or invalidated before return; external close is use-time failure that\n  must settle pending waits (`zio-http-channel-handoff-completion`).\n- Transferable rule: completion promise or pool return is permission for another borrower to act. Effect-runtime\n  mechanics of finalizers and interruption belong to `scala-effect-cancellation-finalization`.\n\n**I6. Oracles must be independent of implementation they check.**\n\n- JSON error test interpolating same template as renderer (`zio-http-request-local-error-disclosure`).\n- Play PR 8363: public-cache CSRF test was inverted to make parser patch pass; review restored it\n  (`play-cors-csrf-policy-matrix`).\n- Cask: trie construction tests are not lookup oracles (`cask-route-trie-validation-order`).\n- Ember: #4348's two-response test is parser-level, not network test (`http4s-http1-bodyless-connection-framing`).\n- URI: compare against literals, not another call to changed normalizer (`http4s-uri-segment-representation`).\n- ZIO pool: repeated random traffic is supplemental, not deterministic ordering oracle\n  (`zio-http-channel-handoff-completion`).\n\n**I7. Intentional policy change is not regression, but must be declared.** Routing middleware (CORS OPTIONS,\ntrailing-slash normalization, allow\u002FallowZIO, metrics) legitimately changes route sets. Application may normalize\n`\u002F\u002F` before its own lookup. Deployment may replace permissive CORS config. Ember may deliberately close after HEAD,\ntrading reuse for simpler framing. Domain endpoint may return documented public error body. Require old\u002Fnew rows and\nrationale; do not rubber-stamp, and do not reject.\n\n## Routing table\n\n| Change touches | Library \u002F anchor files or APIs | Load |\n|---|---|---|\n| HEAD \u002F status-implied no-body, `discardBody`, drain\u002Fremainder `Option[Array[Byte]]`, `ClientHelpers` reuse, response `Resource` release | http4s Ember (`ember-core` Parser, `ember-client` `ClientHelpers`) | [references\u002Fhttp4s-http1-bodyless-connection-framing.md](references\u002Fhttp4s-http1-bodyless-connection-framing.md) |\n| `Uri.Path`, `Segment.apply` vs `Segment.encoded`, `normalize`, `pathInfo`\u002F`scriptName`, String-to-Path equality, Path laws | http4s core `Uri.scala`, `PathSuite`, `UriSpec` | [references\u002Fhttp4s-uri-segment-representation.md](references\u002Fhttp4s-uri-segment-representation.md) |\n| `Main.prepareDispatchTrie`, `DispatchTrie.construct`\u002F`validateGroup`\u002F`map`, `DefaultHandler` 404\u002F405 | Cask | [references\u002Fcask-route-trie-validation-order.md](references\u002Fcask-route-trie-validation-order.md) |\n| Netty client pool return\u002Finvalidation, `onComplete`\u002F`onResponse`, close listener, `AsyncBodyReader.onLastMessage`, `ZClient` request-scope finalizer, retry schedule | ZIO HTTP JVM (`zio.http.netty.client`) | [references\u002Fzio-http-channel-handoff-completion.md](references\u002Fzio-http-channel-handoff-completion.md) |\n| Middleware lifting, `HandlerMiddleware`, CSRF\u002Fguard rejection branch, composition\u002Ffallback (`Http.Empty`), before\u002Fafter order | ZIO HTTP (`zhttp` 1.x, `zio.http` 2.x) | [references\u002Fzio-http-middleware-execution-boundaries.md](references\u002Fzio-http-middleware-execution-boundaries.md) |\n| `Response.fromThrowable`\u002F`fromCause`, error body\u002Fstack\u002Fdepth\u002Fformat config, debug middleware, FiberRef policy | ZIO HTTP `Response.scala`, `ResponseSpec` | [references\u002Fzio-http-request-local-error-disclosure.md](references\u002Fzio-http-request-local-error-disclosure.md) |\n| `CORSConfig.allowedForOrigin`, `fromUnprefixedConfiguration`, preflight path, `CSRFActionHelper` \u002F `isCacheableBySharedCache` | Play `play-filters-helpers` | [references\u002Fplay-cors-csrf-policy-matrix.md](references\u002Fplay-cors-csrf-policy-matrix.md) |\n\nChange can match several rows (e.g. ZIO HTTP CSRF middleware that also renders errors): load each. Each case's\nevidence is byte copy of its original audit record under `references\u002Fevidence\u002F`.\n\n## Workflow\n\n1. **Classify intent.** Compatibility-preserving refactor, bug fix, or declared policy change (I7). For policy\n   change, first collect old\u002Fnew matrix rows and approval\u002Fmigration note.\n2. **Pin target.** Record versions and SHA (Prerequisites). Do not transplant historical API (`zhttp.HttpData`,\n   CE2 `Resource` exit cases, `Http` vs `Routes`, Akka vs Pekko) into different line.\n3. **Draw boundary path.** From producer to consumer: parse -> represent -> decide -> effect -> respond ->\n   release\u002Fhand off. Mark every conversion (I3), every decision (I4) and every ownership transfer (I5).\n4. **Build matrix.** Rows: input classes (method, status, framing, origin config, cache directive,\n   matched\u002Funmatched, accepted\u002Frejected, typed failure\u002Fdefect\u002Finterruption, concurrent opposite policies). Columns:\n   observable dimensions from I1. Mark absent\u002Funknown\u002Fempty as separate rows (I2). Fill \"before\" column from source\n   and existing tests.\n5. **Find first lossy or reordered step.** Compare \"after\" column. Defect, if any, is usually first point where\n   later-needed information is discarded, decision moves after effect, or handoff precedes cleanup.\n6. **Choose smallest correction at that boundary.** Restore ordering or representation; do not repair by collapsing\n   states (`getOrElse(empty)`, first-wins `distinct`, catch-all fallback, process-wide flag, arbitrary sleep before\n   scope exit, reading HEAD's Content-Length).\n7. **Write discriminating tests (I6).** At least one row broken version fails and corrected version passes, plus\n   legitimate counterexample row that must still pass (GET\u002FPOST at same path, `Some(empty)` reuse, CORS OPTIONS\n   routing, public domain error body).\n8. **Discover and, only if authorized, run real targets.** See Validation. Report unexecuted obligations.\n\n## Review and Refactoring Checks\n\nTransferable checks (any Scala HTTP library):\n\n- [ ] Every observable dimension of touched branch asserted separately (I1); flag status-only tests.\n- [ ] No three-valued state collapsed into two (I2); look for `getOrElse`, `toMap`, `distinct`, `orElse`, boolean\n      predicates replacing `Option`.\n- [ ] No conversion dropping multiplicity, boundaries, or encoding state precedes validation or decision needing it\n      (I3).\n- [ ] Rejection and selection happen before protected effects; each decision's scope (request, method group,\n      selected handler) unchanged (I4).\n- [ ] Reuse\u002Fhandoff published only after previous owner's cleanup and only at known boundary; every terminal path\n      (setup failure, remote close, interruption, never-pulled body) settles what it owns (I5).\n- [ ] Review deleted or inverted assertions, not only added green tests (I6).\n- [ ] Intentional behavior changes declared with old\u002Fnew rows (I7).\n- [ ] Equality changes keep symmetry and hash agreement; no `a.equals(b) != b.equals(a)` migration shim.\n- [ ] Unrelated renames, abstraction experiments, Vary-header optimizations and effect-model changes kept out of\n      semantic repair.\n\nLibrary\u002Fversion-specific checks (verify against target source first):\n\n- [ ] Ember: `None` keeps `DontReuse`; `Some(bytes)` stores remainder before marking reuse; HEAD discard returns pure\n      `None` without read in #7369; status-implied emptiness preserves `finalBuffer`.\n- [ ] http4s URI: parsed text uses `Segment.encoded`, raw text uses `Segment.apply` (2020 snapshot names).\n- [ ] Cask: sequence retained through `prepareDispatchTrie`; `construct(...)(_.map(_._1)).map(_.toMap)` ordering.\n- [ ] ZIO HTTP pool: remove reader -> `onLastMessage` -> final callback; `Invalid` before intentional close; reset\n      failure -> invalidation; WebSocket channels excluded from historical close listener.\n- [ ] ZIO HTTP middleware: `HandlerMiddleware` applies after `route.run(in)` and preserves `Http.Empty`.\n- [ ] ZIO HTTP errors: defaults disable generated body and stack; format Html; `fromCause` preserves existing\n      `Response` and uses `prettyPrint` when body disclosure is enabled.\n- [ ] Play: explicit-origin match before wildcard; All reflects only with credential support; public-cache GET adds\n      no CSRF cookie; `Locale.ROOT` normalization; deprecated `isCached` bridge retained.\n\n## Consolidated false positives\n\n- `Some(empty)` after fully consumed response is safe to reuse; absence of buffered next bytes is not a defect.\n  Explicit closure after HEAD is not evidence bytes were drained. Reviewer's security concern is not an exploit.\n- `Segment.encoded` on previously parsed data is not injection defect; hash collisions between unequal paths do not\n  break hash law.\n- GET and POST on same Cask path are not duplicates; not every `.toMap` is the bug; deliberately concealed protected\n  resource may intentionally not return 405; two annotations on one function is separate macro boundary.\n- ZIO HTTP: `Invalid` published before intentional non-keepalive close is not reuse-before-close; open WebSocket is\n  not evidence of HTTP request hang; do not demand single callback location without proving every failure reaches\n  it. (Opposite error also common: assuming successful `isOpen` guarantees lifetime, or blaming lazy pool\n  finalization, which adamgfraser explicitly corrected in #2610.)\n- Public error bodies are allowed; #542 body-leak concern does not prohibit them. Author-reported test addition is\n  weaker than retained oracle.\n- Typed public error is not necessarily secret; reviewer's plaintext proposal is not final default (Html).\n  Conversely, request-local storage is not authorization: client header enabling debug is unsafe without access\n  control.\n- ACAC `true` alongside ACAO `*` in Play's server test is not proof of browser credentialed access; conservative\n  `Vary: Origin` on wildcard responses was accepted; deprecated forwarding method is not dead code; approved\n  secure-policy migration may break legacy rows.\n\n## Version fences\n\n| Case | Historical anchor(s) | Fence |\n|---|---|---|\n| Ember framing | #4348 `32893c3` series\u002F0.21: Scala 2.12.13\u002F2.13.4, CE 2.3.1, FS2 2.5.0; #7369 `7e5a974`: Scala 2.12.18\u002F2.13.12\u002F3.3.1, CE 3.5.3, FS2 3.9.4 | CE2 vs CE3 `Resource` exit-case APIs; suite renamed (`ParsingSpec` -> class `ParsingSuite` in `ParserSuite.scala`) |\n| URI segments | `7775249` (2020): Scala 2.12.12\u002F2.13.3, CE 2.3.1, FS2 2.5.0 | Constructor names are observed historical APIs; calendar year does not identify release line |\n| Cask routing | PR 52 `d7f7d55` (2021), PR 70 `e01c972` (2022), validation snapshot `d5fa6d4`: Scala 2.12.16\u002F2.13.8\u002F3.1.3, Mill 0.10.5, Undertow 2.2.18.Final, Java 8 CI | 2020 and late-2024 builds use different Scala\u002FMill layouts (`build.mill`); JVM-only server |\n| ZIO HTTP pool | #2610: ZIO 2.0.19, Netty 4.1.101.Final, project `zioHttp`; #2924: ZIO 2.1.1, Netty 4.1.109.Final, project `zioHttpJVM` | Not ZIO 1 `zhttp.HttpData`; JVM Netty results do not carry to Scala.js\u002FNative |\n| ZIO HTTP middleware | #542: ZIO 1.0.13, package `zhttp`, project `zhttp`; #1916: ZIO 2.0.6, package `zio.http`, project `zioHttp` | `Http` vs modern `Routes`\u002Fhandler aspects |\n| ZIO HTTP errors | #3050 `ab9fdf7`: ZIO 2.1.8, Netty 4.1.112.Final, Scala 2.12.19\u002F2.13.14\u002F3.3.3; `ResponseSpec` JVM-only | #850 (2022) is earlier concern; successor #1024 unverified |\n| Play filters | 2019\u002F2020 Scala 2 + Akka (`Filters-Helpers`); Dec 2022 Akka 2.6.20; Dec 2024 Scala 2.13.15\u002F3.3.4 + Pekko 1.0.3 (`Play-Filters-Helpers`) | Project IDs, integration config (`It` vs `Test`) and backend differ per era |\n\n## Validation\n\nEvery command below is source-derived; rediscover it on target checkout.\n\n1. Read build first (`build.sbt`, `project\u002F*.scala`, `project\u002Fbuild.properties`, `build.sc`\u002F`build.mill`,\n   `.mill-version`, CI JDK settings) and suite's package declaration. Loading sbt or Mill build executes code, and\n   Cask Mill wrapper may download an executable: get separate authorization and isolate checkout.\n2. Discover before running: `sbt projects` then `sbt 'show \u003Cproject> \u002F Test \u002F definedTests'`, or\n   `.\u002Fmill resolve '\u003Cmodule>.test'`. Require nonzero discovered tests. Trait (Play `CORSCommonSpec`) is not runnable\n   suite: find its concrete consumers or run project's whole `test`.\n3. Run narrowest discovered selector. Historical selectors per case live in each reference's Validation section.\n4. Add matrix tests per Workflow. Where oracle is runtime ordering (pool handoff, never-pulled body, concurrent\n   policies), use controlled barriers, overall deadline, and cleanup after failure. Observe connection or channel\n   identity, close\u002Freuse events, handler counts, and promise outcomes.\n5. Isolate global state: Cask example fixtures both bind `localhost:8081` (serialize them); locale-sensitive Play tests\n   restore default locale in `finally`.\n6. Label evidence by layer: source observation, reviewer testimony, parser-\u002Fhelper-level test, executed transport or\n   browser evidence. Server headers are never browser or CDN proof.\n\n## Examples\n\n### Good\n\nCask cleanup keeps method entries as sequence until `DispatchTrie.construct` validates each method group, then maps\npayloads to method maps. Its test pairs rejected duplicate-GET registration (through `prepareDispatchTrie`, asserting\ndiagnostic reason) with GET\u002FPOST reachability at same path, unknown-path 404, and DELETE-on-POST 405. Covers every I1\nrouting dimension; I7 counterexample still passes.\n\n### Broken and Correction\n\nZIO HTTP CSRF refactor invokes application unconditionally, then overwrites status to Forbidden on token mismatch. It\nrenders exception into JSON by string interpolation. Status-only test passes. Correction: branch before invocation\n(I4); assert zero protected-execution counter and absent body sentinel (I1). Render with build's real JSON encoder; in\ntest, parse output with quote\u002Fnewline\u002Fcontrol characters (I6). Keep disclosure policy request-local (I4). Load both\nmiddleware and error-disclosure references.\n\n### Negative\n\nEmber change returns `Some(Array.emptyByteArray)` after fully consumed fixed-length body and marks connection reusable\nwhile next exchange has not started. Do not flag it: boundary is known (I2), and #4348 explicitly distinguishes this\nnon-pipelined case. Likewise, Play deployment replacing null CORS config with explicit trusted list and documenting\nnewly rejected origins is declared migration (I7), not compatibility bug.\n\n## Output Contract\n\nFor each finding return:\n\n- `file:line`, severity, case reference(s) used, and invariant (I1-I7) violated.\n- Exact matrix row(s) before and after: inputs and each observable dimension.\n- Evidence: claim IDs from `references\u002Fevidence\u002F\u003Csource-id>.json` and pinned source\u002FPR URLs.\n- Smallest correction at first lossy\u002Freordered boundary, and one legitimate counterexample that must still pass.\n- Discriminating test and oracle layer it reaches (parser\u002Fhelper, in-process HTTP, socket, browser).\n- Target version tuple, discovered selectors, commands actually executed with results, and explicit unexecuted\n  obligations. Separate source observation, reviewer proposal, merged decision, and current-version inference.\n\nJustified non-finding is valid: name guard, owner, or declared policy making suspicious change safe, and list matrix\nrows still untested. Never turn structural pass into safety certification.\n\n## Limitations\n\n- Invariants synthesize seven historical cases; they are not maintainer-stated universal policy. Reviewer statements\n  are attributed to their PRs. Merges without retrieved discussion (Cask PR 70, ZIO HTTP #2924's praise-only approval)\n  are not design reviews.\n- No upstream compilation, test execution, socket trace, race reproduction, browser probe or performance measurement\n  performed. No current-version vulnerability or defect asserted.\n- Not covered: HTTP\u002F2, request smuggling, complete URI\u002FRFC conformance, CSRF token strength, cookie policy, origin\n  validation design, complete cache-directive grammar, WebSocket lifecycles, and Scala.js\u002FNative transports.\n- Several historical exemplars carry their own observed gaps (http4s 2020 `normalize` default flags, String split\n  trailing-empty handling, Segment equality fallback; Cask shared-children lookup for mixed-method wildcard\u002Fsubpath\n  routes). These limit exemplars; they are not proven current defects.\n\n## Sources\n\nPer-case procedures, PR\u002Fcommit permalinks and test oracles live in references; each links its evidence record:\n\n- [http4s Ember HTTP\u002F1 bodyless framing](references\u002Fhttp4s-http1-bodyless-connection-framing.md) -\n  [evidence](references\u002Fevidence\u002Fscala-http4s-http1-bodyless-connection-framing.json) (`c-framing-connection-contract`, `c-drain-reuse-state`)\n- [http4s URI segment representation](references\u002Fhttp4s-uri-segment-representation.md) -\n  [evidence](references\u002Fevidence\u002Fscala-http4s-uri-segment-representation.json) (`c-uri-representation-laws`)\n- [Cask route-trie validation order](references\u002Fcask-route-trie-validation-order.md) -\n  [evidence](references\u002Fevidence\u002Fscala-cask-route-trie-validation-order.json)\n- [ZIO HTTP channel handoff completion](references\u002Fzio-http-channel-handoff-completion.md) -\n  [evidence](references\u002Fevidence\u002Fscala-zio-http-channel-handoff-completion.json) (`c-pool-handoff`, `c-pool-callback-order`)\n- [ZIO HTTP middleware execution boundaries](references\u002Fzio-http-middleware-execution-boundaries.md) -\n  [evidence](references\u002Fevidence\u002Fscala-zio-http-middleware-execution-boundaries.json) (`c-middleware-semantics`)\n- [ZIO HTTP request-local error disclosure](references\u002Fzio-http-request-local-error-disclosure.md) -\n  [evidence](references\u002Fevidence\u002Fscala-zio-http-request-local-error-disclosure.json) (`c-error-disclosure`)\n- [Play CORS\u002FCSRF policy matrix](references\u002Fplay-cors-csrf-policy-matrix.md) -\n  [evidence](references\u002Fevidence\u002Fscala-play-cors-csrf-policy-matrix.json) (`c-filter-defaults`, `c-filter-boundaries`, `c-filter-test-discovery`)\n","# Scala HTTP server semantics as a behavior matrix\n\nSeven historical cases from http4s, Cask, ZIO HTTP and Play share one failure shape. Refactor keeps one visible signal\ngreen (status code, empty body, successful startup, passing replacement test) but silently changes another HTTP\ncontract dimension (unread socket bytes, segment boundaries, lost duplicate registration, borrower admitted too early,\nprotected handler still ran, stack trace shown to wrong request, token cookie behind public cache).\n\nEach case derived from pinned 2019-2024 source and maintainer PR review history, then audited. Evaluated by source\ninspection and model-based review; **no upstream build, test, socket, or browser probe was executed** during research.\n\n## When to Use\n\n- Diff changes HTTP\u002F1 response framing, HEAD\u002Fno-body handling, drain\u002Fremainder metadata, or pool reuse decisions.\n- Diff changes URI path parsing, rendering, segment constructors, normalization, or String-to-Path equality.\n- Diff changes route registration, route-trie construction, ambiguity validation, or missing-path\u002Fmissing-method status.\n- Diff changes pooled-channel completion, close listeners, body last-message callbacks, or request-scope finalizers.\n- Diff moves middleware relative to route selection or protected handler, or changes fallback between routes.\n- Diff changes exception\u002Fcause-to-response rendering, debug flags, or where disclosure policy is stored and read.\n- Diff changes CORS origin-to-header decisions or CSRF token\u002Fshared-cache predicates, their config readers, or tests.\n- Same shapes in another Scala HTTP stack (Akka\u002FPekko HTTP, Finagle, Tapir interpreters, sttp backends); apply\n  transferable checks only and rediscover library facts from source.\n\n## When Not to Use\n\n- HTTP\u002F2 framing, request-smuggling diagnosis, complete URI\u002FRFC conformance audits, full CSRF\u002FCORS security design,\n  or browser\u002FCDN behavior claims.\n- General effect cancellation, `Resource`\u002F`Scope` finalization or outcome-sensitive concurrency without HTTP\n  ownership question: use `scala-effect-cancellation-finalization`. Stream scoping and sink cardinality:\n  `scala-stream-resource-scoping`. Public API\u002Fbinary compatibility and law-backed instances:\n  `scala-library-compatibility-laws` or `scala-library-contracts`. Hot-path cost and diagnostic modes:\n  `scala-runtime-diagnostics-hot-paths`. Macro\u002Fcompiler refactors: `scala-compiler-macro-refactoring`.\n- Choosing library for new project; use `scala-oss-library-review` router.\n- Converting target's effect model. No case justifies moving Cask, Play, http4s or ZIO HTTP to Cats Effect, ZIO,\n  FS2, Future or Ox; keep local runtime, syntax and build tool.\n- Approving or rejecting intentional, documented policy change as if regression (see False positives).\n\n## Prerequisites\n\n1. Identify library, exact source SHA or version, Scala cross versions, effect runtime version, transport (Netty,\n   Undertow, Ember\u002FFS2, Akka\u002FPekko), JDK, and build tool. Historical anchors differ per case and are **not** current\n   targets (see Version fences).\n2. Trace each touched operator to definition and callers; names like `Drain`, `middleware`, `isCached`, `Invalid` or\n   `normalize` do not establish semantics.\n3. Load relevant case reference(s) from routing table before writing findings.\n\n## Shared model: invariants that recur across cases\n\nCase names in parentheses are files under `references\u002F`.\n\n**I1. One green signal is not the contract; enumerate observable dimensions.** Record each dimension independently\nbefore and after change.\n\n- Framing: body exposed to callers, bytes buffered after framing, bytes still unread on socket, connection\n  disposition. Empty public body establishes none of other three (`http4s-http1-bodyless-connection-framing`).\n- Middleware rejection: status, protected-handler execution count, response body\u002Fheader content\n  (`zio-http-middleware-execution-boundaries`).\n- Error rendering: status, generated body presence, stack presence, serialization validity\n  (`zio-http-request-local-error-disclosure`).\n- CORS: ACAO, ACAC, Vary, status, on normal and preflight paths; CSRF: token-cookie outcome with token-creation\n  eligibility held constant (`play-cors-csrf-policy-matrix`).\n- Routing: construction success, selected endpoint, wildcard bindings, remaining segments, 404 vs 405\n  (`cask-route-trie-validation-order`).\n\n**I2. Absent, unknown and empty are distinct states; never collapse them.**\n\n- `None` (cannot establish reusable completion) vs `Some(Array.emptyByteArray)` (boundary known, nothing buffered);\n  `getOrElse(empty)` erases this (`http4s-http1-bodyless-connection-framing`).\n- Play CORS: configuration `null` -> `Origins.All`; case-class default `Origins.None`; literal origin string `\"null\"`;\n  list containing `*`. Four meanings (`play-cors-csrf-policy-matrix`).\n- Play CSRF: absent `Cache-Control` returns `false` from historical shared-cache predicate; that is not proof response\n  is uncacheable (`play-cors-csrf-policy-matrix`).\n- ZIO HTTP: unmatched input vs selected handler's typed failure vs defect\u002Finterruption are distinct fallback\n  categories (`zio-http-middleware-execution-boundaries`); `Invalid` never authorizes reuse\n  (`zio-http-channel-handoff-completion`).\n- http4s: encoded segment text vs decoded segment text vs whole path (`http4s-uri-segment-representation`).\n\n**I3. No lossy conversion before the decision needing the lost information.**\n\n- Cask PR 52: `values.map(_._2).flatten.toMap` dropped duplicate same-method registrations before trie validation;\n  PR 70 keeps sequence, validates per method group, and calls `map(_.toMap)` only after construction\n  (`cask-route-trie-validation-order`).\n- http4s: decoding `\u002Fa%2Fb` to `\u002Fa\u002Fb` before splitting turns one segment into two\n  (`http4s-uri-segment-representation`).\n- ZIO HTTP #1916: `HandlerMiddleware` evaluates `route.run(in)` before applying aspect; transforming request first\n  can turn unmatched input into match (`zio-http-middleware-execution-boundaries`).\n\n**I4. Decide before effecting, and decide at the right scope.**\n\n- Rejection branches before invoking protected handler; status-only rewrite after execution is not rejection\n  (`zio-http-middleware-execution-boundaries`, #542).\n- Path resolution precedes method resolution: no path -> 404, path without effective method -> 405 under Cask's\n  default policy (`cask-route-trie-validation-order`).\n- Ambiguity validation is method-scoped, not path-scoped (`cask-route-trie-validation-order`).\n- Disclosure policy is request-local (FiberRef in #3050); global `Ref`, route-keyed map, or construction-time capture\n  is not equivalent optimization (`zio-http-request-local-error-disclosure`).\n- Play keeps CORS decision helper `private[play]` and deprecated `isCached` bridge forwarding to\n  `isCacheableBySharedCache` (`play-cors-csrf-policy-matrix`).\n\n**I5. Handoff only after previous owner can no longer act; cleanup must run even if consumer never pulls.**\n\n- Reusable HTTP\u002F1 connection starts next exchange at known message boundary and retains legitimate buffered\n  next-message bytes. If alignment is unknown, retire connection; do not guess\n  (`http4s-http1-bodyless-connection-framing`).\n- #4348 moved processing from body-stream finalizer to enclosing response `Resource` release: body finalizer does not\n  run for unconsumed body (`http4s-http1-bodyless-connection-framing`).\n- ZIO HTTP #2924 order: remove reader -> publish completion (`onLastMessage`) -> deliver final body callback.\n  #2610: prior-request damage is cleaned up or invalidated before return; external close is use-time failure that\n  must settle pending waits (`zio-http-channel-handoff-completion`).\n- Transferable rule: completion promise or pool return is permission for another borrower to act. Effect-runtime\n  mechanics of finalizers and interruption belong to `scala-effect-cancellation-finalization`.\n\n**I6. Oracles must be independent of implementation they check.**\n\n- JSON error test interpolating same template as renderer (`zio-http-request-local-error-disclosure`).\n- Play PR 8363: public-cache CSRF test was inverted to make parser patch pass; review restored it\n  (`play-cors-csrf-policy-matrix`).\n- Cask: trie construction tests are not lookup oracles (`cask-route-trie-validation-order`).\n- Ember: #4348's two-response test is parser-level, not network test (`http4s-http1-bodyless-connection-framing`).\n- URI: compare against literals, not another call to changed normalizer (`http4s-uri-segment-representation`).\n- ZIO pool: repeated random traffic is supplemental, not deterministic ordering oracle\n  (`zio-http-channel-handoff-completion`).\n\n**I7. Intentional policy change is not regression, but must be declared.** Routing middleware (CORS OPTIONS,\ntrailing-slash normalization, allow\u002FallowZIO, metrics) legitimately changes route sets. Application may normalize\n`\u002F\u002F` before its own lookup. Deployment may replace permissive CORS config. Ember may deliberately close after HEAD,\ntrading reuse for simpler framing. Domain endpoint may return documented public error body. Require old\u002Fnew rows and\nrationale; do not rubber-stamp, and do not reject.\n\n## Routing table\n\n| Change touches | Library \u002F anchor files or APIs | Load |\n|---|---|---|\n| HEAD \u002F status-implied no-body, `discardBody`, drain\u002Fremainder `Option[Array[Byte]]`, `ClientHelpers` reuse, response `Resource` release | http4s Ember (`ember-core` Parser, `ember-client` `ClientHelpers`) | [references\u002Fhttp4s-http1-bodyless-connection-framing.md](references\u002Fhttp4s-http1-bodyless-connection-framing.md) |\n| `Uri.Path`, `Segment.apply` vs `Segment.encoded`, `normalize`, `pathInfo`\u002F`scriptName`, String-to-Path equality, Path laws | http4s core `Uri.scala`, `PathSuite`, `UriSpec` | [references\u002Fhttp4s-uri-segment-representation.md](references\u002Fhttp4s-uri-segment-representation.md) |\n| `Main.prepareDispatchTrie`, `DispatchTrie.construct`\u002F`validateGroup`\u002F`map`, `DefaultHandler` 404\u002F405 | Cask | [references\u002Fcask-route-trie-validation-order.md](references\u002Fcask-route-trie-validation-order.md) |\n| Netty client pool return\u002Finvalidation, `onComplete`\u002F`onResponse`, close listener, `AsyncBodyReader.onLastMessage`, `ZClient` request-scope finalizer, retry schedule | ZIO HTTP JVM (`zio.http.netty.client`) | [references\u002Fzio-http-channel-handoff-completion.md](references\u002Fzio-http-channel-handoff-completion.md) |\n| Middleware lifting, `HandlerMiddleware`, CSRF\u002Fguard rejection branch, composition\u002Ffallback (`Http.Empty`), before\u002Fafter order | ZIO HTTP (`zhttp` 1.x, `zio.http` 2.x) | [references\u002Fzio-http-middleware-execution-boundaries.md](references\u002Fzio-http-middleware-execution-boundaries.md) |\n| `Response.fromThrowable`\u002F`fromCause`, error body\u002Fstack\u002Fdepth\u002Fformat config, debug middleware, FiberRef policy | ZIO HTTP `Response.scala`, `ResponseSpec` | [references\u002Fzio-http-request-local-error-disclosure.md](references\u002Fzio-http-request-local-error-disclosure.md) |\n| `CORSConfig.allowedForOrigin`, `fromUnprefixedConfiguration`, preflight path, `CSRFActionHelper` \u002F `isCacheableBySharedCache` | Play `play-filters-helpers` | [references\u002Fplay-cors-csrf-policy-matrix.md](references\u002Fplay-cors-csrf-policy-matrix.md) |\n\nChange can match several rows (e.g. ZIO HTTP CSRF middleware that also renders errors): load each. Each case's\nevidence is byte copy of its original audit record under `references\u002Fevidence\u002F`.\n\n## Workflow\n\n1. **Classify intent.** Compatibility-preserving refactor, bug fix, or declared policy change (I7). For policy\n   change, first collect old\u002Fnew matrix rows and approval\u002Fmigration note.\n2. **Pin target.** Record versions and SHA (Prerequisites). Do not transplant historical API (`zhttp.HttpData`,\n   CE2 `Resource` exit cases, `Http` vs `Routes`, Akka vs Pekko) into different line.\n3. **Draw boundary path.** From producer to consumer: parse -> represent -> decide -> effect -> respond ->\n   release\u002Fhand off. Mark every conversion (I3), every decision (I4) and every ownership transfer (I5).\n4. **Build matrix.** Rows: input classes (method, status, framing, origin config, cache directive,\n   matched\u002Funmatched, accepted\u002Frejected, typed failure\u002Fdefect\u002Finterruption, concurrent opposite policies). Columns:\n   observable dimensions from I1. Mark absent\u002Funknown\u002Fempty as separate rows (I2). Fill \"before\" column from source\n   and existing tests.\n5. **Find first lossy or reordered step.** Compare \"after\" column. Defect, if any, is usually first point where\n   later-needed information is discarded, decision moves after effect, or handoff precedes cleanup.\n6. **Choose smallest correction at that boundary.** Restore ordering or representation; do not repair by collapsing\n   states (`getOrElse(empty)`, first-wins `distinct`, catch-all fallback, process-wide flag, arbitrary sleep before\n   scope exit, reading HEAD's Content-Length).\n7. **Write discriminating tests (I6).** At least one row broken version fails and corrected version passes, plus\n   legitimate counterexample row that must still pass (GET\u002FPOST at same path, `Some(empty)` reuse, CORS OPTIONS\n   routing, public domain error body).\n8. **Discover and, only if authorized, run real targets.** See Validation. Report unexecuted obligations.\n\n## Review and Refactoring Checks\n\nTransferable checks (any Scala HTTP library):\n\n- [ ] Every observable dimension of touched branch asserted separately (I1); flag status-only tests.\n- [ ] No three-valued state collapsed into two (I2); look for `getOrElse`, `toMap`, `distinct`, `orElse`, boolean\n      predicates replacing `Option`.\n- [ ] No conversion dropping multiplicity, boundaries, or encoding state precedes validation or decision needing it\n      (I3).\n- [ ] Rejection and selection happen before protected effects; each decision's scope (request, method group,\n      selected handler) unchanged (I4).\n- [ ] Reuse\u002Fhandoff published only after previous owner's cleanup and only at known boundary; every terminal path\n      (setup failure, remote close, interruption, never-pulled body) settles what it owns (I5).\n- [ ] Review deleted or inverted assertions, not only added green tests (I6).\n- [ ] Intentional behavior changes declared with old\u002Fnew rows (I7).\n- [ ] Equality changes keep symmetry and hash agreement; no `a.equals(b) != b.equals(a)` migration shim.\n- [ ] Unrelated renames, abstraction experiments, Vary-header optimizations and effect-model changes kept out of\n      semantic repair.\n\nLibrary\u002Fversion-specific checks (verify against target source first):\n\n- [ ] Ember: `None` keeps `DontReuse`; `Some(bytes)` stores remainder before marking reuse; HEAD discard returns pure\n      `None` without read in #7369; status-implied emptiness preserves `finalBuffer`.\n- [ ] http4s URI: parsed text uses `Segment.encoded`, raw text uses `Segment.apply` (2020 snapshot names).\n- [ ] Cask: sequence retained through `prepareDispatchTrie`; `construct(...)(_.map(_._1)).map(_.toMap)` ordering.\n- [ ] ZIO HTTP pool: remove reader -> `onLastMessage` -> final callback; `Invalid` before intentional close; reset\n      failure -> invalidation; WebSocket channels excluded from historical close listener.\n- [ ] ZIO HTTP middleware: `HandlerMiddleware` applies after `route.run(in)` and preserves `Http.Empty`.\n- [ ] ZIO HTTP errors: defaults disable generated body and stack; format Html; `fromCause` preserves existing\n      `Response` and uses `prettyPrint` when body disclosure is enabled.\n- [ ] Play: explicit-origin match before wildcard; All reflects only with credential support; public-cache GET adds\n      no CSRF cookie; `Locale.ROOT` normalization; deprecated `isCached` bridge retained.\n\n## Consolidated false positives\n\n- `Some(empty)` after fully consumed response is safe to reuse; absence of buffered next bytes is not a defect.\n  Explicit closure after HEAD is not evidence bytes were drained. Reviewer's security concern is not an exploit.\n- `Segment.encoded` on previously parsed data is not injection defect; hash collisions between unequal paths do not\n  break hash law.\n- GET and POST on same Cask path are not duplicates; not every `.toMap` is the bug; deliberately concealed protected\n  resource may intentionally not return 405; two annotations on one function is separate macro boundary.\n- ZIO HTTP: `Invalid` published before intentional non-keepalive close is not reuse-before-close; open WebSocket is\n  not evidence of HTTP request hang; do not demand single callback location without proving every failure reaches\n  it. (Opposite error also common: assuming successful `isOpen` guarantees lifetime, or blaming lazy pool\n  finalization, which adamgfraser explicitly corrected in #2610.)\n- Public error bodies are allowed; #542 body-leak concern does not prohibit them. Author-reported test addition is\n  weaker than retained oracle.\n- Typed public error is not necessarily secret; reviewer's plaintext proposal is not final default (Html).\n  Conversely, request-local storage is not authorization: client header enabling debug is unsafe without access\n  control.\n- ACAC `true` alongside ACAO `*` in Play's server test is not proof of browser credentialed access; conservative\n  `Vary: Origin` on wildcard responses was accepted; deprecated forwarding method is not dead code; approved\n  secure-policy migration may break legacy rows.\n\n## Version fences\n\n| Case | Historical anchor(s) | Fence |\n|---|---|---|\n| Ember framing | #4348 `32893c3` series\u002F0.21: Scala 2.12.13\u002F2.13.4, CE 2.3.1, FS2 2.5.0; #7369 `7e5a974`: Scala 2.12.18\u002F2.13.12\u002F3.3.1, CE 3.5.3, FS2 3.9.4 | CE2 vs CE3 `Resource` exit-case APIs; suite renamed (`ParsingSpec` -> class `ParsingSuite` in `ParserSuite.scala`) |\n| URI segments | `7775249` (2020): Scala 2.12.12\u002F2.13.3, CE 2.3.1, FS2 2.5.0 | Constructor names are observed historical APIs; calendar year does not identify release line |\n| Cask routing | PR 52 `d7f7d55` (2021), PR 70 `e01c972` (2022), validation snapshot `d5fa6d4`: Scala 2.12.16\u002F2.13.8\u002F3.1.3, Mill 0.10.5, Undertow 2.2.18.Final, Java 8 CI | 2020 and late-2024 builds use different Scala\u002FMill layouts (`build.mill`); JVM-only server |\n| ZIO HTTP pool | #2610: ZIO 2.0.19, Netty 4.1.101.Final, project `zioHttp`; #2924: ZIO 2.1.1, Netty 4.1.109.Final, project `zioHttpJVM` | Not ZIO 1 `zhttp.HttpData`; JVM Netty results do not carry to Scala.js\u002FNative |\n| ZIO HTTP middleware | #542: ZIO 1.0.13, package `zhttp`, project `zhttp`; #1916: ZIO 2.0.6, package `zio.http`, project `zioHttp` | `Http` vs modern `Routes`\u002Fhandler aspects |\n| ZIO HTTP errors | #3050 `ab9fdf7`: ZIO 2.1.8, Netty 4.1.112.Final, Scala 2.12.19\u002F2.13.14\u002F3.3.3; `ResponseSpec` JVM-only | #850 (2022) is earlier concern; successor #1024 unverified |\n| Play filters | 2019\u002F2020 Scala 2 + Akka (`Filters-Helpers`); Dec 2022 Akka 2.6.20; Dec 2024 Scala 2.13.15\u002F3.3.4 + Pekko 1.0.3 (`Play-Filters-Helpers`) | Project IDs, integration config (`It` vs `Test`) and backend differ per era |\n\n## Validation\n\nEvery command below is source-derived; rediscover it on target checkout.\n\n1. Read build first (`build.sbt`, `project\u002F*.scala`, `project\u002Fbuild.properties`, `build.sc`\u002F`build.mill`,\n   `.mill-version`, CI JDK settings) and suite's package declaration. Loading sbt or Mill build executes code, and\n   Cask Mill wrapper may download an executable: get separate authorization and isolate checkout.\n2. Discover before running: `sbt projects` then `sbt 'show \u003Cproject> \u002F Test \u002F definedTests'`, or\n   `.\u002Fmill resolve '\u003Cmodule>.test'`. Require nonzero discovered tests. Trait (Play `CORSCommonSpec`) is not runnable\n   suite: find its concrete consumers or run project's whole `test`.\n3. Run narrowest discovered selector. Historical selectors per case live in each reference's Validation section.\n4. Add matrix tests per Workflow. Where oracle is runtime ordering (pool handoff, never-pulled body, concurrent\n   policies), use controlled barriers, overall deadline, and cleanup after failure. Observe connection or channel\n   identity, close\u002Freuse events, handler counts, and promise outcomes.\n5. Isolate global state: Cask example fixtures both bind `localhost:8081` (serialize them); locale-sensitive Play tests\n   restore default locale in `finally`.\n6. Label evidence by layer: source observation, reviewer testimony, parser-\u002Fhelper-level test, executed transport or\n   browser evidence. Server headers are never browser or CDN proof.\n\n## Examples\n\n### Good\n\nCask cleanup keeps method entries as sequence until `DispatchTrie.construct` validates each method group, then maps\npayloads to method maps. Its test pairs rejected duplicate-GET registration (through `prepareDispatchTrie`, asserting\ndiagnostic reason) with GET\u002FPOST reachability at same path, unknown-path 404, and DELETE-on-POST 405. Covers every I1\nrouting dimension; I7 counterexample still passes.\n\n### Broken and Correction\n\nZIO HTTP CSRF refactor invokes application unconditionally, then overwrites status to Forbidden on token mismatch. It\nrenders exception into JSON by string interpolation. Status-only test passes. Correction: branch before invocation\n(I4); assert zero protected-execution counter and absent body sentinel (I1). Render with build's real JSON encoder; in\ntest, parse output with quote\u002Fnewline\u002Fcontrol characters (I6). Keep disclosure policy request-local (I4). Load both\nmiddleware and error-disclosure references.\n\n### Negative\n\nEmber change returns `Some(Array.emptyByteArray)` after fully consumed fixed-length body and marks connection reusable\nwhile next exchange has not started. Do not flag it: boundary is known (I2), and #4348 explicitly distinguishes this\nnon-pipelined case. Likewise, Play deployment replacing null CORS config with explicit trusted list and documenting\nnewly rejected origins is declared migration (I7), not compatibility bug.\n\n## Output Contract\n\nFor each finding return:\n\n- `file:line`, severity, case reference(s) used, and invariant (I1-I7) violated.\n- Exact matrix row(s) before and after: inputs and each observable dimension.\n- Evidence: claim IDs from `references\u002Fevidence\u002F\u003Csource-id>.json` and pinned source\u002FPR URLs.\n- Smallest correction at first lossy\u002Freordered boundary, and one legitimate counterexample that must still pass.\n- Discriminating test and oracle layer it reaches (parser\u002Fhelper, in-process HTTP, socket, browser).\n- Target version tuple, discovered selectors, commands actually executed with results, and explicit unexecuted\n  obligations. Separate source observation, reviewer proposal, merged decision, and current-version inference.\n\nJustified non-finding is valid: name guard, owner, or declared policy making suspicious change safe, and list matrix\nrows still untested. Never turn structural pass into safety certification.\n\n## Limitations\n\n- Invariants synthesize seven historical cases; they are not maintainer-stated universal policy. Reviewer statements\n  are attributed to their PRs. Merges without retrieved discussion (Cask PR 70, ZIO HTTP #2924's praise-only approval)\n  are not design reviews.\n- No upstream compilation, test execution, socket trace, race reproduction, browser probe or performance measurement\n  performed. No current-version vulnerability or defect asserted.\n- Not covered: HTTP\u002F2, request smuggling, complete URI\u002FRFC conformance, CSRF token strength, cookie policy, origin\n  validation design, complete cache-directive grammar, WebSocket lifecycles, and Scala.js\u002FNative transports.\n- Several historical exemplars carry their own observed gaps (http4s 2020 `normalize` default flags, String split\n  trailing-empty handling, Segment equality fallback; Cask shared-children lookup for mixed-method wildcard\u002Fsubpath\n  routes). These limit exemplars; they are not proven current defects.\n\n## Sources\n\nPer-case procedures, PR\u002Fcommit permalinks and test oracles live in references; each links its evidence record:\n\n- [http4s Ember HTTP\u002F1 bodyless framing](references\u002Fhttp4s-http1-bodyless-connection-framing.md) -\n  [evidence](references\u002Fevidence\u002Fscala-http4s-http1-bodyless-connection-framing.json) (`c-framing-connection-contract`, `c-drain-reuse-state`)\n- [http4s URI segment representation](references\u002Fhttp4s-uri-segment-representation.md) -\n  [evidence](references\u002Fevidence\u002Fscala-http4s-uri-segment-representation.json) (`c-uri-representation-laws`)\n- [Cask route-trie validation order](references\u002Fcask-route-trie-validation-order.md) -\n  [evidence](references\u002Fevidence\u002Fscala-cask-route-trie-validation-order.json)\n- [ZIO HTTP channel handoff completion](references\u002Fzio-http-channel-handoff-completion.md) -\n  [evidence](references\u002Fevidence\u002Fscala-zio-http-channel-handoff-completion.json) (`c-pool-handoff`, `c-pool-callback-order`)\n- [ZIO HTTP middleware execution boundaries](references\u002Fzio-http-middleware-execution-boundaries.md) -\n  [evidence](references\u002Fevidence\u002Fscala-zio-http-middleware-execution-boundaries.json) (`c-middleware-semantics`)\n- [ZIO HTTP request-local error disclosure](references\u002Fzio-http-request-local-error-disclosure.md) -\n  [evidence](references\u002Fevidence\u002Fscala-zio-http-request-local-error-disclosure.json) (`c-error-disclosure`)\n- [Play CORS\u002FCSRF policy matrix](references\u002Fplay-cors-csrf-policy-matrix.md) -\n  [evidence](references\u002Fevidence\u002Fscala-play-cors-csrf-policy-matrix.json) (`c-filter-defaults`, `c-filter-boundaries`, `c-filter-test-discovery`)\n",{"name":5,"license":15,"description":7},"main","101d0f67250256ca5d80dc3f95767cad7b541457","skills\u002Fscala\u002Fscala-http-server-semantics","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents","https:\u002F\u002Fgithub.com\u002Fw0rxbend","https:\u002F\u002Freadme.worxbend.com\u002F","Fluent in Backend-ese (microservices, distributed systems, you know the drill)\r\nFunctional Programming Fanatic...","2026-11-14 14:44:12",{"source":8,"skillName":5,"commands":34,"prompt":44,"zipAvailable":45},[35,38,41],{"tool":36,"command":37},"npx","npx skills add w0rxbend\u002Fdot-agents --skill scala-http-server-semantics",{"tool":39,"command":40},"bunx","bunx skills add w0rxbend\u002Fdot-agents --skill scala-http-server-semantics",{"tool":42,"command":43},"pnpm","pnpm dlx skills add w0rxbend\u002Fdot-agents --skill scala-http-server-semantics","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002FSKILL.md",true,[47,51,57,61,65,69,73,77,81,85,89,93,97,101,105],{"path":48,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":16},"LICENSE","许可证",1280,{"path":52,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":55,"sourceHtmlUrl":56},"references\u002Fcask-route-trie-validation-order.md","REFERENCE","参考文档",14351,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fcask-route-trie-validation-order.md",{"path":58,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":59,"sourceHtmlUrl":60},"references\u002Fevidence\u002Fscala-cask-route-trie-validation-order.json",15352,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-cask-route-trie-validation-order.json",{"path":62,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":63,"sourceHtmlUrl":64},"references\u002Fevidence\u002Fscala-http4s-http1-bodyless-connection-framing.json",25214,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-http4s-http1-bodyless-connection-framing.json",{"path":66,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":67,"sourceHtmlUrl":68},"references\u002Fevidence\u002Fscala-http4s-uri-segment-representation.json",10476,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-http4s-uri-segment-representation.json",{"path":70,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":71,"sourceHtmlUrl":72},"references\u002Fevidence\u002Fscala-play-cors-csrf-policy-matrix.json",18726,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-play-cors-csrf-policy-matrix.json",{"path":74,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":75,"sourceHtmlUrl":76},"references\u002Fevidence\u002Fscala-zio-http-channel-handoff-completion.json",16843,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-zio-http-channel-handoff-completion.json",{"path":78,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":79,"sourceHtmlUrl":80},"references\u002Fevidence\u002Fscala-zio-http-middleware-execution-boundaries.json",13610,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-zio-http-middleware-execution-boundaries.json",{"path":82,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":83,"sourceHtmlUrl":84},"references\u002Fevidence\u002Fscala-zio-http-request-local-error-disclosure.json",9330,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fevidence\u002Fscala-zio-http-request-local-error-disclosure.json",{"path":86,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":87,"sourceHtmlUrl":88},"references\u002Fhttp4s-http1-bodyless-connection-framing.md",7810,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fhttp4s-http1-bodyless-connection-framing.md",{"path":90,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fhttp4s-uri-segment-representation.md",7366,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fhttp4s-uri-segment-representation.md",{"path":94,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":95,"sourceHtmlUrl":96},"references\u002Fplay-cors-csrf-policy-matrix.md",15667,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fplay-cors-csrf-policy-matrix.md",{"path":98,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":99,"sourceHtmlUrl":100},"references\u002Fzio-http-channel-handoff-completion.md",7885,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fzio-http-channel-handoff-completion.md",{"path":102,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":103,"sourceHtmlUrl":104},"references\u002Fzio-http-middleware-execution-boundaries.md",7579,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fzio-http-middleware-execution-boundaries.md",{"path":106,"resourceType":53,"resourceTypeDesc":54,"sizeBytes":107,"sourceHtmlUrl":108},"references\u002Fzio-http-request-local-error-disclosure.md",7809,"https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fscala\u002Fscala-http-server-semantics\u002Freferences\u002Fzio-http-request-local-error-disclosure.md",[110,117,124,132,139,146],{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":20},"01M7E6TS1SW1ZSXN748N0RBGHT","wiki-builder","Create and maintain a local Markdown research wiki (sources with provenance, compiled concept\u002Fsource pages, index, maintenance log) driven by a per-wiki config. Use when the user wants to start a wiki or knowledge base, ingest sources into one, or query and update it; use wiki-page-writer for a single code deep-dive page.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fwiki-builder\u002FSKILL.md",[],[],{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":20},"01M7E6S8ARS0VQR85H4FEC390B","refactoring-guru","Diagnose a named code smell and apply the smallest behavior-preserving refactoring, with verification before and after and an explicit stop condition. Use for structural refactors (extract, move, consolidate, change ownership), not for feature or bug work; for readability cleanup of recent changes use code-simplification.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Frefactoring-guru\u002FSKILL.md",[],[],{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":128,"sourceHtmlUrl":129,"categories":130,"keywords":131,"publishedAt":20},"01M7E6RRXCYGSHA0ZBFX3YZP7Y","legacy-seams","When changing untested legacy code, pin the observed results with characterization tests and open the smallest seam that substitutes only the blocking dependency, separate from any later logic change. Use when a clock, random source, I\u002FO, global, or hidden constructor blocks a test or a safe edit. Use test-driven-development for a new behavior or a bug, refactoring-guru for one named structural refactor after the seam exists, and code-refactoring-tech-debt to choose which legacy to replace.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Flegacy-seams\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Flegacy-seams\u002FSKILL.md",[],[],{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":20},"01M7E6QZ11XWSNHCBGYK8HH97C","idea-refine","Refine a raw idea into a one-page brief (problem statement, recommended direction, assumptions to validate, MVP scope, not-doing list) through divergent then convergent thinking. Use when an idea is still vague or you want options and a stress test before committing; use interview-me when the goal itself is unclear and spec-driven-development once the direction is chosen.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fidea-refine\u002FSKILL.md",[],[],{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":145,"publishedAt":20},"01M7E6N2N7BYW7BA5XGM0QD3B4","code-review-and-quality","Review rubric and approval standard for any change before merge, including code written by you, another agent, or a human: five axes (correctness, readability, architecture, security, performance), change sizing, structural remedies, severity labels, and feedback technique. Use to judge whether a change is fit to merge; use code-review to run a PR or diff review end to end.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fcode-review-and-quality\u002FSKILL.md",[],[],{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":150,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":20},"01M7E6MNCZPTRD77Z419X755HQ","code-perfection","Smell and style gate for code you write or change. Bans known code smells (long method, large class, primitive obsession, long parameter list, data clumps, duplicate code, dead code, feature envy, shotgun surgery, flag arguments, message chains) and enforces behavior-preserving structure. On Scala files, enforces worxbend style. Use while implementing, reviewing a diff for smells, or when a smell or style violation is suspected. Routine construction stays with code-complete. SOLID and DRY stay with clean-code-guard. One named structural refactor stays with refactoring-guru.","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fcode-perfection\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fw0rxbend\u002Fdot-agents\u002Fblob\u002Fmain\u002Fskills\u002Fworkflow\u002Fcode-perfection\u002FSKILL.md",[],[]]