fix(app-shell): Studio's flow start node stops offering 「Platform event」, a trigger no engine routes (objectui#11067) - #11090
Conversation
…latform event `triggerType: 'event'` is a token `resolveFlowTriggerKind` answers no kind for and no engine trigger binds, so a flow authored with it never fired. The option leaves the select, the two start-node `showWhen` lists stop naming it, and the zh overlay drops the option's label. A stored `event` is not rewritten: the select shows it as its flagged unknown value. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
… event The table half asks the spec resolver that `event` is unrouted, and pins that no option writes it, no start field is gated on it, and the zh overlay labels only offered options. The inspector half pins that a stored `event` shows as the select's flagged unknown value and is saved back as stored. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
… pin `MetadataInspectorProps` requires it; the test project's type-check refused the mount without it. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ 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 #11067 (body and its 3 comments: triage ① Derived judgmentsBinding direction, triage
② Semver level
Clause-②: no — matches the claim ③ Boundary flagsDev flags:
Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #11067
Clause-②: no
Studio's flow start-node inspector offered a 「Platform event」 trigger that wrote
triggerType: 'event'. The spec'sresolveFlowTriggerKindanswers no trigger kind for that token, and no engine trigger binds it, so a flow authored with it never fired and nothing said so. Implemented along triage's direction (comment 5887202725): remove the option, don't invent the route.What changed
startinspector's Trigger select no longer offers 「Platform event」. A comment beside the objectui#11054apinote says why.event. The Object and Entry condition fields no longer appear for that token alone. A value already stored on such a node stays on screen under the existing stored-value re-show rule, flagged as retained.eventis not rewritten. Nothing new was built for it. The select already shows a stored value it does not offer as a flagged, selectable row:InspectorSelectFieldowns that rule (objectui#8488), and the flow select branch words the flag throughflagUnknownValuewith the catalogue keyengine.form.deprecated. A save keeps the value as stored.FLOW_FIELD_ZH, the start node'striggerTypeoptions). See the next section.Beyond the claim's file surface: one line in
metadata-admin/i18n.tsThe claim names
flow-node-config.ts. The option's zh label lives in the zh overlay inmetadata-admin/i18n.ts, andlocalizeFieldreads an overlay label only through an offered option. Once the option leaves, its label is read by nothing. The one-line removal is the zh half of the same option declaration. It follows the precedent of PR objectui#11064, which swapped the overlay'swebhookkey forapiin the same change. It meets the four conditions for an in-place fix:i18n.ts.A pin states the rule rather than the one token: every zh overlay key for the trigger select names an offered option. Ablation A3 below shows that pin going red when the label is put back.
Measured before building
@objectstack/spec17.4.0.triggerType: 'event'givesundefined. So doeseventwith anobjectName. The controlapigivesapi. objectstackorigin/mainb80ab579has the sameresolveFlowTriggerKind, andFLOW_TRIGGER_KINDSthere isrecord_change,time_relative,scheduleandapi.873284657, this branch's base.triggerType: 'event': zero. The pattern allows an optional quote around the key, then a colon, then the token quoted or bare.873284657, all tracked files:event0. Lit controls on the same shape:api21 hits in 4 files,record-13 hits in 8 files.b80ab579,examples/:event0. Controls:api1 hit (the showcase inbound flow),record-22 hits in 5 files.b80ab579, whole tree:event1 hit. It is not the token:triggerType: eventis a JS variable intrigger-record-change'sbulk-write-per-row-context.test.ts.startnode configSchema that could put the option back. objectstackservice-automation's builtin node forms carry nostartnode, and the inspector's field table forstartis this repo's own.Pins
flow-node-config.platformEvent-11067.test.ts(table half):event, with anapicontrol;event, and no start field is gated on it;eventno longer shows the Object and Entry condition fields on the token alone, and a storedobjectNamebeside it stays visible, flaggedcontroller-off, with a live record-trigger control.FlowNodeInspector.platformEvent-11067.test.tsx(what the author sees):Webhook / APIcontrol;eventdraws the value under the flag. The expected text is built with the sameflagUnknownValueand catalogue key, so the wording is not pinned here.unknownValueFlag.i18n-9652.test.tsxowns the wording.{ triggerType: 'event' }and{ triggerType: 'event', objectName: 'task' }back unchanged.Ablations
Run at
c5ebc3d93(the fix and pins committed). Each leg went through objectstack'sscripts/ablation-replace.mjs. That tool checks that the anchor hit exactly once, that the blob changed, and that the restore proof holds: blob equal to HEAD andgit diff HEADempty. Each red/green split was predicted before the run.Tests 5 failed | 8 passed (13)'event'put back on the Object gateTests 4 failed | 9 passed (13)Tests 1 failed | 12 passed (13)The A3 mutant's blob is
98a9c7936. That is the base file's own blob, so the leg restored the old line byte for byte. The two round-trip cases stay green in every leg, which was predicted: no leg moves the save path. They guard a future rewrite of a stored value, and none of the three mutations exercises that.Gates
The final head is
4de4b51ea. It differs fromc5ebc3d93by one test-only line:readOnly={false}on the new inspector pin's mount.turbo run build --filter='@object-ui/app-shell^...' --concurrency=2:Tasks: 28 successful, 28 total, run atc5ebc3d93. The dependency closure has no diff.4de4b51ea.pnpm --filter @object-ui/app-shell type-checkexits 0. It runstsc --noEmit, thentsc -p tsconfig.test.json, whoseincludeissrc/**/*.test.tsandsrc/**/*.test.tsx. Atc5ebc3d93the test project refused the new inspector pin's mount for a missing requiredreadOnlyprop. That red is how we know the test project reads the new file.4de4b51eais that repair.c5ebc3d93.vitest run packages/app-shell/src/views/metadata-admin/inspectors/:Test Files 111 passed (111)andTests 1554 passed | 1 skipped (1555).4de4b51ea. The two new pin files plus the two objectui#11054 pin files:Test Files 4 passed (4)andTests 42 passed (42).4de4b51ea, each exit 0:node scripts/check-changeset-presence.mjs;node scripts/check-control-bytes.mjs;check:new-line-citations, which reports 0 new;check:vi-mock-specifiers,check:vi-mock-inheritandcheck:vi-mock-override-shape;check:test-path-roots;check:i18n-designer-parityandcheck:i18n-drift;check:designer-field-key-parity. It is run anyway, although no field key moved.A declared narrowing: the full
vitestfarm and the repo-widepnpm lintbelong to CI..ts/.tsxfiles. That count comes from--format json: 4 results, 0 errors, 0 warnings.eslint.config.jssets noprojectServiceand noparserOptions.project, so type-aware linting is off. This diff therefore cannot move a lint verdict on a file it does not touch.Acceptance notes
FLOW_META_ZH.type(the canvas header pill for the flow-leveltype) still carriesevent: '平台事件', and alsowebhook,manualandtime_relative. It is a display fallback for a stored flow-level value, not an option anyone picks, and is outside this card. The installed spec's flowtypeenum isautolaunched,record_change,schedule,screenandapi. Carrier: none.validate-flow-trigger-readinessreports an off-grammartriggerTypeonly on atype: 'record_change'flow. Whetheros validatesays anything abouttriggerType: 'event'on anautolaunchedflow was not run. After this PR, the census finds no producer of the token. Carrier: none.Generated by Claude Code