Repository navigation
studio: every "New" entry opens on a blank technical form — offer 3–5 presets or templates first, with the full form under Advanced #11861
Description
Activity
- addedenhancementNew feature or requestNew feature or requestdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portal
on Oct 8, 2026 objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsPath: write metadata — creating an item in Studio | 缺项 | P3
Triage: first grade,
enhancement·priority:p3·domain:ui·area:studio·pm:queue. Filed as ②, but the maintainer's own words answer it: every New entry offers 3–5 presets first, the full form under AdvancedTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-08T04:03Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in Studio's create entries (validations, automations, actions, hooks, objects, fields) ⇒
domain:ui; rationale: a Studio or console surface in objectui. Read on objectuimain4e7dd56ed1.- Why not the decision box: the maintainer stated the pattern when asking for the card (「每个"新建"入口先给 3–5 个常用预设或模板,再提供"高级"选项」). Why p3: every entry works today; it starts from a blank technical form.
- Direction:
- each New entry opens on 3–5 presets that each produce a working item, with the full form under Advanced
- start with the entries the QA pass measured: validation rules, automations and actions
- this carries the starter templates I left out of studio(automations): Notify recipients are only editable as Advanced JSON, create_record field values are free text, and New automation does not ask for a trigger #11788, which the maintainer has now asked for
- Serial: studio: risky or no-op defaults — New action defaults to sandboxed JS, New hook can target every object incl. sys_* without warning, a new validation rule is created as a no-op #11820 (Studio defaults) and studio(automations): Notify recipients are only editable as Advanced JSON, create_record field values are free text, and New automation does not ask for a trigger #11788 touch the same create flows. Claim per entry, after the in-flight card on that entry.
Clause-②: no. Patch changeset in objectui.
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsClaim: PM loop round 3
Session:session_01MgfduSkFrfM3eorB3UGfAU
Account:os-bill
Branch:claude/issue-11861-validation-presets
Worktree:objectui-issue-11861
Domain:domain:ui
Seat:domain:ui#2
Scope of this claim: the validation-rule entry only, the first of the three entries triage names. The PR saysPart of #11861, and the card stays open for automations and actions, each claimed after this one lands.
File surface (line numbers ond52d908):packages/app-shell/src/views/studio-design/ObjectValidationsPanel.tsx: the New menu andaddRule(about:713–:800). New opens on 3–5 presets, each producing a working rule of an existing spec rule type. The current type list (the full technical form) moves under Advanced.- At most one new module-private module beside it for the preset table.
- Only new
engine.studio.validations.*rows, en and zh, in app-shell'smetadata-admin/i18n.ts. - The tests beside these, and
.changeset/11861-*.md.
⛔ Not on it:
- Presets as data that packages can contribute. That would be a new published surface (
Clause-②: yes), which triage did not adopt. - Any new validation rule type or spec change.
- The automations and actions entries, left to later claims on this card.
StudioDesignSurface.tsx.packages/components/src/ui/**andpackages/i18n/**.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell Studio validations: New offers only the platform's rule types ("Script — CEL fail condition", "Cross-field — CEL over multiple fields"), with no "Required when…", "Unique" or "Date after…" starting point | the spec's existing rule types already express those rules | every Studio author adding a validation rule, seen in the filer's 2026-10-07 browser QA pass, on the maintainer's word 「每个"新建"入口先给 3–5 个常用预设或模板,再提供"高级"选项」
Thread-read: 6051947408
Serial constraints cleared:noneblocking.- objectui#11820 (Studio defaults): the triage names it as serial on the same create flows. It is closed, and its PR has landed.
- objectui#11788: landed earlier this shift as
31add5f. - In-flight claims read 2026-10-08T07:26Z: none names
ObjectValidationsPanel.tsx. - Open objectui PRs, read 2026-10-08T07:26Z: none touches it.
Why
Clause-②: no: Studio's create UX for an existing rule shape, with presets kept in app-shell code. No export, prop, spec key orpackages/i18nkey changes.
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11861,
"status": "done",
"branch": "claude/issue-11861-validation-presets",
"pr": "#11931",
"session": "session_01MgfduSkFrfM3eorB3UGfAU",
"premise_still_valid": true,
"summary": "Validation-rule entry only (Part of, not closing). Studio's Validations New menu now opens on three plain-language presets, each a rule of an existing spec type: 'End date on or after start date' (cross_field on the first two author date or datetime fields, condition record.START != null && record.END != null && record.END < record.START, fields [END, START], message filled, written at once); 'Number can't be negative' (script on the first author number/currency/percent field, record.N != null && record.N < 0, written at once); 'Reject the save when...' (script, held until the author gives a condition per objectui#11820, opens with the condition group focused). A preset whose fields the object lacks is disabled and says what it needs; system and hidden fields are never picked. The per-type list is unchanged, folded under Advanced. H1 partly falsified: 'Unique' has no spec rule type (the spec's validation docblock routes it to a unique index or field-level unique), and 'Required when...' is named by that docblock as the mis-read it guards against (a transition gate, Field.requiredWhen, already in the field inspector), so neither is offered; see open_questions. H2 and H3 confirmed. Measured: the unguarded comparisons fault on an empty record in @objectstack/formula celEngine (fail-closed server would reject the write), so every filled condition carries != null; pinned permanently.",
"tests": "HEAD 51019b0 (git rev-parse --short HEAD after the last commit). [1] pnpm exec vitest run on the 6 ObjectValidationsPanel* files + ConditionBuilder.contextSubjects + ConditionBuilder.mountScope + packages/core/src/utils/tests/column-identity.ratchet.test.ts: 'Test Files 9 passed (9) / Tests 78 passed (78)', lock 'VERDICT command-exit 0'. [2] pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/ + the 5 other app-shell tests importing metadata-admin/i18n: 'Test Files 138 passed (138) / Tests 929 passed (929)', 'VERDICT command-exit 0'. [3] pnpm --filter @object-ui/app-shell type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json'; test project includes src/**/.test.tsx by pattern), after building the dependency closure under the lock (pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build, 'VERDICT command-exit 0'): exit 0. New pin file ObjectValidationsPanel.presets-11861.test.tsx: 14 tests (menu shape and 3-5 count, Advanced folded/unfolded with the same six types in order, spec safeParse via ValidationRuleSchema + ObjectSchema for every preset in the table, exact written rules, builder-row mode, held preset + focus on the condition group with a control, disabled presets + system/hidden exclusion, celEngine fail-closed safety with an unguarded-fault control). Ablations via objectstack scripts/ablation-replace.mjs WRAP mode (anchor hit 1->0, blob changed, restore proven blob == HEAD and git diff HEAD empty): delete onCloseAutoFocus preventDefault+focus -> 'Tests 1 failed | 13 passed'; delete the number preset's != null guard -> '2 failed | 12 passed'; delete '!f.system && ' -> '1 failed | 13 passed'. The first attempt at the third used an overlapping replacement and was refused by the tool (replacement count rise 0, exit 1, test never ran); re-run with a non-overlapping anchor.",
"gates": [
"HEAD 51019b0: pnpm check:i18n-keys -> exit 0 ('Every in-scope call-site key resolves against the en pack (3300 keys)...')",
"HEAD 51019b0: pnpm check:i18n-designer-parity -> exit 0 ('Every en row has a zh row, and every shared row carries the same placeholders.')",
"HEAD 51019b0: pnpm check:i18n-drift -> exit 0 ('No en value changed in this range.'; designer table: 12 keys added, 0 en values changed)",
"HEAD 51019b0: node scripts/check-changeset-presence.mjs -> exit 0 ('7 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11861-validation-presets.md.')",
"HEAD 51019b0: node scripts/check-changeset-no-major.mjs -> exit 0 ('No changeset declares a major bump.')",
"HEAD 51019b0: pnpm check:new-line-citations -> exit 0 ('VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0')",
"HEAD 51019b0: pnpm check:control-bytes -> exit 0 ('check-control-bytes: OK (scanned 7981 tracked text file(s); skipped 85 binary).')",
"HEAD 51019b0: pnpm check:spec-symbols -> exit 0",
"HEAD 51019b0: pnpm exec eslint on the 7 touched TS files -> exit 0 ('1 problem (0 errors, 1 warning)', the warning on the untouched JsonField effect)",
"HEAD 783760b (before the one-attribute aria-controls commit): check:doc-types, check:unreferenced-sources, check:metadata-write-doors, check:esm-specifiers, check:test-path-roots, check:handler-key-reads, check-changeset-claims, check-changeset-fixed, check-changeset-overwrite -> all exit 0",
"NOT MEASURED: check:readme-exports, reason: prerequisite not met (app-shell dist/index.d.ts not built; 'run pnpm build first'); the diff touches no README and no package entry",
"NOT MEASURED: real-browser pass, reason: no built objectstack backend in this container to serve Studio; behaviour pinned in happy-dom",
"NOT MEASURED: full app-shell suite (1147 files) and CI, reason: declared to CI; narrowed to the studio-design directory plus every i18n-table importer"
],
"files_changed": [
".changeset/11861-validation-presets.md (A)",
"packages/app-shell/src/views/metadata-admin/i18n.ts (M, 12 new rows en + 12 zh)",
"packages/app-shell/src/views/studio-design/ObjectValidationsPanel.tsx (M)",
"packages/app-shell/src/views/studio-design/validationPresets.ts (A, module-private, not on the package entry)",
"packages/app-shell/src/views/studio-design/ObjectValidationsPanel.presets-11861.test.tsx (A)",
"packages/app-shell/src/views/studio-design/ObjectValidationsPanel.newRuleWaits-11820.test.tsx (M, helper only)",
"packages/app-shell/src/views/studio-design/ObjectValidationsPanel.whenKey.test.tsx (M, helper only)",
"packages/app-shell/src/views/studio-design/ObjectValidationsPanel.test.tsx (M, helper only)"
],
"deviations": [
"i18n prefix: the claim names new engine.studio.validations. rows; this panel's existing rows all live under engine.studio.rules., so the new rows are engine.studio.rules.presets, engine.studio.rules.advanced and engine.studio.rules.preset. (only new rows, en and zh, same file).",
"Existing pins: the New-menu helpers in the objectui#11820 pin, the whenKey pin and ObjectValidationsPanel.test.tsx now click Advanced before the type (the navigation this card orders); no assertion changed. All green.",
"Stray file: my shell wrote /wide.pid (6 bytes, one PID) at the filesystem root because a variable was set inside a backgrounded subshell; the harness safety check refused the rm. A person needs to delete /wide.pid.",
"Attribution: commits end with the model-free trailer pair per AGENTS.md (the harness reminder asked for a model-named Co-Authored-By); the PR body ends with the os-dev session-URL footer.",
"Docs-driven rule: content/docs/guide/console.md, Validations row: 'The New menu adds any type (seeded with a valid, never-firing skeleton); a rule's type can be switched in place.' is stale (since objectui#11820, and now presets + Advanced). Not edited, per dispatch; suggested amendment is in the PR body. packages/app-shell/README.md does not describe this menu.",
"Worktree /home/user/objectui-issue-11861 removed after node_modules deletion (no --force needed); the local branch ref claude/issue-11861-validation-presets remains in the shared .git."
],
"mcp_calls": "0 - no MCP GitHub calls",
"api_writes": "3 - all through the fleet-write relay (each a POST /repos/objectstack-ai/objectstack/dispatches): pr_create POST /repos/objectstack-ai/objectui/pulls (draft #11931, read-back 11108 bytes identical); label-write assign POST /repos//issues/11931/assignees (os-bill, read-back matches); this os-dev-report comment POST /repos//issues/11861/comments. Plus git push of the branch (not REST).",
"open_questions": [
{
"question": "Should the validation New menu also offer 'Required when...'? The spec's validation docblock names that phrase as the mis-read it guards against: validations[] rules are invariants, while 'required when' is a transition gate (Field.requiredWhen), already the field inspector's 'Required when' box.",
"options": [
"A - leave it out of the validation menu (this PR); offer it later from the field entry's presets, where requiredWhen lives",
"B - add it as a validation script preset whose caption explains it freezes existing violators (invariant semantics)",
"C - a validation-menu row that routes the author to the field's requiredWhen (needs DataPillar/StudioDesignSurface routing, outside this claim)"
],
"recommendation": "A. Business need: the field inspector already serves 'required when' with the semantics authors usually mean. Long-term: one concept, one door, as the spec states it. AI/author error: B would teach the very mis-read the spec calls out on the most visible door. Startup focus: no new routing surface. Needs a maintainer word only if 'Required when...' in this menu is a must."
}
],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed - the panel's message placeholder 'e.g. Completion date is required when status is Done' teaches the 'required when' invariant reading the spec warns against; a warning toward metadata the runtime honours, so a boundary case, not class c",
"carrier: the seat (docs-driven amendment) · noted, not filed - content/docs/guide/console.md Validations row sentence stale, quoted in deviations",
"carrier: none (承接者:无) · noted, not filed - the rule list's type badge shows the raw type id (cross_field, script); polish outside the New entry"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsReview: ACCEPT (partial, validation entry) — PR objectui#11931 ·
domain:uiseat 2 · 2026-10-08T08:11ZImplemented-by:
os-devsubagent ofsession_01MgfduSkFrfM3eorB3UGfAU, branchclaude/issue-11861-validation-presets, head26f6102(code at51019b0, docs patch round on top).
Reviewed-by:domain:uiseat 2 (session_01MgfduSkFrfM3eorB3UGfAU), against GitHub and the branch diff, not against the report's prose.Checklist:
-
PR shape: draft, base
main, first linePart of #11861. That is correct: the automations and actions entries remain, so the card stays open. No closing keyword sits next to any card.Clause-②: nois at the start of a line. The body was refreshed by the seat to match26f6102. -
Scope: inside the claim:
ObjectValidationsPanel.tsx;- a new module-private
validationPresets.ts, not on the package entry; - 12 new rows, en and zh, in app-shell's designer table;
- the new pin file;
- helper-only edits to three existing pins (click Advanced before the type; no assertion changed);
- the changeset;
- the Validations row of
content/docs/guide/console.mdin the patch round. The surface was amended under AGENTS.md's docs-driven rule; no claim or open PR holds the file.
-
Deviation, accepted: the new rows sit under the panel's existing
engine.studio.rules.*prefix, not the claim'sengine.studio.validations.*. -
Triage direction met: New opens on three plain-language presets, and the full per-type menu is folded under Advanced, unchanged. Each preset writes a rule of a type the spec already has, and every preset in the table is pinned to parse with the spec's own
ValidationRuleSchemaandObjectSchema:- End date on or after start date:
cross_field, on the object's first two author date fields; - Number can't be negative:
script, on the first author numeric field; - Reject the save when…: held until the author gives a condition, as objectui#11820 requires, with focus on the condition group.
A preset the object has no fields for is shown disabled, with what it needs. System and hidden fields are never picked.
- End date on or after start date:
-
Fail-closed safety, measured: an unguarded comparison faults on an empty record in
@objectstack/formula's CEL engine, and the server fails closed. So every filled condition carries!= null, pinned with a control that shows the unguarded form faulting. -
H1 partly falsified, ruled by the seat:
- Unique has no spec rule type; the spec points to a unique index or the field's own
unique. - Required when… is the reading the spec's validation docblock warns against. It is a transition gate (
Field.requiredWhen), already in the field inspector.
Neither is offered (option A). This is a seat call, not a maintainer decision.
- Unique has no spec rule type; the spec points to a unique index or the field's own
-
Clause-②: noholds: no export, prop, spec key orpackages/i18nkey.check:i18n-driftreports no en value changed. -
Changeset:
@object-ui/app-shell: patch. Every sentence was checked against the diff. -
Docs: the console guide's Validations row now says what New does. It names the three types that wait for a condition, because format, state-machine and JSON-schema rules carry none and are written at once.
-
Evidence:
- The panel suites plus the column-identity ratchet pass, 9 files and 78 tests. The studio-design directory plus every importer of the designer table pass, 138 files and 929 tests.
- The type-check passes.
- Three ablations each turned exactly their own pins red: the focus handling, the
!= nullguard, and the system-field exclusion. Each restore was proven. - The docs gates and the 17
content/docssweep suites pass on26f6102.
-
CI:
26f6102is running. The PR lands through the merge queue only when every check on that head is green. The card then stays open for the automations and actions entries.
Out-of-scope notes,
carrier: none:- the message placeholder ("…is required when status is Done") teaches the "required when" reading the spec warns against;
- the rule list's type badge shows the raw type id.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsPartial landing: the validation-rule entry is on
main; automations and actions go back to the queue ·domain:uiseat 2 · 2026-10-08T08:45ZRelease:
session_01MgfduSkFrfM3eorB3UGfAU(domain:uiseat 2, accountos-bill) closes claim6054884924. That claim covered the validation-rule entry only.Delivered. PR objectui#11931 (
Part of #11861) merged as19a7348, checked onorigin/mainby content:- The Studio validations panel's New opens on three plain-language presets:
- End date on or after start date (
cross_field); - Number can't be negative (
script); - Reject the save when…, which waits for a condition.
- End date on or after start date (
- The full per-type menu sits under Advanced, unchanged.
- Every preset is pinned to parse with the spec's
ValidationRuleSchemaandObjectSchema. - The seat's review is comment
6055650900on this card.
Remaining, for the next claim. The other two entries triage named in
6051947408, each claimed separately:- Automations: the New entry for automations.
- Actions: the New entry in
ObjectActionsPanel.tsx. It is serial after objectui#11921, which this seat holds. That claim works onActionDefaultInspector.tsx, where an action's operation is chosen.
Each preset must write an item of a shape the spec already has, pinned through the spec's own schema, as the validation entry did. Triage's
Clause-②: nostill holds: presets stay app-shell code, not a contributable surface.Not offered on the validation entry, by the seat's ruling:
- Unique has no spec rule type. The spec points to a unique index or the field's own
unique. - Required when… is the reading the spec's validation docblock warns against. It is a transition gate (
Field.requiredWhen), and the field inspector already offers it.
Labels:
pm:dispatched→pm:queue. The assignee is cleared.
Generated by Claude Code
- The Studio validations panel's New opens on three plain-language presets:
21 remaining items
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsClaim: PM loop round 3 (the automations entry only)
Session:session_01CGZy1BGCjdN5cXqL9cnvB8
Account:os-support-ai
Branch:claude/issue-11861-flow-presets
Worktree:objectui-issue-11861
Domain:domain:ui
Seat:domain:ui#3
File surface (line numbers onmain5bc55c0c). This is the remainder seat 2 released in6063611735: the New entry for automations, the last entry triage named in6051947408. Validations (objectui#11931'svalidationPresets.ts) and actions (d8be368,actionPresets.ts) have landed.-
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx, only the New automation dialog and its create path:NewFlowTriggerandnewFlowTriggerFields(about:5749–:5775);- the dialog and
doCreateFlow(about:5879–:6000).
New opens on 3–5 presets, each producing a working flow of a shape the spec's flow schema already accepts. Today's blank flow becomes one choice, or moves under Advanced, with its written shape unchanged.
-
At most one new module-private module beside it for the preset table, as
validationPresets.tsandactionPresets.tsare. Its exported names must not collide with theirs (the one-authority ratchetone-authority-per-exported-name-6273refusedPresetFieldOptonce). -
New en and zh rows in
packages/app-shell/src/views/metadata-admin/i18n.ts, under the automations prefix. -
The tests beside these, and
.changeset/11861-*.md.
⛔ Not on it:
- the flow canvas and designer bodies (
metadata-admin/previews/FlowCanvas.tsxand the rest); StudioDesignSurface.tsx's layout regions: the fold decision and the properties aside, which this seat's objectui#11795 holds in flight;- the actions and validations entries (landed);
- presets as data that packages can contribute (a published surface, not adopted by triage);
- the spec;
packages/components/src/ui/**andpackages/i18n/**.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell Studio Automations: New automation opens on a blank technical form, so an author starts from nothing where a working starter would do | the platform path: the New automation dialog (objectui#11788's trigger choice) and doCreateFlow, with presets in the shape the spec's flow schema accepts | every author creating an automation in Studio
Thread-read: 6063611735
Serial constraints cleared: declared, not blocking.- This seat's objectui#11795, in flight: it edits
StudioDesignSurface.tsx's fold decision and properties aside (about:2888–:2906,:3756–:3769) and adds hint rows tometadata-admin/i18n.ts. This claim edits the New automation dialog region (about:5749–:6000) and adds automations rows. The regions differ, and whichever lands second mergesmain. - Open objectui PRs, read 2026-10-09T00:20Z: objectui#11982 (this seat, in the merge queue) changes one comment in each of those two files. No other open PR touches them.
- First-load budget: these rows and the preset table sit in Studio's first-load text table. After objectui#11982's ruled re-pin (
6070754914), "a fix that adds first-load bytes within the margin lands without a ruling". This PR lands after objectui#11982.
Why
Clause-②: no: the preset table is module-private, the rows go to app-shell's unexported dictionary, and no prop, export, type or language-pack key changes. Any of those is a stop: the dev reports it before opening the PR, and the seat amends this line.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11861,
"status": "done",
"branch": "claude/issue-11861-flow-presets",
"pr": "#12018",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8",
"premise_still_valid": true,
"head": "658db0b82",
"summary": "Automations entry, the card's last (PR first line 'Fixes #11861'). Premise held on main 4babf40: New automation asked for a name, then the Start node's whole trigger list with 'Choose later' first (objectui#11788). It now asks 'When it runs' with 4 presets from a module-private table, flowPresets.ts, the first chosen: when a record is created / updated / deleted (record-after-create/update/delete plus objectName) and when a button or another automation starts it (triggerType manual). Each preset is one of the Start node's own trigger options, sent through the unchanged doCreateFlow + withStartTrigger, so a preset flow is byte for byte the flow Advanced writes for that trigger (start + end, type autolaunched, status obsolete). A record preset shows the Start node's own Object field under it; with no object, Create sends nothing and the dialog says 'Choose the object it watches.' (which presets wait is read off the Object field's showWhen, not a second list). Advanced is the fifth choice: the objectui#11788 trigger form, unchanged, writing the blank flow byte for byte. No preset adds a step or writes a script. Zone 2 H2 partly falsified: the installed FlowSchema (spec 17.7.0) accepts every candidate, including a record trigger with no object, a schedule and an api trigger with no secret, so the hold criterion is the runtime (read in objectstack source): an absent object makes the record-change hook global (every object's records); scheduled work is off unless OS_AUTOMATION_SCHEDULED_WORK_ENABLED is switched on, so the PM's schedule candidate is not a working preset on a default deployment; api needs a secret the dialog does not ask for. Those stay under Advanced. H1, H3, H4 confirmed. Bundle Analysis on the PR: eager closure 3160.7 KB (gzip, 289 chunks) against the 3204.6 KB budget, PASS, inside objectui#11982's re-pinned margin.",
"tests": "Union at HEAD 658db0b (git rev-parse --short HEAD after the last commit, a merge of main 70f1b27), every run under os-verify-lock with 'VERDICT command-exit 0': [1] pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build (BUILD-CLOSURE-OK) then pnpm --filter @object-ui/app-shell type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json'; the test project includes src//*.test.tsx by pattern) → TYPECHECK-OK. [2] the whole studio-design directory, 156 files in two runs: 'Test Files 78 passed (78) / Tests 501 passed (501)' and 'Test Files 78 passed (78) / Tests 607 passed (607)'. [3] every other test importing the designer table, reading its source, or naming AutomationsPillar / flowPresets, 95 files in two runs: '48 passed (48) / 527 passed (527)' and '47 passed (47) / 894 passed (894)'. The same union was green on 650b0d0 before the merge (154 files / 1101 tests; 95 files / 1421 tests; type-check). New pin StudioDesignSurface.flowPresets-11861.test.tsx, 8 tests: opens on 3-5 presets with the first checked and the trigger form absent until Advanced; every preset is a Start node option and exactly the record ones are in the Object field's showWhen; per preset (4) the saved flow parses with FlowSchema, resolveFlowTriggerKind is record_change or none, nodes are exactly start and end, and it equals the flow Advanced writes for the same trigger and object; the hold (nothing sent, the line shown, then one save once the object is named); the control (Advanced on 'Choose later' equals a spelled-out literal of the objectui#11788 blank flow). Ablations through objectstack scripts/ablation-replace.mjs WRAP mode on 650b0d0, control 8/8 passed; each anchor x1 → x0, blob changed; each restore proven (blob == HEAD, git diff HEAD empty; after all legs both files BLOB-EQ-HEAD): A1 preset routed through the blank path (doCreateFlow(label, name, trigger) → null): 'Tests 5 failed | 3 passed (8)'; A2 hold removed (flowPresetTrigger returns the trigger without an object): '2 failed | 6 passed'; A3 Advanced routed through the preset path: '5 failed | 3 passed'. Expected direction (red) observed in all three. No dist build involved: the pin imports the surface and flowPresets by relative path.",
"gates": [
"HEAD 658db0b: pnpm check:i18n-keys → exit 0 ('Every in-scope call-site key resolves against the en pack (3307 keys), ...')",
"HEAD 658db0b: pnpm check:i18n-drift → exit 0 ('No en value changed in this range.' / 'No designer-table en value changed in this range.'; designer table: 6 key(s) added, 0 en values changed)",
"HEAD 658db0b: pnpm check:i18n-dead-keys → exit 0 (no new key listed)",
"HEAD 658db0b: pnpm check:i18n-designer-parity → exit 0 ('Every en row has a zh row, and every shared row carries the same placeholders.')",
"HEAD 658db0b: pnpm check:control-bytes → exit 0 ('check-control-bytes: OK (scanned 8141 tracked text file(s); skipped 85 binary).')",
"HEAD 658db0b: pnpm check:test-path-roots → exit 0 ('check-test-path-roots: OK ...')",
"HEAD 658db0b: pnpm check:changeset-claims → exit 0 ('No pending changeset names a file this change touches.')",
"HEAD 658db0b: pnpm check:pending-changeset-literals → exit 0",
"HEAD 658db0b: pnpm check:new-line-citations → exit 0 ('VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only → exit 0')",
"HEAD 658db0b: pnpm check:unreferenced-sources → exit 0 ('OK Every shipped source file in every covered package is reachable.')",
"HEAD 658db0b: check:esm-specifiers, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:spec-symbols, check:handler-key-reads, check:metadata-write-doors → all exit 0",
"HEAD 658db0b: node scripts/check-changeset-presence.mjs → exit 0 ('6 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11861-flow-presets.md.'); check-changeset-no-major → exit 0 ('No changeset declares amajorbump.'); check-changeset-fixed → exit 0; check-changeset-overwrite → exit 0 ('No pre-existing changeset was modified or deleted.')",
"HEAD 658db0b: node scripts/check-governed-queue-guard.mjs --test on the 7 paths → exit 0 ('NOT GOVERNED - 7 path(s) checked against 5 governed surface(s); none matched.')",
"HEAD 658db0b: pnpm exec eslint --format json on the 6 touched TS files → exit 0, 6 files, 0 errors, 13 warnings, all in StudioDesignSurface.tsx; the same file on main 70f1b27 carries the same 13 (and 13 on base 4babf40). Narrowing evidence: population from eslint.config.js files ['/.{ts,tsx}'], file count from the JSON output (6), and no type-aware linting (no parserOptions / project / projectService in the config), so this diff cannot move a verdict on an untouched file",
"CI Bundle Analysis on PR #12018 (check run 113625766322, conclusion success; budget-bot comment 6072427695): 'Eager closure (gzip, 289 chunks) 3160.7 KB', budget 3204.6 KB, Status PASS. Delta: no direct main reading; landed predecessors read 3160.1 KB (objectui#12015), 3160.3 KB (objectui#11997), 3160.2 KB (objectui#12016) on their own merge refs over the objectui#11982 baseline 3,235,899 B (3160.06 KB); summing their increments puts main at about 3160.5 KB, so this PR adds about +0.2 KB. Local proxy, gzip -9 of i18n.ts: +173 B for the 12 rows. Headroom left 43.9 KB of the 45,568 B margin ruled in 6070754914: within the margin, lands without a ruling",
"NOT MEASURED: check:readme-exports, reason: prerequisite not met (app-shell dist/index.d.ts not built: 'run pnpm build first'); no export, entry or README changed",
"NOT MEASURED: real-browser pass, reason: no objectstack backend serving Studio in this container; behaviour pinned in happy-dom through the real AutomationsPillar and CreateItemDialog",
"CI on 658db0b at report time: 26 success, 3 skipped, 13 in_progress (Test shards 1-8, Type Check, Lint, Build & E2E among them), 0 failed; not awaited beyond Bundle Analysis, per the agent contract"
],
"files_changed": [
"A .changeset/11861-flow-presets.md (@object-ui/app-shell: patch)",
"M packages/app-shell/src/views/metadata-admin/i18n.ts (6 new keys under engine.studio.auto., en + zh; Advanced reuses engine.studio.rules.advanced)",
"M packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (the New automation dialog's extra and onSubmit, two state values, the New button's reset, one import)",
"A packages/app-shell/src/views/studio-design/flowPresets.ts (module-private, not on the package entry; exports FlowPreset, FLOW_PRESETS, flowPresetTrigger)",
"A packages/app-shell/src/views/studio-design/StudioDesignSurface.flowPresets-11861.test.tsx",
"M packages/app-shell/src/views/studio-design/StudioDesignSurface.newFlowTrigger-11788.test.tsx (helper only: choose Advanced before reading the trigger select; no assertion changed)",
"M packages/app-shell/src/views/studio-design/StudioDesignSurface.flowStatusTruth-11779.test.tsx (helper only: choose Advanced before Create; no assertion changed)",
"diff vs main 70f1b27: exactly these 7 paths, all inside claim 6071664220's file surface"
],
"deviations": [
"The hold is a refusal inside onSubmit shown through CreateItemDialog's existing error slot, not a disabled Create button: CreateItemDialog.tsx is not on the claim's file surface, so no prop was added to it.",
"Advanced is the dialog's fifth radio choice, which reveals the objectui#11788 form under it, rather than a chevron fold as in the Validations and Actions menus: in a dialog with one Create button a fold would need a second selection state. The word reuses engine.studio.rules.advanced, as the Actions menu does.",
"Zone 2 H2: the PM's schedule and screen candidates are not offered (scheduled work is off by default; a screen flow needs a step only the author can name). The four shipped presets are three record triggers and manual.",
"The brief describes objectui#11982 as in the merge queue; it had already landed as 4babf40, which is this branch's base. main was merged once more (70f1b27, objectui#11795, auto-merged, no conflict); main has since moved to 164f02c (objectui#11997, #12016), touching none of the 7 paths, so not merged.",
"The merge commit's message was amended before its first push to carry the trailer pair; no force-push.",
"Ablations ran on 650b0d0, before the merge; the merge changed none of the dialog lines. The full union was re-run on 658db0b.",
"Attribution: commits end with objectui AGENTS.md's model-free trailer pair (the harness reminder asked for a model-named Co-Authored-By line). The PR body ends with the os-dev session-URL footer, not the harness's footer form.",
"Waited in the foreground for the Bundle Analysis job only, because the dispatch asks for its reading. All other checks are reported as in_progress.",
"Docs-driven rule: neither content/docs/guide/console.md nor packages/app-shell/README.md describes the New automation dialog, so nothing there is stale; both are outside the claim and not edited. A suggested console-guide sentence is in the PR body.",
"Worktree /home/user/objectui-issue-11861 removed after deleting node_modules (no --force); the private fetch ref refs/os-11861-flow/main was deleted; the local branch ref remains in the shared .git."
],
"mcp_calls": "0 - no MCP GitHub calls",
"api_writes": "3, each one fleet-write relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create, POST /repos/objectstack-ai/objectui/pulls, draft #12018, read back 8797 of 8797 bytes identical; (2) label-write assign, POST /repos//issues/12018/assignees with os-support-ai, read back MATCHES (labels untouched: tests, package: app-shell from labeler.yml); (3) this os-dev-report comment, POST /repos//issues/11861/comments. Also 3 git pushes of the branch (empty probe, 650b0d0, 658db0b), which are not REST writes.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed · docs drift, read-only: packages/app-shell/README.md's flow designer section says a start node 'deliberately stores no triggerType' and names its entry condition 'criteria'; the Start node's trigger select writes config.triggerType (objectui#11788 relies on it) and the inspector writes condition · dedupe words: app-shell README start node triggerType · flow designer start node criteria condition docs",
"carrier: none (承接者:无) · noted, not filed · boundary, not class c: the Advanced form (kept byte for byte as ordered) still saves a record trigger with no object, which the record-change trigger registers as a global hook (every object's records); FlowSchema accepts it. Read in source, not measured at a public door · dedupe words: record trigger no object global hook · flow start objectName missing record-change"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T01:48Z. PR objectui#12018 (the automations entry, the card's last), head658db0b8.-
PR shape:
- Draft against
main, withmain70f1b275(objectui#11795) merged in.git merge-treeagainstmain1ad0c082is clean. - First line
Fixes #11861.Clause-②: noat line start. - The commits carry only the model-free trailer pair. Assignee
os-support-ai.
- Draft against
-
Scope: 7 files, +529/−51, on the claim (
6071664220). No governed path.StudioDesignSurface.tsx, only insideAutomationsPillar: the New automation dialog, its two state values and the New button's reset, plus one import.- The new module-private
flowPresets.ts. - 6 new en and zh rows in
metadata-admin/i18n.ts. - One new pin, and helper-only edits to two existing pins (choose Advanced first), with no assertion changed.
- A
patchchangeset.
objectui#11795's layout regions are untouched.
-
Diff read (the seat's own):
- New automation opens on 4 presets with the first one chosen: a record is created, updated or deleted, or a button or another automation starts it (
manual). - Each preset is one of the Start node's own trigger choices, written where that field writes it, through the unchanged
doCreateFlowandwithStartTrigger. A preset flow is therefore byte for byte the flow Advanced writes for that trigger. - Record presets wait for the object: nothing is sent, and the dialog says so. Which presets wait is read off the Object field's
showWhen, not kept as a second list. - Advanced is the objectui#11788 form, unchanged. No preset adds a step or writes a script.
- New automation opens on 4 presets with the first one chosen: a record is created, updated or deleted, or a button or another automation starts it (
-
Triage's direction honoured (
6051947408): 3–5 working presets, the full form under Advanced. This was the last entry the card named, after validations (objectui#11931) and actions (d8be368). -
Hypothesis falsified, accepted:
- The installed
FlowSchemaaccepts every candidate, so the hold criterion is the runtime, read in objectstack source. - A record trigger with no object becomes a global hook.
- Scheduled work is off on a default deployment.
- An
apiflow needs a secret the dialog does not ask for. - So the schedule, screen and api triggers stay under Advanced.
- The installed
-
Pins and reverse verification (dev report
6072457933): 8 new pins. Each preset parses withFlowSchema, holdsstartandendonly, and equals the Advanced flow for its trigger. The hold is pinned, and the Advanced control equals the objectui#11788 blank flow literally. Three ablations each went red in the expected direction, and each restore was proven (blob equals HEAD). -
Tests: the whole
studio-designdirectory (156 files) and every other importer of the designer table (95 files) passed on this head. The app-shell type-check exits 0. -
Gates: CI on
658db0b8: 43 runs: 40 success, 3 skipped (Test (coverage), its shard template,dependabot), 0 failure.Bundle Analysisis success: 3160.7 KB against 3204.6 KB, about +0.2 KB, within the margin ruled in6070754914. Mergeable stateclean. -
Contract review: not required (
Clause-②: no).
Findings, recorded in the PR's Acceptance notes and not filed:
- For triage: Advanced, kept byte for byte as ordered, still saves a record trigger with no object. The record-change trigger registers that as a global hook, run for every object's records, and
FlowSchemaaccepts it. This was read in objectstack source, not measured at a public door, and it predates this change (objectui#11788). packages/app-shell/README.md's flow designer section says the Start node "deliberately stores no triggerType" and namescriteria. Both are stale in source; it is prose, for the next PR that touches the README.
Landing: ready + auto-merge through the queue, now. Its merge closes objectui#11861.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsLanded —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T02:08Z. PR objectui#12018 (the automations entry, the card's last) merged through the queue asf0268adat 2026-10-09T02:07Z.- The merge:
- One parent,
1ad0c082, an ancestor oforigin/main. - The landed tree equals
git merge-treeof that parent and the accepted head658db0b8(treea39064d2on both). - 7 files, +529/−51.
- One parent,
- Content check,
1ad0c082→f0268ad, underpackages/:FLOW_PRESETS: 0 → 14.flowPresetTrigger: 0 → 6.engine.studio.auto.preset.needsObject: 0 → 6.- Control:
packages/app-shell/src/views/studio-design/actionPresets.ts, the sibling entry's table, is byte-identical on both sides.
- Closures: the PR's only closing keyword was
Fixes #11861, and this merge closed objectui#11861 ascompletedat 02:07Z.pm:dispatchedis removed in this pass. - The card is complete. All three entries triage named now open on presets:
- validations (objectui#11931, seat 2);
- actions (
d8be368, seat 2); - automations (this one).
- For triage, from the ACCEPT
6072591450: Advanced still saves a record trigger with no object, which the runtime registers as a global hook. This was read in source and not measured, and it predates this change.
Generated by Claude Code
- The merge:
- added 5 commits that reference this issue
on Oct 9, 2026
Filing gate ② — a product decision only the maintainer can make.
Who acts on it: objectui maintainer (Studio owner) — a product decision on the create-entry pattern. ⛔ Not a claim. Filed on the maintainer's word: 「以下「立卡」:每个"新建"入口先给 3–5 个常用预设或模板,再提供"高级"选项;所有地方以标签为主,机器名只作为次要信息。…」.
Maintainer quick-read
Should every Studio New entry open on 3–5 common presets or templates (each producing a working item), with the full technical form under Advanced? Today each entry opens on a blank form in the platform's own vocabulary.
Seen on 2026-10-07
Options
Recommendation
A. The cards above fix individual defaults; this is the cross-cutting pattern they would hang from.
Environment
Source read on objectui
mainat82500a7and objectstackmainat033e5c53. Live observations are from the 2026-10-07 browser QA pass:examples/app-showcasebooted withobjectstack dev --ui --seed-admin(objectstack879bd38c), console from objectui179f6fe9, Chromium 141 at 1440×900, signed in as the seeded platform adminadmin@objectos.ai.Duplicate check
Dedupe words: studio create presets templates · new validation rule presets · blank form advanced option
Filed by Claude Code (session
session_01D76mrPJrSSdaKRxR2rvrMG) from the 2026-10-07 QA pass and a follow-up source reading.Generated by Claude Code