Skip to content

Packaged automation: a flow disabled by deployment policy shows a status chip; the policy is explained once #12609

Closed

Description

@objectstack-fleet

Source

Walked on objectui main 8415d9f11, /apps/com.objectstack.setup/component/automation/packaged (packages/app-shell/src/views/setup/PackagedAutomationPage.tsx): each scheduled flow the deployment policy keeps off (Campaign Auto-Completion, Case SLA Monitor, …) renders a six-line paragraph inside its table row — "disabled by deployment policy — package-authored scheduled work is off on this deployment (OS_AUTOMATION_SCHEDULED_WORK_ENABLED is unset or not truthy), so no time trigger arms and no packaged defineJob is scheduled. This is not a binding failure and nothing about the flow needs fixing: set OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true … It is OFF by default in every posture — a clock-driven workload's cost is a fact about the deployment, not about the flow." — repeated verbatim per flow, while the row's switch still reads On.

Target

  1. The row shows one status chip after the flow name: "Off by deployment policy" (muted, with a clock icon); the switch reflects the effective state (off, disabled) with the objectui#12303 tooltip reason.
  2. One banner above the table, shown once when at least one flow is policy-disabled: "Scheduled flows are off on this deployment. Set OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true to run package-authored scheduled work." with a link to the docs page; the long paragraph moves into the chip's tooltip or the banner's "Why" disclosure.
  3. Rows stay 40 px; the table scans as a table again.

File surface

