Repository navigation
fix(plugin-chatbot): the build panel reads the build-verify part beside the tree, and an unknown phase is not "Building" (objectui#11988) - #11997
Conversation
…de the tree, and an unknown phase is not "Building" (objectui#11988) The receiver took the last data-build-progress part whatever its id and coerced every phase but data/done to structure, so cloud's post-apply verification hop (part id build-verify) replaced the finished tree with "Building your app...". The tree and the verify part are now read apart by part id; phases are read against @objectstack/spec/ai's BUILD_PROGRESS_PHASES, and a value outside it is surfaced as unknown. The panel draws a verification line that advances per hop and closes on done. Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8 Co-authored-by: Claude <noreply@anthropic.com>
…pec's types, not its runtime module (objectui#11988) A value import from @objectstack/spec/ai does not tree-shake: it moved the console's eager closure about 27 KB gzipped over budget. The frame type and the phase table are now typed by the spec's own declarations (a Record over BuildProgressPhase, so a missing or extra phase is a compile error), and the test reads the spec's runtime BUILD_PROGRESS_PHASES to pin every member. Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8 Co-authored-by: Claude <noreply@anthropic.com>
…hed build-progress typings (objectui#11988) Naming BuildProgressPhase in ChatbotEnhanced's exported interface put an @objectstack/spec/ai reference into the published .d.ts that the package's ^17.0.0 floor cannot carry (check:spec-floors: floor-too-low, needs ^17.5.0). The exported phase union is spelled out instead, and a compile-time test holds it equal to the spec's BuildProgressPhase in both directions; the type-only spec import stays internal to mapMessages and is erased from the typings. Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8 Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Inputs: card objectui#11988 (body and comments ① Derived judgmentsAccept-set changes the diff implies, each judged:
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…iver Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8 Co-authored-by: Claude <noreply@anthropic.com>
❌ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. Which half objected:
📦 Bundle Size Report
Size Limits
|
…iver Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8 Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Re-record of What changed since ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #11988
Clause-②: yes
The build-progress receiver in
@object-ui/plugin-chatbotnow reads cloud's post-apply verification loop. This is the receiver that objectstack-ai/cloud#2172's ruling A orders re-filed. Implemented in sessionhttps://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8(seatdomain:ui#3, claim6064346951).What changed
mapMessages.tsextractBuildProgressreads the tree from thedata-build-progressparts whose id is notbuild-verify.extractBuildVerifyreads thebuild-verifypart: its phase,hopandtool.buildProgress.verify. Abuild-verifypart never displaces the tree, in either part order.unknownand is no longer coerced tostructure.ChatbotEnhanced.tsxChatBuildProgress.phasewidens to the spec's four phases plusunknown.ChatBuildProgressgains an optionalverify: { phase, hop?, tool? }.BuildProgressPanel, an unknown tree phase shows a warning header ("Unknown build phase") instead of "Building X…".done. An unknown verify phase shows the warning.chatbot.build.verifying,chatbot.build.verifyStep,chatbot.build.verifiedandchatbot.build.unknownPhase..changeset/11988-build-verify-receiver.md:minoron both packages.The wire shape these pins read
This session cannot read objectstack-ai/cloud#2721: the GitHub API answers 403, and attaching
objectstack-ai/cloudis refused for lack of access. The fixtures therefore follow the card's restatement of the wire shape:data-build-progress;build-verify, besidebuild-progress;{ phase: 'verify', hop, tool };{ phase: 'done' }.Two measurements changed the route the claim names
The claim says the phase values come from the spec's runtime
BUILD_PROGRESS_PHASES/BuildProgressFrameSchema. Two measurements ruled that out.BUILD_PROGRESS_PHASESandBUILD_PROGRESS_FRAME_TYPEfrom@objectstack/spec/aiputs the spec's AI module on the first load, because that module is not tree-shaken. Measured with a local consolevite buildandpnpm check:eager-closureon commit ee4fbd1:vendor-objectstackwas +27,540;BuildProgressPhasein the exportedChatBuildProgressputs an@objectstack/spec/aisymbol into the published.d.ts.pnpm check:spec-floors, which runs on pushes tomainand before publish, then reports "@object-ui/plugin-chatbot [floor-too-low] packages/plugin-chatbot/dist/ChatbotEnhanced.d.ts referencesBuildProgressPhasefrom @objectstack/spec/ai, which @objectstack/spec@17.0.0 does not export". Fixing that needspackage.jsonand the lockfile, which are outside the claim.What landed instead. The vocabulary is read through the spec's TYPES. That costs nothing at runtime and puts no spec symbol in the typings.
mapMessages.tsimports the spec's types withimport type, which is erased from the typings. Its phase table is a Record over the spec'sBuildProgressPhase, so a missing or extra phase is a compile error. Its frame type is typedtypeof BUILD_PROGRESS_FRAME_TYPE.buildVerify-11988.test.tsxasserts at compile time, through the package'stsconfig.test.json, that it equals the spec's union in both directions.BUILD_PROGRESS_PHASESand pins every member.First-load bytes
This change's own cost, from a local console
vite buildandpnpm check:eager-closure, base fff07fb against 22a59ea: +377 B gzip. Of that,plugin-chatbotis +345,i18n-locale-en+41 andindex+9.At head 4549bcf, which merges
main5d77c09, after the eager ceiling was re-pinned to 3,281,467 B by objectui#11982 under ruling 6070754914:main's own push run at 5d77c09 reads "✅ Console eager closure is 3160.0 KB gzipped across 289 of 2474 chunks (budget: 3204.6 KB, headroom: 44.5 KB)."main, within the margin.vendor-objectstack1561.8 / 1585.0 KB,ui-components278.8 / 282.2 KB,framework73.5 / 97.7 KB andi18n-locale-en44.2 / 48.8 KB.This PR does not edit any ceiling and moves nothing lazily.
Published typings (Clause-②)
Read on the built
dist/index.d.ts:ChatMessageandChatbotEnhancedPropsfrom./ChatbotEnhanced.js;ChatMessage.buildProgress?is aChatBuildProgress;phaseisChatBuildPhase='structure' | 'data' | 'verify' | 'done' | 'unknown', where it was'structure' | 'data' | 'done', and it carries the new optionalverify.The entry's type graph widens, so
@object-ui/plugin-chatbottakes aminor, as the claim expected.@object-ui/i18ngains four keys, alsominor. After this change,check:spec-floorshas no finding for@object-ui/plugin-chatbot.Verification (at 22a59ea; re-run at the merge head 4549bcf as noted)
pnpm --filter @object-ui/plugin-chatbot type-checkandpnpm --filter @object-ui/i18n type-check(each istsc --noEmit && tsc -p tsconfig.test.json): exit 0. Re-run at 4549bcf: exit 0.pnpm exec vitest run packages/plugin-chatbot/ packages/i18n/ --maxWorkers=2: "Test Files 140 passed (140)", "Tests 1920 passed | 13 skipped (1933)". Re-run at 4549bcf: the same counts.column-identity.ratchet,check-i18n-call-site-keys,check-i18n-en-drift,check-i18n-dead-keys,one-authority-per-exported-name-6273,check-eager-closure-budgetandObjectView.viewConfigGate. Result: "Test Files 7 passed (7)", "Tests 524 passed (524)".check:i18n-keys,check:i18n-drift("No en value changed in this range."),check:i18n-dead-keys(report only; none of the new keys is listed),check:i18n-designer-parity,check:control-bytes,check:test-path-roots,check:changeset-claims,check:pending-changeset-literalsandscripts/check-changeset-presence.mjs.pnpm exec eslinton the 13 touched source files returned 0 errors. All 10 warnings are inChatbotEnhanced.tsx, on lines this diff does not touch, and the base version has the same 10.--format json, and none is ignored byeslint.config.js.parserOptions.projectandprojectServiceare unset for these files), and no custom rule reads another file. So this diff cannot change the lint result of a file it does not touch.scripts/check-governed-queue-guard.mjs --teston the diff answers NOT GOVERNED.app-shell,console) is left to CI. The only importer, app-shell'sAiChatPage, buildsbuildProgressfrombuildProgressFromDraftReviewand spreads it, so a wider union cannot break that site.check:spec-floorscannot judge the 15 packages that are not built in this worktree (no-artifactfindings).Reverse verification (at 22a59ea, through
ablation-replace)Every leg restored with the blob equal to HEAD and
git diff HEADempty.done".structure: 2 failed, 12 passed. Red: "a phase outside the vocabulary isunknownon either part…" and "an unknown tree phase is surfaced as a warning, not rendered as Building".verifyrow deleted from the phase table: 5 failed, including "reads every phase of the spec vocabulary as itself…".tsc --noEmitalso fails: "TS2741: Property 'verify' is missing … required in type Record over structure, data, verify, done". (An earlier try at this leg passed an empty--replacement, which the tool refused before running anything. It was redone with--delete.)tscstays green and the test project fails twice with "TS2344: Type 'false' does not satisfy the constraint 'true'". This is the compile-time pin working in the direction the source cannot see.Acceptance notes
build-verifypart on a message with no build tree draws no verify line. This covers anapply_editturn, if cloud verifies those. The old reader drew "Building your app…" there, and that is gone. Carrying the line without a tree needs a sibling message key, which means wideningchatMessageAdapter.ts's runtime-only key list, outside this claim. Carrier: none.phasenow readsunknown(a warning), where it used to readstructure. The spec declaresphaserequired on every frame.hopis rendered as sent ("step N"). The spec leaves the base, 0 or 1, to the emitter, so a 0-based loop would read "step 0" first. That is for the cloud seat to know.doneframe. The tree behaves the same way today.BUILD_PROGRESS_PHASESgoes stale once this lands. It still describes this reader as coercing tostructure, and cites it by line address. Carrier: none.Generated by Claude Code