You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ui: flow designer leaves a typed schedule block with no cadence when the cron is cleared, which the flow parse now refuses #31383
scheduleWithExpression (ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts, near line 1710) rewrites the whole start-node config.schedule block on each cron edit. When the author clears the cron on a typed block, it leaves { type: 'cron' } or { type: 'cron', timezone: 'UTC' }. Only an untyped { expression } collapses to undefined. The field's own help text says "A time-relative sweep defaults to daily if left empty".
On main today: the draft stores, and the schedule flow silently never binds. A sweep falls back to daily 08:00 UTC.
When a typed block no longer carries its cadence (expression, intervalMs or at), the designer drops config.schedule entirely, as it already does for the untyped form. It never writes a typed block with no cadence.
Evidence
Contract review 6717630512 on PR #31376, ③ ("the Studio designer produces a refused draft"). Seat ruling 6717636410 on #31224, item 4.
Ruling-ref: the maintainer's 「定级你可以自己决定」 (2026-11-01T12:11Z): a seat grades a card itself under the existing triage rules and posts the record on the card.
Reproduced by reading origin/main.scheduleWithExpression is in ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts, line 1710. Clearing the cron on { type: 'cron', expression } takes the expression === '' arm, deletes only expression (and cron), and returns { type: 'cron' }. The object is not empty, so it is not collapsed. With a timezone present, the result is { type: 'cron', timezone }.
Grade p2. Today the draft stores a cadence-less typed block, and the flow never binds; the sweep's documented "daily if left empty" does not hold. Once PR fix(spec)!: refuse a start-node filter beside timeRelative and a schedule the readers cannot use #31376 (open) lands, the same edit is refused 422 at save. The designer produces a shape the published ScheduleSchema refuses, so it blocks an author's save. That is a p2 authoring defect, not p0/p1: nothing is red on main, and no data is lost.
Lane:domain:ui, as filed; the fix is one function plus its pin flow-node-config.scheduleCadence-12779.test.ts.
Direction: the card's Expected as written. A typed block left with no cadence (expression, intervalMs, at) is dropped whole, as the untyped form already is. No spec change.
Labels: pm:triage → pm:queue, priority:p2 added. The seat dispatches it in this round.
Claim: PM loop round 4 · 2026-11-08T05:38Z
Session: session_01FEkQ5oAnL2z711MLVm7ZnB (card thread, dev) · seat session_01FEkQ5nLA7wiVY5YWjT9Svr
Account: os-project-manager
Branch: claude/project-thread-xmmugm
Worktree: objectstack-issue-31383
Domain: domain:ui
Seat: domain:ui#1
File surface: scheduleWithExpression and any sibling schedule write path in ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts, its pin flow-node-config.scheduleCadence-12779.test.ts (or a sibling test in that folder, a rendered inspector case allowed), root .changeset/. ⛔ No packages/spec edit, ⛔ no change to PR #31376's branch, ⛔ no server code.
Container & model: M, mode:thread, model: default tier, effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the flow designer writes a typed schedule block with no cadence when the cron is cleared | none (found by contract review 6717630512 on PR #31376) | every flow author clearing a start node's cron
Thread-read: 6717793605
Premise: holds by code reading on origin/main (grade record 6717793605): clearing the cron on { type: 'cron', expression } returns { type: 'cron' }
Serial constraints cleared: no other domain:ui card is pm:dispatched on flow-node-config.ts; PR #31376 touches packages/spec only on this path
Scope: the card's Expected as written, one PR, Fixes #31383. The declaration lines start at no / none; the dev measures them on the diff, and the seat amends this claim if they differ. Order: /mnt/project-files/pm-orders/ui/order-31383.md. Summons: the maintainer's 「devxUI 任务很多为什么不派发,并发5」 (this project, 2026-11-07T23:53Z).
os-dev-report
{
"issue": 31383,
"status": "done",
"branch": "claude/project-thread-xmmugm",
"pr": "#31412",
"head": "3251f97c",
"session": "session_01FEkQ5oAnL2z711MLVm7ZnB",
"premise_still_valid": true,
"summary": "scheduleWithExpression's clearing arm now returns undefined whenever the object left after deleting expression and cron resolves to no cadence through normalizeScheduleCadence (the designer's mirror of the engine's normalizeSchedule). A cleared { type: 'cron', expression } or { type: 'cron', expression, timezone } stores no config.schedule; the set arm is unchanged (a typed block keeps type and timezone). Bounded in-place fix named in the PR: a cleared untyped { expression, timezone } used to leave { timezone }, which binds nothing and which PR #31376's flowStartScheduleReadsNothing refuses; it is dropped too. No other designer path writes config.schedule (FlowNodeInspector.tsx line 552 routes the Cron schedule commit through this function; the other schedule helpers only read). Card assignee untouched; pr_create sent no assignees.",
"tests": "flow-node-config.scheduleCadence-12779.test.ts: the old assertion pinning { type: 'cron', timezone: 'UTC' } removed; new describe objectstack#31383, 11 cases (7 typed cleared forms -> undefined, untyped { expression, timezone } -> undefined, CONTROLS: untyped { expression } -> undefined, a cron typed over a typed block keeps type/timezone, clearing { expression, intervalMs } keeps the interval). FlowNodeInspector.scheduleCadence-12779.test.tsx (rendered, fireEvent.change on the real Cron schedule input): clearing a typed cron and a typed cron with timezone leaves config with no schedule key, objectName kept, box empty; CONTROL untyped { expression }. Plus module-top import '@objectstack/lint' (check:test-source-alias). Run on 3251f97: Test Files 2 passed (2), Tests 68 passed (68). Wider: inspectors/FlowNodeInspector* + inspectors/flow-node-config* = 39 files passed, 667 passed, 1 skipped. Ablation via scripts/ablation-replace.mjs: clearing return restored to Object.keys(next).length === 0 ? undefined : next (anchor 1 -> 0, blob aa3d830d -> 91bc6d94): 10 failed / 58 passed (68): the 8 new non-control table cases and 2 rendered typed cases red, every CONTROL green. Restored: blob == HEAD aa3d830d, git diff HEAD empty. Tests import flow-node-config.ts from source by relative path, so no build leg.",
"gates": "Local on head 3251f97: dispatch-gates --commands derived 36 families; all 36 exit 0 (incl. ui vitest scripts/ and check:type-check-debt). --ran with exit codes: 36 derived, 36 run, 0 NOT-MEASURED (derived zero), 0 UNRUN; record pm-orders/ui/31383-gates-ran.txt in project files. Round 1 on 93b35e7: check:test-source-alias exit 1 (edited rendered test reaches import('@objectstack/lint') lazily); fixed in 3251f97 and the whole list re-run. Also: eslint on 3 changed files exit 0; ui check:new-line-citations 0 new, exit 0. Build: spec/formula/client/lint/sdui-parser closures VERDICT command-exit 0. app-shell type-check NOT MEASURED locally (needs all @object-ui dists), declared to CI. CI check-runs: in_progress at report time; the seat holds them.",
"line_budget": "106 changed lines (+98 / -8, 4 files), under 3000",
"files_changed": [
".changeset/31383-flow-designer-cleared-cron-drops-typed-schedule.md",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.scheduleCadence-12779.test.ts",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.scheduleCadence-12779.test.tsx"
],
"declarations": "Clause-②: no; Metadata-protocol: none; measured on the diff: no published key, export, schema arm or i18n string added or removed. Changeset @object-ui/app-shell patch, both lines in PR body and changeset.",
"deviations": "1) Scope: untyped { expression, timezone } -> { timezone } fixed in place under os-dev rule 3's bounded exemption (same defect, same function, inside the claim's file surface, no new gate family); the seat can ask for the narrower typed-only predicate. 2) Two git pushes (93b35e7, then 3251f97 after the round-1 gate red) instead of one. 3) The ablation run itself was not wrapped in os-verify-lock (2 test files, ~16s); every other build/test ran under the lock. 4) PR opened with no labels key (order names none; no skip-changeset applies). os-dev.md rule 2 still says pr_create carries assignees; followed the order (none).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "4 — reads only: mcp__github__issue_read x3 (#31383 get, #31383 get_comments x2), mcp__github__pull_request_read x1 (#31376 get); no write tool",
"api_writes": "4 — git push x2 (branch claude/project-thread-xmmugm); relay pr_create (fw-20261108T063025Z-5f7245, PR #31412, read-back identical, assignees none); this os-dev-report comment on #31383 via post-stamped",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed: PR #31376 is unmerged, so the cleared case was not run through FlowSchema; the comment-review shapes are a typed cron with no expression, which the published ScheduleSchema already refuses on main."
]
}
ACCEPT → PR #31412 comment 6718382774 · 2026-11-08T06:46Z · head 3251f97c (clearing the cron drops a schedule block left with no cadence; 106 lines, not governed, Fixes #31383). Landing through the merge queue.
Activity
objectstack-fleet commentedon Nov 8, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
席位核对 · Grade · 2026-11-08T05:35Z · p2 ·
domain:ui·pm:queueRuling-ref: the maintainer's 「定级你可以自己决定」 (2026-11-01T12:11Z): a seat grades a card itself under the existing triage rules and posts the record on the card.
origin/main.scheduleWithExpressionis inui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts, line 1710. Clearing the cron on{ type: 'cron', expression }takes theexpression === ''arm, deletes onlyexpression(andcron), and returns{ type: 'cron' }. The object is not empty, so it is not collapsed. With atimezonepresent, the result is{ type: 'cron', timezone }.ScheduleSchemarefuses, so it blocks an author's save. That is a p2 authoring defect, not p0/p1: nothing is red onmain, and no data is lost.domain:ui, as filed; the fix is one function plus its pinflow-node-config.scheduleCadence-12779.test.ts.expression,intervalMs,at) is dropped whole, as the untyped form already is. No spec change.Labels:
pm:triage→pm:queue,priority:p2added. The seat dispatches it in this round.objectstack-fleet commentedon Nov 8, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
Claim: PM loop round 4 · 2026-11-08T05:38Z
Session:
session_01FEkQ5oAnL2z711MLVm7ZnB(card thread, dev) · seatsession_01FEkQ5nLA7wiVY5YWjT9SvrAccount:
os-project-managerBranch:
claude/project-thread-xmmugmWorktree:
objectstack-issue-31383Domain:
domain:uiSeat:
domain:ui#1File surface:
scheduleWithExpressionand any sibling schedule write path inui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts, its pinflow-node-config.scheduleCadence-12779.test.ts(or a sibling test in that folder, a rendered inspector case allowed), root.changeset/. ⛔ Nopackages/specedit, ⛔ no change to PR #31376's branch, ⛔ no server code.Container & model: M,
mode:thread,model: default tier,effort: highClause-②: no
Metadata-protocol: none
Responsibility: the flow designer writes a typed schedule block with no cadence when the cron is cleared | none (found by contract review 6717630512 on PR #31376) | every flow author clearing a start node's cron
Thread-read: 6717793605
Premise: holds by code reading on
origin/main(grade record 6717793605): clearing the cron on{ type: 'cron', expression }returns{ type: 'cron' }Serial constraints cleared: no other
domain:uicard ispm:dispatchedonflow-node-config.ts; PR #31376 touchespackages/speconly on this pathScope: the card's Expected as written, one PR,
Fixes #31383. The declaration lines start atno/none; the dev measures them on the diff, and the seat amends this claim if they differ. Order:/mnt/project-files/pm-orders/ui/order-31383.md. Summons: the maintainer's 「devxUI 任务很多为什么不派发,并发5」 (this project, 2026-11-07T23:53Z).objectstack-fleet commentedon Nov 8, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5oAnL2z711MLVm7ZnB
os-dev-report
{
"issue": 31383,
"status": "done",
"branch": "claude/project-thread-xmmugm",
"pr": "#31412",
"head": "3251f97c",
"session": "session_01FEkQ5oAnL2z711MLVm7ZnB",
"premise_still_valid": true,
"summary": "scheduleWithExpression's clearing arm now returns undefined whenever the object left after deleting expression and cron resolves to no cadence through normalizeScheduleCadence (the designer's mirror of the engine's normalizeSchedule). A cleared { type: 'cron', expression } or { type: 'cron', expression, timezone } stores no config.schedule; the set arm is unchanged (a typed block keeps type and timezone). Bounded in-place fix named in the PR: a cleared untyped { expression, timezone } used to leave { timezone }, which binds nothing and which PR #31376's flowStartScheduleReadsNothing refuses; it is dropped too. No other designer path writes config.schedule (FlowNodeInspector.tsx line 552 routes the Cron schedule commit through this function; the other schedule helpers only read). Card assignee untouched; pr_create sent no assignees.",
"tests": "flow-node-config.scheduleCadence-12779.test.ts: the old assertion pinning { type: 'cron', timezone: 'UTC' } removed; new describe objectstack#31383, 11 cases (7 typed cleared forms -> undefined, untyped { expression, timezone } -> undefined, CONTROLS: untyped { expression } -> undefined, a cron typed over a typed block keeps type/timezone, clearing { expression, intervalMs } keeps the interval). FlowNodeInspector.scheduleCadence-12779.test.tsx (rendered, fireEvent.change on the real Cron schedule input): clearing a typed cron and a typed cron with timezone leaves config with no schedule key, objectName kept, box empty; CONTROL untyped { expression }. Plus module-top import '@objectstack/lint' (check:test-source-alias). Run on 3251f97: Test Files 2 passed (2), Tests 68 passed (68). Wider: inspectors/FlowNodeInspector* + inspectors/flow-node-config* = 39 files passed, 667 passed, 1 skipped. Ablation via scripts/ablation-replace.mjs: clearing return restored to Object.keys(next).length === 0 ? undefined : next (anchor 1 -> 0, blob aa3d830d -> 91bc6d94): 10 failed / 58 passed (68): the 8 new non-control table cases and 2 rendered typed cases red, every CONTROL green. Restored: blob == HEAD aa3d830d, git diff HEAD empty. Tests import flow-node-config.ts from source by relative path, so no build leg.",
"gates": "Local on head 3251f97: dispatch-gates --commands derived 36 families; all 36 exit 0 (incl. ui vitest scripts/ and check:type-check-debt). --ran with exit codes: 36 derived, 36 run, 0 NOT-MEASURED (derived zero), 0 UNRUN; record pm-orders/ui/31383-gates-ran.txt in project files. Round 1 on 93b35e7: check:test-source-alias exit 1 (edited rendered test reaches import('@objectstack/lint') lazily); fixed in 3251f97 and the whole list re-run. Also: eslint on 3 changed files exit 0; ui check:new-line-citations 0 new, exit 0. Build: spec/formula/client/lint/sdui-parser closures VERDICT command-exit 0. app-shell type-check NOT MEASURED locally (needs all @object-ui dists), declared to CI. CI check-runs: in_progress at report time; the seat holds them.",
"line_budget": "106 changed lines (+98 / -8, 4 files), under 3000",
"files_changed": [
".changeset/31383-flow-designer-cleared-cron-drops-typed-schedule.md",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.scheduleCadence-12779.test.ts",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.scheduleCadence-12779.test.tsx"
],
"declarations": "Clause-②: no; Metadata-protocol: none; measured on the diff: no published key, export, schema arm or i18n string added or removed. Changeset @object-ui/app-shell patch, both lines in PR body and changeset.",
"deviations": "1) Scope: untyped { expression, timezone } -> { timezone } fixed in place under os-dev rule 3's bounded exemption (same defect, same function, inside the claim's file surface, no new gate family); the seat can ask for the narrower typed-only predicate. 2) Two git pushes (93b35e7, then 3251f97 after the round-1 gate red) instead of one. 3) The ablation run itself was not wrapped in os-verify-lock (2 test files, ~16s); every other build/test ran under the lock. 4) PR opened with no labels key (order names none; no skip-changeset applies). os-dev.md rule 2 still says pr_create carries assignees; followed the order (none).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "4 — reads only: mcp__github__issue_read x3 (#31383 get, #31383 get_comments x2), mcp__github__pull_request_read x1 (#31376 get); no write tool",
"api_writes": "4 — git push x2 (branch claude/project-thread-xmmugm); relay pr_create (fw-20261108T063025Z-5f7245, PR #31412, read-back identical, assignees none); this os-dev-report comment on #31383 via post-stamped",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed: PR #31376 is unmerged, so the cleared case was not run through FlowSchema; the comment-review shapes are a typed cron with no expression, which the published ScheduleSchema already refuses on main."
]
}
Generated by Claude Code
objectstack-fleet commentedon Nov 8, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
ACCEPT → PR #31412 comment 6718382774 · 2026-11-08T06:46Z · head
3251f97c(clearing the cron drops a schedule block left with no cadence; 106 lines, not governed,Fixes #31383). Landing through the merge queue.objectstack-fleet commentedon Nov 8, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
Landed · 2026-11-08T07:10Z
218f83456f930b87c621640e7e4d0f063664cea1onmaincompletedbyFixes #31383; no otherdomain:uicard left the open inventoryState:
pm:dispatchedremoved, assignee cleared.