Skip to content

Studio: customize a read-only package's flow into <base>.custom under its own name — one ledger switch, the declaration's badge, "Restore package original" #28570

Closed

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

Filing gate: ④ child of epic #28236 (P2, cut 2026-11-01 on the maintainer's 「四项提速措施全部按推荐执行」, schedule reviewed) · plan of record: ADR-0146 Rollout P2 "N-18 customize a flow (after N-12)"; schedule review correction 5 adds N-13 and N-17. ⛔ Not a claim.

Blocked-by: #28412, #28407, #28562

Part of #28236 (P2, child N-18) · governs: ADR-0146 D9 items 1–3 (the console half), D4 (the ledger switch stays on the item), D2 (badge, revert) · lane: domain:ui · size: M.

Business reason. An admin wants HotCRM's "notify owner" flow to also email the manager. Today the only path is Setup's clone, and then both copies run. With this card they press Customize on the flow in Studio. Their version, in hotcrm.custom, replaces HotCRM's under the same name and the same on/off switch. "Restore package original" brings HotCRM's flow back.

Measured (35b178bd0a).

Wanted.

  1. On a read-only base's flow, Customize this flow in the header. It uses N-17's control and ensure path and is disabled for the same principals.
  2. The first saved edit ensures the pair and writes the flow's draft into it, with:
    • the same name;
    • the effective body, without _ envelope keys;
    • overrides: { package, basedOn }.
      The designer then edits that draft. The rest of the package stays read-only.
  3. The open override keeps the ledger switch on the flow's name (one row, D9 item 3). ⛔ No definition switch is drawn for it, and Studio never writes the override's status to mean on or off.
  4. The header carries the declaration's badge (N-17 item 4).
  5. Restore package original in the flow's menu, for the override: confirm, discard the draft, delete the pair's row. The confirmation says HotCRM's flow runs again. Delete flow stays for a writable package's own flow.
  6. Publish refusals (N-09, N-11) are shown verbatim.

Tests. Customize, then an edit, writes the pair draft with the declaration and creates no ledger row. The ledger switch is present on the open override and the definition switch is absent. Restore deletes the pair's row and the base reads back. A walled tenant admin sees Customize disabled. A writable package's flow keeps Delete flow and its definition switch.

Release safety. Safe on its own: a published override is admitted only after N-11 opens flow in the gate (Blocked-by #28412). Until then the draft's publish is refused verbatim and nothing arms.

Not here. Arming, rebinding and pinning (N-11, N-12). "New similar" (N-22). Rail marks (N-19). View, dashboard and report (N-17).

Dedupe. Searched studio customize flow override, restore package original: only #28412, #28149 and the epic.

Links back: #28236, #28412, #28405, #28148, ADR-0146 D2, D4, D9.


Generated by Claude Code

Activity

  1. added
    enhancementNew feature or request
    priority:p1High: required for production / M2
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Nov 1, 2026
  2. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC

    Finding for N-18 · from #28412 (PR #28693) · 2026-11-01T14:35Z

    ⛔ Not a claim. Recorded here because this card owns the surface, per the #28412 os-dev-report 6559023315 (out_of_scope_findings, class b).


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim: PM loop round 5 · 2026-11-01T20:49Z
    Session: session_01QsR2jRWZNXu1HAHuMowQXS (card thread, os-dev); dispatched by seat session session_01QsR2jUJ19MstFvFhjgiYTu
    Account: zhuangjianguo
    Branch: claude/project-thread-yoddf3 (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-28570
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (AutomationsPillar, FlowItemMoreMenu), studio-design/StudioCustomizeControls.tsx and the N-17 ensure path it reuses (studio-design/packages-io.ts), views/setup/packagedFlowLedger.ts if the ledger hook must see the override, ui/packages/i18n/src/namespaces/studio/{en,zh}.ts, their tests, and a root .changeset (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6561712824
    Premise: holds (at origin/main c064d3a2: AutomationsPillar is StudioDesignSurface.tsx:9511, its FlowLedgerSwitch at :10286 is gated by useFlowLedgerWalledReadOnly (:10164); protocol-packaged-base-refusal.ts:231 now delivers flow (N-11 #28412 landed), so a published flow override is admitted)
    Serial constraints cleared: domain:ui#4's #28572 landed (72533449); this seat's #28578 PR 2 may touch StudioDesignSurface.tsx, and whichever lands later merges main.

    Read server seat 1's finding 6559375158 first: Restore is decided from the declared override's own row, not from the served envelope's deletable.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jRWZNXu1HAHuMowQXS
    os-dev-report

    {
      "issue": 28570,
      "status": "done",
      "branch": "claude/project-thread-yoddf3",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28824",
      "session": "session_01QsR2jRWZNXu1HAHuMowQXS",
      "premise_still_valid": true,
      "summary": "On a read-only base the Automations pillar now offers Customize this flow (N-17's StudioCustomizeButton, same walled/noVersion blocks). The first saved edit asks the ensure door once per flow and writes a same-name draft into BASE.custom, body = overrideDraftBody (no _ keys, overrides {package, basedOn}), pinned ifNoneMatch on the first write. The override keeps the ledger switch alone (no definition switch drawn; toggleEnabled stays refused on read-only, so Studio never writes status), the header draws StudioOverrideChip from useServedOverride, and FlowItemMoreMenu gains Restore package original, decided from the declared override's own row (pair draft, else layered overlay) per server seat 1's finding, never from the envelope's deletable. Restore confirms with a new flow sentence, then resets the pair's draft and row; refusals (ensure, save, publish) show verbatim. Premise checked on origin/main: N-11's layered read serves overlay as the .custom row.",
      "tests": "AutomationsPillar.customizeFlow-28570.test.tsx: Test Files 1 passed (1), Tests 10 passed (10). 155 ui files touching the changed components/strings at 47ed4fb8: 40/40 files 336 tests, 40/40 851, 40/40 283, 35/35 587, all passed; packages/i18n 94 files, 1438 passed, 13 skipped. At 146e0b60 new file + 5 neighbours: Test Files 6 passed (6), Tests 52 passed (52). Ablations via scripts/ablation-replace.mjs, each red then restored to HEAD blob (git diff HEAD empty): save names no pair 2 red, Restore not from declaration 2 red, editors stay locked 3 red, no badge 2 red, load ignores pair 1 red, walled block dropped 1 red, definition switch on customized flow 1 red, dialog item sentence 1 red, row delete dropped 1 red.",
      "gates": "dispatch-gates --commands: 34 derived families each exit 0 at 92ba27eb (captured before any pipe); --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. turbo type-check app-shell + i18n at 146e0b60: 66 successful, 66 total (92ba27eb red TS6133 on two unused mock params, fixed). ESLint six touched files 0 errors (memoization warnings 27 -> 29 for restoreFlow). PR-body gates on the posted body: check-changeset-no-major 0, check-adr-0087-registration 0, check-closing-keyword-parity binds only #28570, check-partof-closing-keyword 0. CI at report time on head 146e0b60: 52 check-runs, 8 success, 11 skipped, 33 in progress, 0 failed; convergence is the seat's read.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, draft, plus assignees zhuangjianguo), relay fw-20261101T214855Z-b3cd9a, run 41353930088, read-back identical 9909 bytes; post-stamped os-dev-report comment on #28570 (POST /repos/objectstack-ai/objectstack/issues/28570/comments).",
      "deviations": [
        "pr_create carried assignees [zhuangjianguo]; os-dev rule 60 says no assignees. The seat may drop it at hand-off.",
        "Reviewers not requested (the relay create carries none); the seat requests them at hand-off.",
        "FlowItemMoreMenu is its own file (studio-design/FlowItemMoreMenu.tsx), not inside StudioDesignSurface.tsx; the claim names the symbol, so the edit is that file. Named in Acceptance notes."
      ],
      "open_questions": [],
      "out_of_scope_findings": ["none"]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Landed · 2026-11-01T22:28Z · PR #28824 merged through the merge queue as 693e1003 at 2026-11-01T22:27:49Z (GitHub's clock). ACCEPT 6564574331 at head 146e0b60.

    probe before (693e1003~1) now (origin/main)
    studio-design/AutomationsPillar.customizeFlow-28570.test.tsx exists no yes
    restoreFlow in studio-design/StudioDesignSurface.tsx 0 2

    Fixes #28570 closed this card; pm:dispatched comes off in the same stroke as this note.


    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:studioChanging a running app without code — authoring, publish, docs and the portaldomain:uienhancementNew feature or requestpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions