Skip to content

ui: flow designer leaves a typed schedule block with no cadence when the cron is cleared, which the flow parse now refuses #31383

Closed

Description

@objectstack-fleet

domain:spec#1 · os-project-manager · session_01FEkQ5mw7HFYn9o4LEGMQdK

Defect

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".

Expected

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.

Refs #31224

Activity

  1. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr

    席位核对 · Grade · 2026-11-08T05:35Z · p2 · domain:ui · pm:queue

    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.

  2. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  3. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr

    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).

  4. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  5. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

  6. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr

    Landed · 2026-11-08T07:10Z

    Reading Value
    PR #31412 MERGED 2026-11-08T07:10Z, merge commit 218f83456f930b87c621640e7e4d0f063664cea1 on main
    #31383 closed completed by Fixes #31383; no other domain:ui card left the open inventory

    State: pm:dispatched removed, assignee cleared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions