- the constants name one bound each
- resolveLocalInstant reuses an instance a caller already holds instead of
copying it per candidate date
- the README entry-point paragraph drops its duplicate sentence
- the note replaces an invalid reason for the zone mapper and a
review-vantage sentence with the facts
- isFourDigitYearInstant is the shared predicate; Schedule's five
representability guards delegate to it instead of re-deriving the range
- the reason for a field outside its calendar range is out_of_range in
both strict parsers, so year 0 no longer reads as a wall-clock problem
- LocalCalendarTime.year states which entries reject year 0 and which
accept it at the UTC edges
- the note counts the five removed expressions and records that the zone
mapper is a silent catch-all; the Chinese side mirrors the English
paragraph order
- the README no longer claims resolveLocalInstant answers a string
- the accepted-input table records the widened plain date-time input
- canonicalClientTimeZone is named as the wire-boundary form rather than
left outside a blanket claim about discriminated results
- the non-canonical scheduledAt diagnostic has one source
- resolveLocalInstant accepts an already-built plain date-time, so the
recurrence walkers drop their private copy of the disambiguation and
round-trip decision
- decodeInstant narrows its field explicitly and drops the assertion
- the model-input exhaustiveness fallbacks throw a plain Error, matching
the timing-change fallback, while durable decoding keeps
ScheduleLogError
- the library module and README state which entries answer a
discriminated result
- the guarded ignore covers only the uncovered branch point
- the note says two consumers copied the profile, counts copies rather
than consumers, and scopes the platform cause to the unsupported
rejection
- the note names the remaining instant-profile copy in session-format
time-context kept a third copy of the IANA profile: its own regular
expression and its own Intl canonicalization in request-zone.ts. It now
reads a request's reported zone through canonicalizeTimeZone and keeps
its stricter policy — an alias whose canonical answer differs from the
reported value is still refused, with the same three diagnostics.
The shared rejection now carries the platform error it caught, so the
unsupported refusal keeps its cause in both time-context and Schedule.
Review found three ways the takeover could let two writers overlap.
- A claimant that read an exited PID could remove the lock of a new
holder that reused that PID before the claim. The claimant now probes
the PID again under the claim, after re-reading the record.
- The browser Worker's process shim reports its own PID as absent, so a
second writer in the Worker took over the first one's live lock. A
record naming the contender's own process is never taken over.
- Takeover proves only that the holder exited, while a pnpm run it
started can still be writing the profile. Each profile operation now
records its pnpm run in .plugin-manager/run.json and removes the record
when the run ends; an operation that finds a record waits for the run
within the existing tree bound and otherwise refuses, naming the
process and the record, without running pnpm.
A failed removal of the exited holder's lock now waits instead of
failing the acquisition, the probe range is stated as int32, and the
tests inject exited PIDs instead of reusing real ones, which Windows
reissues at once.
The tools pipeline's ask decision now carries an optional displayReason
that ToolRuntime forwards to the approval service, so the Auto review
prompt is localized while the audited reason stays English.
Adds the auto-review-approval Web snapshot for a user rejection after a
reviewer denial and for a reviewer failure, and updates the permission
preset pages, READMEs, Agent Notes, and child-agent JSDoc that still
described the shared never bundle.
The takeover note said no Windows binding exists for a kernel-released lock; the Session write lease already holds a named semaphore there through koffi.
skippedProfileBundles recomputed the selected-minus-loaded bundle set from
the manifest, a second home for what loadProfileDirectory already records.
Runtime resolution and generateConfigSchema now read
profile.skippedBundles, so generateConfigSchema no longer reads the profile
manifest and drops its binName parameter.
Optional request extension fields had no size bound. A very large field
could exceed the runtime's string limit while the request was serialized,
which failed every attempt, including retries.
- Bound the extension payload carried by one request (8 MiB by default,
configurable) and send the remainder with later requests.
- If the combined request still cannot be serialized, send the base
request without extension fields and log which fields were omitted.
- Add regression tests and update the related references and decision note.
The seat kept the pending row in local state, so a stale settlement after
connection/reset could clear a newer selection's spinner, a remount lost
it, and /model popup selections never marked a row. ModelDirectory now
publishes the submitted selection as pending under its generation guard.
The trigger spins whenever a selection is pending, so leaving the row's
pane keeps the feedback visible.
The hostname guarded only writers on several hosts sharing one file,
which no supported deployment does, and macOS changes its hostname when
networks change, so locks from before the change could not be taken
over. The nonce closed a race that needs the PID space to wrap between
two reads. Keeping the `<pid>\n` record lets processes of both releases
interoperate.
A process that ends without running withFileLock's finally left
<file>.lock behind, and every later writer timed out until an operator
deleted it. `dsh plugin` interrupted with Ctrl-C, `dsh web` exiting
right after disposal while a cancelled install still restores files,
and any crash all left the profile package lock this way.
The lock now records its holder's PID, hostname, and a nonce. A
contender that finds a record from this host whose PID a signal probe
reports absent claims that record through a wx-created claim file,
re-reads the lock, removes it only while it still holds the record, and
retries at once. A PID-only record from an earlier release counts as
written on this host, so locks left before this change are taken over
too. Empty, incomplete, foreign-host, and live-holder records are still
waited for.
loadProfileDirectory printed each skipped bundle on every call, and startup,
runtime resolution, the config editor, the plugin manager, and HMR all load
the profile, so one incompatible bundle printed the same warning six times at
startup and again on each Web page load. Loading now returns the skips in
Profile.skippedBundles, and the CLI and Desktop launchers print them once per
start with reportSkippedBundles.