Skip to content

Binder: pre-v1 hardening — lock-free frozen Default reads and a loud terminal-reuse guard #244

Description

@Reefact

Problem

(1) The RequestBinderOptions.Default getter executes lock (Gate) { _frozen = true; return _default; } unconditionally (RequestBinderOptions.cs:29-41), so every request bound through the bare Bind.Request entry acquires a process-global monitor and performs a shared cache-line write — on precisely the hot path issue #151/ADR-0023 optimized to sub-microsecond precision. Once frozen, _default can never change, so the steady state needs neither. (2) Nothing prevents calling New/Create twice on the same binder, or binding more properties after a terminal ran: errors keep accumulating and BuildFailureEnvelope silently rebuilds — inconsistent with the binder's loud bug-channel doctrine (cross-binder reads, mis-declared properties, and invalid selectors all throw).

Impact

(1) is a needless scalability tax on every request; (2) is the one silent-misuse hole in an API otherwise defined by loud programming-error reporting — and it becomes a behavioral change after v1.

Direction

  • Double-checked fast path preserving ADR-0017's semantics exactly: if (Volatile.Read(ref _frozen)) return _default; before the lock; setter unchanged.
  • Add a terminal-ran flag to RequestBinding; a second terminal — and any converter-stage call after a terminal — throws InvalidOperationException naming the contract ("a binder binds one request; create a new binder per request").
  • While in the file: give the default-constructed BindingScope failure its own message (today it misdiagnoses as a cross-binder read).

Acceptance criteria

  • Steady-state Default reads take no lock and perform no write (concurrency tests for the freeze contract still pass).
  • Terminal reuse and post-terminal binding throw with the documented message; tests pin both.

Context

Surfaced by the 2026-07-20 architecture, design & ecosystem audit (doc/handwritten/for-maintainers/audit/2026-07-20-firstclasserrors-architecture-and-design-audit.md, §8.2-Binder/§14-HV11; branch claude/firstclasserrors-audit-83gap7).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions