Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

studio(automations): flow status shown by Studio disagrees with what runs — header Trigger reads flow.type, a published flow reads Status draft, unbound scheduled flows read On/active #11779

Closed

Description

@objectstack-fleet

Filing gate ① — product defect with a named location and a reproduction. reach: Studio → Automations, read against the server log and the published metadata of the same flows.

Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.

What happens

Expected

One source of truth for state: the header shows the real trigger; published/enabled state reads the same in list and header; a flow the deployment will never run says so.

Suggested direction (triage to rule)

Header trigger from the Start node; one derived status used by list, header and Problems; render the unbound state visibly (e.g. a grey Not running here chip) from the per-flow binding the server already serves on GET /api/v1/automation/_status (objectstack-ai/objectstack#18235); align the default toggle with the "off by default" promise or change the copy.

Environment

objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless stated.

Duplicate check

Dedupe words: flow status header autolaunched · status draft published flow · scheduled flow not bound shown on · off by default enabled

Filed by Claude Code (session session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:workflowApprovals and automation — the work that runs without a person driving it
    on Oct 7, 2026
  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: approvals and automation — the author sees what will run | 缺项 | P2

    Triage: first grade, bug · priority:p2 · domain:ui · area:workflow · pm:queue. Direction as the body proposes

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T16:07Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in the Studio Automations list, flow header and Problems panel ⇒ domain:ui; rationale: a Studio or console surface in objectui. Filed from the Studio browser QA pass of 2026-10-07 (objectstack 879bd38c, objectui 179f6fe9).

  3. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_01CGZy1BGCjdN5cXqL9cnvB8
    Account: os-support-ai
    Branch: claude/issue-11779-flow-status-truth
    Worktree: objectui-issue-11779
    Domain: domain:ui
    Seat: domain:ui#3
    File surface (on d53fd02):

    • packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx, the Automations pillar only:
      • the runtime state from GET /automation/_status (FlowRuntimeState :4552, flowRailState :4586, the fetch at about :4733);
      • the list row's On/Off label;
      • doCreateFlow (:4793) for the new flow's enabled default;
    • packages/app-shell/src/views/metadata-admin/previews/FlowPreview.tsx (the header pills at about :220–:221: Trigger reads flowType, Status reads status);
    • packages/app-shell/src/views/metadata-admin/previews/flow-problems.ts (buildFlowProblems :227) and ProblemsPanel.tsx, only if the unbound state shows there;
    • the engine.studio.auto.* / engine.flowPreview.* rows of views/metadata-admin/i18n.ts;
    • the tests beside them;
    • .changeset/11779-*.md.

    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/objectui: no path-derived mandate; default tier)
    Clause-②: no
    Responsibility: objectui app-shell: the flow header's Trigger pill reads flow.type rather than the Start node's trigger, its Status pill reads a status key a published flow lacks (so it reads draft), the list's green On ignores the server's binding for an unbound scheduled flow, and a new flow's toggle starts enabled under an "Off by default" bar | the platform path exists: GET /api/v1/automation/_status serves each flow's enabled and bound state (objectstack-ai/objectstack#18235), and the Start node carries triggerType | every author reading a flow's state in Studio → Automations
    Thread-read: 6041845966
    Serial constraints cleared: none blocking. This seat's objectui#11778 (area:workflow, in flight) holds FlowCanvas.tsx, flow-canvas-parts.tsx, flow-node-config.ts and FlowNodeInspector.tsx, and its pushed diff touches none of the files above except a test (FlowPreview.removeNode-11772.test.tsx), which this card does not edit. So the same-axis surfaces are disjoint.

    StudioDesignSurface.tsx is shared with this seat's objectui#11784 (area:studio, a different axis). That card holds only PackageSwitcher's onManageChanged (:665), a different region. Whichever lands second merges main. No open objectui PR touches the files above (read 2026-10-07T20:22Z; open: #11830, #11829, #11600, #11069).

    Why Clause-②: no: display and default fixes inside @object-ui/app-shell. Its strings are rows of app-shell's unexported designer table. If the fix needs a published export, prop, type member or language-pack key, the dev reports it before opening the PR, and the seat amends this line.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 11779,
      "status": "done",
      "branch": "claude/issue-11779-flow-status-truth",
      "pr": "https://github.com/objectstack-ai/objectui/pull/11834",
      "session": "session_01CGZy1BGCjdN5cXqL9cnvB8 (subagent mode: the parent seat session, as the dispatch names it; the relay derived the same id from the container)",
      "premise_still_valid": true,
      "summary": "All four defects confirmed at source on d53fd02 and fixed in @object-ui/app-shell. (1) The header Trigger pill reads the Start node through the spec resolver resolveFlowTriggerKind: a record trigger shows its event and object (Record updated · task), time-relative shows its object, schedule and API their kind, and only a flow with no resolvable trigger falls back to flow.type; the words are the Start-node inspector option labels (en and zh). (2) One derivation, deriveFlowRunStatus plus describeFlowRunStatus in flow-problems.ts, is read by the rail FlowStatusDot, the header Status pill and a Problems-panel note; the pillar hands the open flow its _status row through FlowRuntimeContext (a context, so MetadataPreviewProps is unchanged). A published flow with no status key now reads On (runtime) or Enabled (no runtime), never draft. (3) An enabled flow with a declared triggerType and bound false reads a grey Not running here in the rail and the header (platform reason verbatim as the title) and gets an uncounted, non-error note in Problems; a flow that declares no trigger keeps On. (4) Fork decided per the four axes: the default follows the bar, doCreateFlow saves status obsolete, so the switch reads Disabled under Off by default. Measured on the published 17.7.0 engine: a no-status flow is stored as status draft (spec default) and armed; manual rows carry no triggerType and no reason; every enabled unbound declared-trigger row carries a reason.",
      "tests": "All runs from the worktree root through os-verify-lock. At final head 26ec168 (after merging origin/main 32124ac): vitest studio-design/ + metadata-admin/previews/ + plainLanguage pin + src/__tests__/ + console StudioRoute suites: Test Files 217 passed (217), Tests 2287 passed; vitest metadata-admin __tests__/ datasource/ external/ inspectors/ + 165 root files + apiErrorEnvelope + AiChatPage 11658 + three i18n suites + scripts check-i18n-call-site-keys: Test Files 303 passed (303), Tests 3597 passed, 1 skipped; turbo build of app-shell^... (28 tasks, 24 cached) then pnpm --filter @object-ui/app-shell type-check (tsc --noEmit and tsc -p tsconfig.test.json, which compiles the tests): VERDICT command-exit 0. Before the merge, at 6916515: 221 files / 2466 tests passed and 295 files / 3358 passed 1 skipped (same union). New pins: StudioDesignSurface.flowStatusTruth-11779.test.tsx (8), FlowPreview.headerPills-11779.test.tsx (7), flow-problems.runStatus-11779.test.ts (9). Ablation (restore the old Trigger pill source, value translateFlowMeta type of d.type, over value flowTriggerLabel), through ablation-replace.mjs with its own restore: leg 1 at cd562f5, anchor 1 to 0, blob 1404ef239c15 to f12c7b8d4439, 5 failed 10 passed; leg 2 at 26ec168, blob 172f1cbf7090 to 7bfb27b575ab, 5 failed 10 passed (red: record en, record zh, time-relative, record through the pillar, schedule; green: the type-fallback control and every status pin); both restores proven blob == HEAD and git diff HEAD empty. Declared narrowing: the ~560 app-shell test files outside studio-design/, metadata-admin/ and src/__tests__/ were not run locally (git grep found no direct import of a touched module there beyond those run); CI pnpm test runs them. NOT MEASURED: browser rendering (DOM pinned through the real pillar and preview only).",
      "mcp_calls": "0",
      "api_writes": "3 relay writes as objectstack-fleet[bot] (fleet-write repository_dispatch to objectstack-ai/objectstack, each read back): pr_create POST /repos/objectstack-ai/objectui/pulls (PR 11834, draft, 11934 bytes sent = stored); assign POST /repos/objectstack-ai/objectui/issues/11834/assignees (os-support-ai, read-back MATCHES); comment POST /repos/objectstack-ai/objectui/issues/11779/comments (this os-dev-report). Plus git push of the branch (not REST).",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none named (承接者:无) · noted in Acceptance notes, not filed · buildFlowSkeleton in skeletons.ts still emits no status; the default-off key is added in doCreateFlow to stay inside the claimed surface, so createConformance.test.ts skeleton gate does not see it (the new pillar pin parses the body doCreateFlow saves with FlowSchema). Moving the key into the skeleton is a one-line follow-up.",
        "carrier: none named (承接者:无) · noted in Acceptance notes, not filed · Setup Packaged automation page (packagedFlows.ts, objectui#9217) projects the same _status rows through its own reader and is not moved onto deriveFlowRunStatus here."
      ],
      "gates": [
        {
          "command": "pnpm --filter @object-ui/app-shell type-check (after turbo build app-shell^...)",
          "exit": 0,
          "verdict": "os-verify-lock: VERDICT command-exit 0 (head 26ec168)"
        },
        {
          "command": "pnpm exec vitest run studio-design/ metadata-admin/previews/ plainLanguage-11659 src/__tests__/ console StudioRoute x2",
          "exit": 0,
          "verdict": "Test Files 217 passed (217); Tests 2287 passed (head 26ec168)"
        },
        {
          "command": "pnpm exec vitest run metadata-admin __tests__/ datasource/ external/ inspectors/ + root files + 6 outside readers",
          "exit": 0,
          "verdict": "Test Files 303 passed (303); Tests 3597 passed | 1 skipped (head 26ec168)"
        },
        {
          "command": "pnpm exec eslint (15 touched ts/tsx files)",
          "exit": 0,
          "verdict": "0 errors; per-file warning counts equal to origin/main 32124ac (StudioDesignSurface 14, FlowPreview 2, ProblemsPanel 0, flow-problems 0, i18n 0)"
        },
        {
          "command": "pnpm check:control-bytes",
          "exit": 0,
          "verdict": "check-control-bytes: OK (scanned 7809 tracked text file(s); skipped 85 binary)."
        },
        {
          "command": "pnpm check:test-path-roots",
          "exit": 0,
          "verdict": "check-test-path-roots: OK"
        },
        {
          "command": "pnpm check:changeset-claims",
          "exit": 0,
          "verdict": "Every package declared across those 1 body(ies) is either not negated"
        },
        {
          "command": "pnpm check:pending-changeset-literals",
          "exit": 0,
          "verdict": "No test source names a pending changeset."
        },
        {
          "command": "pnpm check:i18n-keys",
          "exit": 0,
          "verdict": "Every in-scope call-site key resolves against the en pack (3297 keys)"
        },
        {
          "command": "pnpm check:i18n-drift",
          "exit": 0,
          "verdict": "No en value changed in this range."
        },
        {
          "command": "pnpm check:i18n-dead-keys",
          "exit": 0,
          "verdict": "report-only; the three new rows are not among its candidates"
        },
        {
          "command": "pnpm check:i18n-designer-parity",
          "exit": 0,
          "verdict": "Every en row has a zh row, and every shared row carries the same placeholders."
        },
        {
          "command": "pnpm check:new-line-citations",
          "exit": 0,
          "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0"
        },
        {
          "command": "pnpm check:vi-mock-specifiers / vi-mock-inherit / vi-mock-override-shape",
          "exit": 0,
          "verdict": "OK x3"
        },
        {
          "command": "pnpm check:spec-symbols",
          "exit": 0,
          "verdict": "spec symbol derivation: 1471 files scanned against 5140 spec export names; 0 untriaged collisions"
        },
        {
          "command": "node scripts/check-changeset-presence.mjs",
          "exit": 0,
          "verdict": "15 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11779-flow-status-truth.md."
        },
        {
          "command": "check:readme-exports",
          "exit": null,
          "verdict": "not run: no package export changed (src/index.ts untouched)"
        }
      ],
      "deviations": [
        "PR body is stale on one section, by timing not content: it cites head 6916515 and the pre-merge counts (221 files / 2466 tests; 295 files / 3358 tests). origin/main moved after the PR opened (objectui#11778, #11784, #11774, #11809 landed, touching flow-node-config.ts, StudioDesignSurface.tsx and i18n.ts); the branch merged it (no conflict) as 26ec168 and the full union above was re-run there. Seat edit, not done here (one PR-body write): retitle the section Tests and gates (head 26ec168), replace the two count lines with 217 files / 2287 tests and 303 files / 3597 tests 1 skipped, and in Ablation add that a second leg at 26ec168 (blob 172f1cbf7090 to 7bfb27b575ab) gave the same 5 red / 10 green; the first leg quoted there ran at cd562f5.",
        "Placement inside the claimed surface: the shared derivation and FlowRuntimeContext live in flow-problems.ts (listed) rather than a new module (unlisted, and the claim says stop on any file outside the list). The context first sat in ProblemsPanel.tsx and moved because react-refresh/only-export-components flagged it there; flow-problems.ts now imports createContext, so its objectui#11772 note was reworded from React-free to component-free. A dedicated module is the cleaner home if the seat amends the surface.",
        "Updated existing pins on purpose: the objectui#11281 cases that held a policy-unbound flow at a green On (FlowStatusDot.test.tsx, StudioDesignSurface.railUnboundReason-11281.test.tsx) now read Not running here, and the no-reason declared-trigger case titles notRunningTitle instead of Enabled; the 11124, 11546, 11553 and 11204 pillar suites waited on the raw active Status pill and now wait on its derived Enabled. This card Expected (a flow the deployment will never run says so) supersedes the 11281 visible-text choice.",
        "Three new designer-table rows in i18n.ts (en and zh): engine.studio.auto.notRunning, engine.studio.auto.notRunningTitle, engine.studio.auto.unpublishedTitle. Not language-pack keys, no package export, prop or type member reaching the built entry: Clause-② no stands.",
        "Declared test narrowing (above) and browser rendering NOT MEASURED.",
        "Lock: two acquisitions timed out once each (exit 99, holders were other agents vitest runs, pid 31565 and pid 15547); both re-acquired with the same slot and the runs completed."
      ],
      "files_changed": [
        ".changeset/11779-flow-status-truth.md",
        "packages/app-shell/src/views/metadata-admin/i18n.ts",
        "packages/app-shell/src/views/metadata-admin/previews/FlowPreview.tsx",
        "packages/app-shell/src/views/metadata-admin/previews/ProblemsPanel.tsx",
        "packages/app-shell/src/views/metadata-admin/previews/flow-problems.ts",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
        "packages/app-shell/src/views/metadata-admin/previews/FlowPreview.headerPills-11779.test.tsx",
        "packages/app-shell/src/views/metadata-admin/previews/flow-problems.runStatus-11779.test.ts",
        "packages/app-shell/src/views/metadata-admin/studioAutomationCopy.plainLanguage-11659.test.ts",
        "packages/app-shell/src/views/studio-design/FlowStatusDot.test.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.flowStatusTruth-11779.test.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.railUnboundReason-11281.test.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnly-11124.test.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnlySelect-11546.test.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.packageLessFlows-11553.test.tsx",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.autosaveInFlight-11204.test.tsx"
      ],
      "line_budget": "not applicable (no skills/** surface)"
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T22:30Z. PR objectui#11834, head 26ec168.

    • PR shape: draft against main. origin/main 32124ac is merged in with no conflict. First line Fixes #11779, no other closing keyword. Clause-②: no at line start. The five commits carry only the model-free trailer pair.

    • Scope: 16 files, +924/−98, on the claim's surface (6046146169):

      • FlowPreview.tsx, ProblemsPanel.tsx, flow-problems.ts, and the Automations pillar in StudioDesignSurface.tsx;
      • three designer-table rows in i18n.ts;
      • three new pin files;
      • seven existing pins beside them;
      • the changeset.

      MetadataPreviewProps is unchanged: the runtime row reaches the preview through FlowRuntimeContext. No export, prop, type member or language-pack key reaches the built entry. No governed path.

    • Diff read (the seat's own):

      • Trigger pill: reads the Start node through the spec's resolveFlowTriggerKind, in the Start-node inspector's words. It falls back to flow.type only with no resolvable trigger.
      • Status: one derivation, deriveFlowRunStatus / describeFlowRunStatus in flow-problems.ts, feeds the rail's FlowStatusDot, the header Status pill, and a Problems note (not counted, not error-styled). An enabled flow with a declared trigger and bound: false reads Not running here, titled with the platform's reason. A flow with no trigger keeps On.
      • New flows: doCreateFlow saves status: 'obsolete', so a new flow reads Disabled. That is the same value the existing enable switch writes for Disabled (toggleEnabled: next ? 'active' : 'obsolete'), not a new state.
    • Ruling honoured (triage 6041845966):

      • the header trigger is read from the Start node;
      • one derived status is used by the list, the header and Problems;
      • the unbound state is visible (a grey chip) from _status.

      The card's one fork (Zone 2 item 4: the new flow's default) is answered on the four axes in the PR body: the default follows the bar's "Off by default" promise.

    • Existing pins changed, accepted:

      • The objectui#11281 cases that held a policy-unbound flow at a green On now read Not running here. This card's Expected ("a flow the deployment will never run says so") and its ruling supersede that card's visible-text choice; its hover reason is kept.
      • Four pillar suites waited on the raw active Status pill and now wait on the derived Enabled. No assertion was loosened.
    • Changeset sentences checked against the head: the Trigger, Status, Not-running-here and New-flows bullets, including "the Problems panel shows the same reason as a note, which is not counted as a problem" and "saved with status: 'obsolete'". patch on @object-ui/app-shell.

    • Reverse verification (dev report 6048136899):

      • Ablation (the old Trigger-pill source) at cd562f5 and again at 26ec168, each restored with the blob equal to HEAD: 5 red (record en/zh, time-relative, record through the pillar, schedule), and the type-fallback control and every status pin stayed green.
      • The dev measured on the published 17.7.0 engine that a flow with no status key is stored as draft and armed, which is why the default needed to change.
      • The studio-design/ + previews/ union passed 2287 tests and the metadata-admin union passed 3597, on 26ec168.
    • Gates: CI on 26ec168 (head_sha equals the PR head): 43 runs, 40 success, 3 skipped (Test (coverage), its shard template, dependabot), 0 failure. Lint and Type Check are success. Mergeable state clean.

    • Contract review: not required (Clause-②: no).

    • PR body: the dev refreshed the test section to 26ec168. One preamble line still says "Runs, all at 6916515 unless stated", and the eslint line compares against d53fd02. These are timing labels, not claims about the head, so they are left as they are.

    Findings:

    • buildFlowSkeleton (skeletons.ts) still emits no status, so the default-off key lives in doCreateFlow and createConformance.test.ts does not see it. A one-line follow-up, off the claim's surface → Acceptance notes
    • The Setup Packaged automation page (packagedFlows.ts, objectui#9217) reads the same _status rows through its own projection, not deriveFlowRunStatus. Not measured as wrong → Acceptance notes
    • FlowRuntimeContext lives in flow-problems.ts, which now imports createContext; a dedicated module would be a cleaner home. The claim's surface did not list one → Acceptance notes

    Landing: ready + auto-merge through the queue, now.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-07T22:50Z. PR objectui#11834 merged through the queue as 16cda0b at 2026-10-07T22:48Z.

    • The merge:
      • One parent, 03fc85d (seat 1's objectui#11776 landing), an ancestor of origin/main.
      • The landed tree equals git merge-tree of that parent and the accepted head 26ec168 (tree c41e7af9 on both).
      • 16 files, +924/−98.
    • Content check, 03fc85d → 16cda0b, in packages/app-shell/src:
      • files naming deriveFlowRunStatus: 0 → 4;
      • the Trigger pill's old translateFlowMeta('type', flowType source: 1 → 0;
      • control: the enable switch's next ? 'active' : 'obsolete' mapping is 1 on both sides, so the new-flow default reuses it unchanged.
    • Closures: the PR's only closing keyword was Fixes #11779. Since 22:00Z, the issues closed are objectui#11779 and objectui#11776 (seat 1's own PR). pm:dispatched is removed.

    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:workflowApprovals and automation — the work that runs without a person driving itbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions