fix(render): schema-readiness gate for view/ask streaming lifecycle (NG0950/NG0953)#680
Merged
Conversation
…ion); drop get/getFallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sync schema gate) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…xes NG0950 for view tools Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…NG0953 on ask teardown Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The client-tools coordinator built the view registry from bare component
Types, dropping each tool's Standard Schema — so the render lib's new
schema-readiness gate had no schema to gate on and the real view component
still mounted before its required args streamed in (NG0950 persisted live
despite green unit tests). Map view/ask tools to RenderViewEntry { component,
schema } so the schema reaches the registry. Caught by the live smoke.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fix Records the published-stack audit findings, the schema-readiness-gate design (Approach B), and the 7-task TDD plan. The spec includes the live-smoke correction: the client-tools coordinator must propagate each view/ask tool schema into the render view registry, or the gate never engages in production. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…c (lint) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The view/ask lifecycle fix replaced AngularRegistry's get()/getFallback() with a single getEntry() returning the full NormalizedEntry. Update the define-angular-registry reference + registry guide, and regenerate api-docs.json from source. No backwards compatibility, so the old accessors are gone from the public surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
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.
Summary
Fixes a render-pipeline streaming-lifecycle bug class surfaced by the published-stack audit, where
view/askclient-tool components mounted before their streamed args were complete:input.required()was read before its value arrived (a view component mounted while a streaming tool call's args were still incomplete: mount-before-args). Observed 6× onday_cardin the canonical itinerary demo.OutputRef.emit()fired after the host was destroyed, onaskteardown.The fix is a schema-required-keys readiness gate (Approach B), implemented in the render library — not bolted onto the old architecture. The internal registry contract was refactored so the gate has the data it needs; no backwards compatibility was kept (the project is pre-1.0).
Changes
@threadplane/render(the framework fix):AngularRegistrynow exposes a singlegetEntry(name): NormalizedEntry | undefined(component + resolved fallback + optionalschema/description), replacingget()/getFallback(). The old accessors dropped everything but the component, so the schema never reached the gate.internals/element-readiness.tsisElementReady(entry, resolvedProps): not-ready if any resolved prop isundefined, and (when the entry carries a Standard Schema) not-ready if sync validation reports issues. Async (Promise) validation is intentionally not gated.RenderElementComponent.notReadyroutes throughisElementReady, keeping the per-type fallback skeleton mounted until the real component's required inputs are satisfiable. The mount is monotonic: once the real component mounts it never reverts.internals/guarded-emit.tsmakeGuardedEmit(emit, isDestroyed), applied at the singleOutputRefemit tap inRenderSpecComponent, plus destroyed-guards on the element-scopedRenderHost.*methods. The finallifecycle/destroyedevent still emits before the latch closes.@threadplane/chat(required propagation fix):5.
client-tools-coordinator.ts—viewComponentsnow maps eachview/asktool to aRenderViewEntry { component, schema }. Without this the schema never reached the registry and the gate never engaged in production — caught by the live-LLM smoke, not the unit tests.Docs: registry API reference + guide updated to
getEntry;api-docs.jsonregenerated from source.Verification
nx test render/nx test chatgreen;nx lint render/nx lint chat0 errors.nx build examples-chat-angulargreen (compiles render+chat source).day_cardview path AND a composed flow (backendrequest_approvalinterrupt → Accept → client-toolclear_dayask → Clear → freeze → continuation). Previously NG0950 fired 6× and NG0953 on teardown.Design spec and TDD plan included under
docs/superpowers/.🤖 Generated with Claude Code