feat(provider-tangle): observation and interactive-terminal wiring (#136 phase 2) - #171
Merged
Merged
Conversation
…andbox and bridge transports (#136) The Tangle provider implements the normalized environment observation over the Sandbox SDK: provider identity, lifecycle with its scheduled retirement, the credential-free runtime endpoint, verified placement, requested and effective compute shape, current and peak memory use, per-execution token usage and cost, GPU-lease compute billing, and the account plan, credits, quota, and period. Each surface carries its freshness state, so a value the SDK does not report is visibly absent instead of arriving as a measured zero. Sandbox states no effective CPU or disk, no CPU utilization, and no per-sandbox container compute cost, so those surfaces report unavailable with the reason. A negative overage credit balance and an account with no concurrent-sandbox ceiling report unavailable for the same reason. The Tangle provider also binds the interactive terminal over the sandbox PTY socket: attach and reattach, ordered output with an exclusive replay cursor, input, resize, detach, and close, each bound to its parent execution and to a fail-closed expiry one detach window past the newest proven activity. Close reports closed only when the socket delivered an exit. Both capability blocks are claimed only where a concrete source backs them. The create call now sends the compute shape Sandbox reads (cpuCores, memoryMB, diskGB, accelerator). The contract states cpu, memoryMb, and diskMb, and passing those names through unchanged reached the service as unknown fields, so a requested size was never applied. The cli-bridge provider reports the same observation for the surfaces it backs: identity, lifecycle, the bridge endpoint, placement, and the token usage of the newest execution, summed across that run's events. It provisions no compute and holds no account, so those surfaces are never claimed.
…nd a terminal to its socket A Sandbox transport failure states the request URL in its message, and that URL can carry userinfo or a token, so no observation or terminal attach result repeats it. Each degraded surface names the read that failed and a structured cause: an HTTP status, an error code, an abort, or an error name. Every observation surface is held to the schema the contract states for it, and an SDK accessor that throws is read through the same guard, so one refused value degrades that surface alone instead of destroying the observation beside it. The observation subject names only the provider and the environment id, which both a create handle and a handle rebuilt by id can produce, so a live observation binds to its replay for the same sandbox. A terminal reference describes what its own socket can do: a detached, closed, or dropped socket makes the reference unusable, and a reattach closes the socket it replaces. The terminal states the replay cursors it can serve, and the oldest one delivers every retained frame, so eviction cannot lock a consumer out. cli-bridge carries its configured execution kind as the requested placement and states the verified placement and a live lifecycle as unavailable, because it never probes the bridge.
…wledgement read, and release the terminal registry `events()` with no cursor starts at the oldest retained frame, resolved when the read begins. Cursor 0 is the one value the bounded log refuses after it evicts an output frame, so a consumer that held no cursor was locked out. A cursor the consumer names is still refused when its successors were evicted. `attachTerminal()` reads the ready acknowledgement inside a guard and closes the socket it opened. The Sandbox stream exposes `ready` as an accessor that throws before the runtime acknowledges, so an unguarded read replaced the attach result with a raw transport error that also states the request URL. A terminal handle releases its registry entry on detach and on close, matched by the socket the handle was built on, so a stale handle cannot evict the terminal a later attach installed.
tangletools
approved these changes
Aug 14, 2026
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — bf0d7e86
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
This approval is provisional. It rests on the audit running. If the audit cannot run — for example the CLI bridge rejects it — this approval is dismissed rather than left standing, so an unrun check never reads as a passing one.
tangletools · auto-approval · reason: drewstone_author · 2026-08-14T06:31:58Z
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Phase 2 of #136: the provider side of the observation + interactive-terminal contract that shipped in #158.
unavailable/unknown) rather than a zero, so a missing number is always visibly missing.Security fix included
describeFailure()copied the raw transport error into the observation payload on five paths. The Sandbox SDK throws<url> failed (<status>): <message>, so a URL carrying userinfo or a token landed in an observation for which the contract's ownobservationContainsCredential()returned true. Reasons are now bounded and credential-free, asserted on all five paths.Verification
Two adversarial review rounds. The final review found no functional defect and independently mutation-proved all eight closures, including:
plan: 'pro ') can no longer destroy an entire observation;Suites green across provider-tangle and cli-bridge;
pnpm -r check-types,check:package-artifacts,check:control-artifactsall pass.Known test gap (not a defect)
close()'s registry release is correct but unpinned — deleting therelease()call survives the suite. Worth a follow-up pin; it does not change behavior.Refs #136