3 Commits
Author SHA1 Message Date
DongHyeonkaandClaude Opus 5 cc91fc6ae0 fix: settle a shared abort operation by observation, not by drain count
The primitive decided a raced outcome by draining a hard-coded four
microtasks and then asking whether the task had landed. That made the
answer depend on scheduling rather than on what was observed: a caller
abort could fix the terminal owner synchronously and a rejection later in
the same call stack still won the public result, so `race()` disagreed
with `terminal()` and the failure taxonomy a caller received depended on
microtask ordering.

Task settlement and the terminal event now share one settle-once state
machine. Whichever callback actually runs first owns the outcome; a value
that loses is compensated exactly once and a rejection that loses is
absorbed, so neither can surface late.

The three consumers that kept their own copies of these mechanics move
onto it. The Image probe and the Resumable fetch transport attached their
caller listener before installing the timer, so a scheduler that threw
rejected the public `probe()`/`execute()` promise natively and left the
listener on the caller's signal; both now close atomically inside their
own Result vocabulary and start no fetch. `snapshotAbortTimers` binds the
scheduler callables once at construction, so replacing a method after
composition can no longer change how work already in flight is bounded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 01:24:53 +09:00
DongHyeonkaandClaude Opus 5 000a2581af fix: complete presigned capability and upload transport contracts
BT-PRE-02: add the top-level PRESIGNED_TRANSFER_V1 protocol literal to the
capability request and response. A missing, V0 or V2 envelope is closed as
POLICY_REJECTED before the vault registers anything. The server negotiates by
request shape; fields are never dual-emitted into a strict decoder, and the
nested PRESIGNED_MULTIPART_V1 binding protocol is unchanged.

BT-PRE-03: aborting a controller does not settle a fetch that ignores its
signal, so both presigned scopes now race the task, cancel a late response body
and survive a throwing scheduler without leaking the external abort listener.

BT-PRE-04: the vault owns its registration invariants, re-checking method,
href/origin/path agreement, embedded credentials, byte bounds, digest shape and
expiry, so a second issuer cannot register a weaker capability of the same type.

BT-PRE-05: decode each path segment once and require it to round-trip through
the canonical uppercase percent encoder, closing %2f, %5c, %252e%252e, mixed-case
escapes and encoded NUL while still admitting valid opaque UTF-8 segments.

BT-UP-02: inject and snapshot the upload transport clock and scheduler, so
Retry-After delta-seconds and HTTP-date resolve against the same captured now
and a clock rollback clamps to zero instead of producing a negative delay.

BT-IMG-01: make the image resolve() lifetime signal required, replacing the
hidden PRIMARY_REQUIRED preset precondition with a type-level one, and add the
negative typecheck fixture and gate that prove it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 02:19:00 +09:00
donghyeon-ka 6c52cdb916 feat: 기능 추가 과정중 2026-07-30 15:58:20 +09:00