Preserve forwarded Result values without eager materialization, advance live Builds from disposable indexes, and bound HyperFrames resource, source-frame, and output work.
* fix(generation): refuse supplied media fields a provider cannot carry
* fix(media): probe selected tools in their execution environment
* fix(credentials): use native file replacement across processes
* fix(runtime): distinguish tool preparation from process startup
* fix(cli): bootstrap from the physical distribution directory
Reserve the trailing UTF-16 NUL required by the Win32 rename API while keeping FileNameLength exclusive of the terminator. Verify exact destination names and open-reader behavior, and close test runtimes on failure before removing their SQLite files.
Keep reused media as explicit references, publish Result changes only when needed, and replace Windows files without timed retries. Clarify environment selection and CLI output.
Refine Studio task and media browsing, editable display names, inline media previews, single-row track overlap, semantic ruler pinning, and Companion-owned Ranking selection.
A Windows stress run failed three times in ten, each the same shape: one Build
complete and the other with no Result written at all. A Build with no Result has
not failed, it has stopped being scheduled, and the message said nothing about
why. Dump the execution snapshots and Operations at the deadline: `wakeAt`
absent means waiting on a resource release, which separates a lost wake-up from
ordinary waiting.
The Result manifest carries `failure` beside `outcome`, and the wait read only
the outcome. A Build that reached `failed` therefore reported the state and not
the reason, which is the one thing the Windows runs needed to say.
Under load the test failed `1 !== 2` on "a later Build must join work already in
progress": the first handler held for a fixed 80 ms and the assertion required
the Worker to admit the second Build, plan its graph and reach the same producer
inside that span. Forty runs against a loaded machine reproduced it eight times.
The first handler now holds until the second one actually starts, bounded at
10 s, so the overlap no longer depends on machine speed. A Worker that serialized
the Builds waits out that bound and the assertion reports it. The same forty runs
now pass forty times.
The poll for terminal outcomes also stops on any outcome other than `complete`
and names it. Only `complete` ended that wait, so a Build reaching `failed` was
waited on until the deadline and then reported as a stall, which is how the
Windows failure read.
Closing the SQLite state in `finally` while `runtime.work` was still running
turned the Worker's next `claim` into an unhandled rejection, which node reports
in place of the assertion that failed the test. The abort and the wait for the
loop now happen first, bounded so a loop that will not stop cannot hold up the
cleanup, and the removal retries rather than failing on a handle Windows has not
released yet.
The run this came from is the answer the earlier masking hid: the test failed at
30.5 s, so the deadline fired and the two Builds did not reach a terminal
outcome. That stall is the same one that hung the job for 97 minutes and is
still unexplained.
A Windows run failed two tests whose messages named neither cause.
"one local Worker admits later Builds" reported `EBUSY ... unlink
runtime.sqlite`. That is the cleanup: a throw above skips `runtime.close()`,
SQLite keeps the file open, and the removal in `finally` fails on Windows and
replaces the error that failed the test. Closing the state in `finally` lets
that error through.
"one live detached Runtime Worker" reported `another Runtime Worker launch did
not finish in time`, which is the sibling call giving up on the launch lock
rather than the launch it was waiting for. Carrying the Worker log into the
failure gives the next one something to read.
Re-running the same commit passed, so both remain intermittent. This changes
what they print, not how often they fail.
A Windows job on f80a562 sat for 97 minutes after its last output. The suite had
reached "one local Worker admits later Builds while preserving shared Endpoint
capacity", whose poll for two terminal Build outcomes carried no deadline; one
Build did not complete on that run, so the loop polled every 5 ms until the job
was cancelled. Re-running the same commit passed, so the stall is intermittent
and its cause in the Worker launch path is not yet identified.
Three bounds now apply. The poll fails after 30 s and prints each Build's last
outcome. `node --test` receives `--test-timeout=120000`, well above the 5.75 s
slowest test measured on that run. The job takes `timeout-minutes: 20`.
Group requests by endpoint and rate material, summarize explicit no-charge work, and preserve every priced request in JSON. Providers may supply a concise summary alongside their original rate documents; the CLI does not infer prices or walk upstream media dependencies.
Let HyperFrames render explicit frame intervals with independent browser workers, and make Runtime account for request-dependent resource units across Builds. Preserve external Operations while stopped executions settle so capacity is released only after real work ends.
Studio can only show media that has been normalized, and normalization is a
Need served by the Profile's local FFmpeg Endpoint. A Studio that installs no
Endpoint therefore rejects every file Candidate: satisfying the generated
output leaves inspect-media and normalize-media unresolved, and a file cannot
satisfy the normalized output's type. The deleted path-based preview bypass
answered this question with the wrong mechanism; this is the right one.
The Runtime Host gains localEndpoints(): every Endpoint the Profile selects
whose Provider declares local pricing, immediate capabilities only, with the
Profile's bindings applied. A capability bound to a priced Endpoint stays
unresolved rather than falling to a local one. Studio preflight and execution
resolve Needs through that registry, exactly as plan and a Build do minus every
priced Endpoint, and name the capability when a Need reaches nothing free.
Verified on the media-track preview with three file Candidates and an
estimated semantic take: normalized through media.local and displayed in
306 ms. Duplicate studio.svrun files that were byte-identical to a sibling Run
are removed; a Run's path carries no semantics.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Vertex: requestTimeoutMs now bounds every request (it was accepted and
ignored), the capability-to-model map fails closed, doctor asks Vertex for
each declared model with the configured project so a disabled API or an
unreachable model is reported with Vertex's own message before the first
paid call, and the README finally shows the Profile fragment with both
required CredentialRefs. Two Endpoints that share a pool but size it
differently are reported by doctor instead of failing inside a Build. The
starter Profile names pools by role like the examples do, and the KIE
README's rejected instance key is corrected.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Providers declare everything they can do and never hide a capability:
HypiHub's audio:false flag is gone. When several selected Endpoints offer
the same capability, the Profile's bindings name the one that serves it,
keyed by name@version#capability. plan, creation-time invoke and the Build
resolve through the same EndpointRegistry with the same bindings; doctor
reports a contested capability without a binding (error when a Run demands
it, warning otherwise) and a binding to an Endpoint that does not offer the
capability. Unknown Profile keys are listed together, and the retired
nested-runtime Profile shape gets a migration message.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add the one-shot boundary the creation-time tools were missing: the
Runtime host's `invoke(need, resources)`, implemented by runtime-local as
the same Endpoint activation, capability resolution and credential
resolution a Build uses, with no Build id, Worker, Result or stored state.
Unresolved, ambiguous and asynchronous capabilities are refused with the
exact command that fixes them; the caller owns the ResourceStore.
The reference-video tools now observe and transcribe through it. Gemini
observation seals a real GeminiRequest against the Profile's Gemini
Endpoint instead of picking HypiHub or Vertex from HYPIT_GEMINI_PROVIDER
and reading credential stores itself; the transcript asks the Profile's
whisperx-alignment Endpoint instead of instantiating the local Provider
and probing 127.0.0.1:8765. `--runtime <profile>` names the Profile on
prepare_reference, observe_reference and compare_reconstruction; without
it the project's `hypit runtime use` selection is read, the way `hypit`
reads it. A missing selection, Endpoint or credential leaves the
transcript unavailable with that exact reason and prepares everything
else. The observation retry loop is unchanged but now reports each failed
attempt; its limits wait for real-video measurements.
The Gemini default model comes from @hypit/gemini's declaration rather
than a string, and the Skill's four passages about the environment switch
now describe the Profile binding.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A Provider declares only where it publishes prices: `pricing` on
defineEndpointPackage is either { kind: "page", url } for a paid remote
service or { kind: "local" } for work that runs on this machine. Hypit
never copies or interprets the prices.
The Runtime host gains `providers(capabilities)`, implemented by
runtime-local from the Profile and Endpoint declarations alone; it never
resolves a credential or contacts a service, and reports an unresolved or
ambiguous selection as such. `hypit plan --runtime <profile>` prints a
"Providers and price pages" section so the Agent has exactly one place to
learn which Endpoint serves each external request and where to read its
price; without --runtime it says to pass one.
HypiHub, KIE, Vertex, Xiaomi MiMo and AWS Lambda declare their public
pricing pages; the media, WhisperX, HyperFrames and OpenCV local Providers
declare local. The Provider guide documents the declaration in place of
the removed quote paragraph.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Prices belong to the Provider's own service, not to Hypit code. Drop the
quote path added in dad9808b: EndpointPriceQuote and the quote hook in
endpoint-kit, the host quote method and RuntimeHostNeedQuote, runtime-local
quoteRuntimeConfig, HypiHub's model-card price interpreter and its tests,
and the public Provider guide paragraph that described quote(context).
diagnose stays: capability reachability is a fact, a price is not.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>