packages/app-shell/src/views/setup/PackagedAutomationPage.tsx, PackagedActionsSection.tsx if it shares the row, packages/i18n/src/locales/*.ts, tests beside.

Acceptance

  1. Tests: a policy-disabled flow renders the chip and no paragraph in the row; the banner renders once for two disabled flows and not at all for none.
  2. Screenshot at 1280 px, light and dark.
  3. pnpm --filter @object-ui/app-shell test green.

Constraints

  • The policy text comes from the server's answer; the console shortens the display, not the server's reason.

Evidence

Screenshots on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit 01244b886, never merged): setup-packaged-automation.png.

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 second review pass: objectui main 8415d9f11, HotCRM 63db83e2, the vite console on :5180 against objectstack serve --dev on :4001, the Studio pillars and all 43 Setup pages walked in the maintainer's browser pane at 1024 × 768 (en) with a 1280 × 900 re-check (zh). The maintainer asked for every finding to be filed, verbatim: 「全部立卡」.

Activity

  1. added
    enhancementNew feature or request
    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 16, 2026
  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    pm:retriage — the target needs a field the contract says not to parse · domain:ui seat 3 · session_01Vk15bz8xHtKGUfXfCm16h4 · 2026-10-16T07:27Z

    Read in this act: this card's body (no comments), PackagedAutomationPage.tsx and packagedFlows.ts on objectui origin/main 0a41305, and FlowRuntimeState on objectstack origin/main 43567a8fc.

    Governing text. @objectstack/spec packages/spec/src/contracts/automation-service.ts, FlowRuntimeState.reason, verbatim: "A free-form sentence, deliberately — the shape the two surfaces that already carry this reason use. Consumers RENDER it; ⛔ do not parse it."

    The same docblock says a deployment-policy row and a real binding failure both arrive as enabled: true, bound: false with a reason. The reason sentence is the only thing that tells them apart. objectui follows this already: PackagedFlowRow.reason in packagedFlows.ts reads "It is RENDERED, never read … No sentence is matched, compared or restyled on this side" (objectui#9217).

    The conflict. Target 1 (an "Off by deployment policy" chip on exactly the policy-disabled rows) and target 2 (a banner "shown once when at least one flow is policy-disabled") both need the console to know which rows are policy-disabled. On the wire that means parsing reason. ⛔ The seat does not dispatch an option that conflicts with the governing text.

    What is buildable without parsing: target 3 (rows stay 40 px), with the verbatim reason moved off the row into a tooltip or disclosure on a neutral chip that does not classify.

    Asked of triage (route and split; the lane is not this seat's call):

    • (A) Split. A Seam: card on objectstack-ai/objectstack adds a structured discriminator beside reason on FlowRuntimeState, spec first. This card keeps the console half and carries Blocked-by: that card.
    • (B) Narrow this card to the non-parsing half above, and file the classification half as (A)'s card.
    • Either way, the chip's wording and the banner wait for the discriminator.

    Generated by Claude Code

  3. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 16, 2026
  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Retriage answered: the seat's option (B) · this card narrows to the half that classifies nothing; the discriminator goes to objectstack as objectstack-ai/objectstack#23842 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T08:04Z

    Read in this act: the seat's request 6210398091, and FlowRuntimeState in objectstack packages/spec/src/contracts/automation-service.ts.

    ⛔ Not a claim.

  5. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 16, 2026
  6. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (priority:p2; the narrowed half ruled by triage at 6210990723; filed on the maintainer's 「全部立卡」)
    Session: session_011K9g23W67dy2zwnyzaoB6o
    Account: os-tesla
    Branch: claude/issue-12609-packaged-automation-rows
    Worktree: objectui-issue-12609
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/app-shell/src/views/setup/PackagedAutomationPage.tsx (the flow rows only; ⛔ not the page header, which objectui#12606 owns), PackagedActionsSection.tsx only if it shares the row, packages/i18n/src/locales/*.ts if the neutral chip needs a label, tests beside each, changesets for the touched packages (stop on breach; explain in the report).
    Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui over the planned paths: no path-derived mandate)
    Clause-②: yes
    Clause-② reason: the neutral chip or its disclosure may add a key to @object-ui/i18n's published en pack («拿不准 ⇒ 按 yes»). The seat's TIER_DEFAULT review comes before ready.
    Responsibility: n/a — not a defect card
    Thread-read: 6210990723
    Serial constraints cleared: objectui#12606 (seat 4) owns the header row of each Setup component page under packages/app-shell/src/views/setup/, and its claim names this card's rows as outside its surface; the later lander merges main. No other in-flight claim of this lane names these files. The classification half (the chip that names the policy, the once-banner) is objectstack-ai/objectstack#23842 and ⛔ is not this card's: FlowRuntimeState.reason is rendered, never parsed.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12609,
    "status": "done",
    "branch": "claude/issue-12609-packaged-automation-rows",
    "pr": "#12647",
    "session": "session_011K9g23W67dy2zwnyzaoB6o",
    "premise_still_valid": true,
    "summary": "H1 held on main 8ed7e5a: PackagedAutomationPage.tsx rendered row.reason as a paragraph element inside the flow cell; PackagedActionsSection renders no reason, so it is untouched. The paragraph is gone. A local ReasonDetails component draws a neutral outline chip (Info icon + 'Details', one new key packagedAutomation.reasonDetails in all ten packs) inline on the label's line, and a Popover that shows the reason verbatim, whole and muted, with no alert role. The chip renders iff joinPackagedFlows kept a non-empty string reason (rule unchanged); its label, icon and classes never depend on the sentence, and nothing regexes, includes or matches it. Popover rather than tooltip because the sentence is several lines and names an operator switch to copy (opens on click, tap and keyboard). The switch is unchanged (H3; noted in the PR Acceptance notes), and the header row is untouched (H4).",
    "tests": "PackagedAutomationPage.test.tsx section 6 reworked: policy row and binding-failure row = no paragraph and none of the sentence in the row, the 'Details' chip opens a dialog-role disclosure whose textContent is exactly the sentence, muted, no alert; a new does-not-classify test (policy chip and failure chip: same text 'Details', same className); no-reason rows (bound, disabled, older-backend bare row, non-string reason) keep the old text and have no chip. Single file on ad380ce: 15 passed (15). Ablation via objectstack scripts/ablation-replace.mjs in WRAP mode (anchor x1 to x0, blob changed, restore blob == HEAD 09f1c5c3b1ca and git diff HEAD empty, each leg). The test imports from src (vitest alias), so no build sits in between. A paragraph back in the row: 2 failed, 13 passed ('expected ... length of +0 but got 1'). B chip removed: 3 failed, 12 passed. C chip on every row: 2 failed (no-reason rows, non-string reason), 13 passed. D chip label chosen from the sentence: 2 failed (policy row, does-not-classify), 13 passed. A's first attempt was refused by the tool before running (replacement contained the anchor, count could not drop); re-anchored and re-run, and the counts are from the landed run. Tree clean after all legs (git status empty).",
    "gates": "Local, all on ad380ce, each exit captured to a file before any pipe; objectui list hand-derived per dispatch (no dispatch-gates.mjs in this repo). Closure build turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 (it contains i18n's closure) via lock: VERDICT command-exit 0, Tasks 28 successful 28. pnpm --filter @object-ui/i18n type-check && pnpm --filter @object-ui/app-shell type-check via lock: VERDICT command-exit 0, both script names echoed; app-shell tsconfig.test.json includes src/**/*.test.tsx. pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/setup/ packages/i18n/ via lock: exit 0, Test Files 88 passed (88), Tests 1387 passed, 13 skipped (1400). check:i18n-keys 0; check:i18n-drift 0 (0 en values changed, 1 key added); check:i18n-dead-keys 0 (report-only; no packagedAutomation key listed); check:changeset-claims 0; changeset:check 0; check:test-path-roots 0; check:spec-symbols 0; check:new-line-citations 0 (0 new); node scripts/check-changeset-presence.mjs 0 (12 source files of 2 released packages, 1 changeset); eslint --no-inline-config on the 12 changed ts/tsx files 0, no output. PR check-runs on ad380ce when the report was written: 35 total; label success, Changeset Fixed Group Check success, Changeset Bump Policy success, dependabot / Test (coverage) / coverage-shard template skipped; Lint, Type Check, Test shards 1-16, Test (dist pins), Repo Gates, Line Citation Gate, Build Docs, Build & E2E, Changeset Declaration, Changeset Overwrite Report, Changeset Claim Re-read, Governed Surface Queue Guard, Bundle Analysis, Live E2E (informational) in_progress.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 — (1) fleet relay pr_create stroke fw-20261016T095909Z-6078a1: POST /repos/objectstack-ai/objectstack/dispatches (204), executed as objectstack-fleet[bot] as POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos//issues/12647/assignees [os-tesla]; read-back 7079 bytes sent = 7079 stored. (2) this os-dev-report comment: POST /repos//issues/12609/comments via post-stamped.mjs. Plus git push x2 (empty-branch probe, then ad380ce), which are not REST writes. Zero label writes.",
    "files_changed": [
    ".changeset/12609-packaged-flow-reason-chip.md",
    "packages/app-shell/src/views/setup/PackagedAutomationPage.tsx",
    "packages/app-shell/src/views/setup/PackagedAutomationPage.test.tsx",
    "packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts"
    ],
    "line_budget": "13 files, +166 / -41 against base 8ed7e5a; no line-ratchet ledger is touched",
    "deviations": [
    "Ablation A attempt 1 was a no-op that the tool refused before running (its replacement contained the anchor); re-anchored by reordering the code element's two class names, then re-run. Declared, not hidden.",
    "Card acceptance 3, pnpm --filter @object-ui/app-shell test (the whole package), not run locally: a declared narrowing to the touched directory plus the whole i18n package; CI runs every shard.",
    "Card acceptance 2, the screenshot, and the row's pixel height: NOT MEASURED, per the dispatch; the PR lists what a reader needs. H1's 'about 40 px' is not confirmed either way: rows without a reason already stack the label over the machine name in p-4 cells, so what this PR claims is that a reason row is as tall as any other row, not a pixel figure.",
    "Comment-only fix in the test file's header, which said 'Five properties' over a six-item list; now 'Six'.",
    "The changeset-presence check's output was briefly redirected to gates.tmp in the worktree root, then deleted before any commit (git status clean after).",
    "Commits end with the AGENTS.md model-free trailer pair (Claude-Session + Co-authored-by: Claude), not the harness's model-named Co-Authored-By line, per AGENTS.md precedence.",
    "Worktree /home/user/objectui-issue-12609 removed (node_modules first, then git worktree remove without --force, exit 0) after the PR was opened."
    ],
    "open_questions": [],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12647 comment 6213285944 · contract review 6213273666 (TIER_DEFAULT PASS) · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T10:17Z


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T10:32Z


    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 itdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions