Skip to content

rest: flush-chain integrity — composition test, convention guards, error-path fakes (#174)#187

Merged
SyniRon merged 7 commits into
developfrom
agent/issue-174
Jun 8, 2026
Merged

rest: flush-chain integrity — composition test, convention guards, error-path fakes (#174)#187
SyniRon merged 7 commits into
developfrom
agent/issue-174

Conversation

@SyniRon

@SyniRon SyniRon commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Closes #174.

What

Closes the flush-chain integrity gap: the composed flush property is now pinned against rest.New's real assembly, the wrapper conventions are mechanically enforced, and the error paths have a reusable fake family.

Validation

🤖 Generated with Claude Code

SyniRon added 7 commits June 7, 2026 21:15
…h lint (#174)

The composition test now consumes chain() — the same function New
composes its middleware with — so mirror-drift is impossible by
construction. The flush convention closes its Unwrap hole: every
ResponseWriter wrapper must declare FlushError() error or
Unwrap() http.ResponseWriter; a dead-end wrapper (neither, no Flush)
now violates, with a meta-case pinning the detection.
…flush-panic pin (#174)

Three pins from the #174 reviews: the rollback's captured&& guard
(refused flush after WriteHeader(503) keeps the capture — symmetric
with cachecontrol's keep-side pin), the commitWriter-presence witness
the composition test's premise stands on, and the #165 x #174
composition (103 non-latching, flush captures implied 200, panic
meters 200).
)

Three confirmed detection evasions closed: a wrapper embedding another
wrapper (fixpoint over embeds, feeding the flush AND informational
guards, with promotion-aware dead-end escapes), a named-field
http.ResponseWriter delegate (the embed-only comment's rationale was
false — corrected), and an aliased net/http import (local name resolved
per file). Meta-cases pin each; floors keep, with failure messages that
name the bump-the-floor path and violations printing before floor
aborts.
The Flush/FlushError switch cases credited an escape for EVERY receiver
type under ANY signature, while violations fire only on wrappers — the
promotion fixpoint then laundered a non-wrapper helper's escape into a
clean bill for a wrapper embedding it. Two demonstrated evasions, both
previously zero-violation:

  - bare Flush() on a plain helper, embedded: the promoted method IS
    matched by http.ResponseController's Flusher branch and silently
    swallows errors — now flagged on the embedding wrapper, naming the
    helper the method promoted from (provenance via the embed graph);
  - malformed FlushError() (int, error) on a plain helper, embedded:
    invisible to the controller's method search, so the wrapper is a
    runtime dead end — now caught by the dead-end rule.

Non-wrapper receivers now earn escape credit only on the exact shapes
the controller matches (FlushError() error — the same discipline Unwrap
always had); wrappers keep any-signature credit because their shape
problems are flagged individually. Meta-cases added for both evasion
shapes plus the legitimate-promotion counterpart (exact FlushError on a
helper stays clean); all prior meta-cases unchanged and green.
@SyniRon SyniRon force-pushed the agent/issue-174 branch from f37ce21 to b55dc7c Compare June 8, 2026 01:15
@SyniRon SyniRon merged commit 8a0afa7 into develop Jun 8, 2026
3 checks passed
@SyniRon SyniRon deleted the agent/issue-174 branch June 8, 2026 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rest: flush-chain integrity — composition test, FlushError convention guard, error-path fakes

1 participant