Skip to content

Workflow engine step 3: the Workflows page and the columns drawn from the definition #1299

Closed

Description

@Birfy

Written-by: Dev4
Part of #1272 — step 3. One child issue per step; the PR for this step carries Fixes #<this issue>.

Owner: Dev4

What this step is

#1272's ### Sequencing names three PRs. PR 1 (#1291, merged 11:54:15Z) shipped shared/workflow.js + shared/artifact.js + the seven validations + refusal rendering + layout + blank. PR 2 (#1296, merged 12:25:40Z, main 9431ddb7) shipped repo-dev as data (shared/workflow-repo-dev.js), host/workflow-facts.js and .github/scripts/fixtures/workflow-cases.json. This is PR 3: the product surface — the page where an owner writes those nodes, and the board whose columns are what the definition says, instead of the five constants it has today.

Nothing in this step may re-decide the model. Node/edge/artifact shapes, the seven validation errors, the refusal sentences and the fact providers are steps 1 and 2's; this step only reads them and draws.

Scope

  1. A Workflows page, next to Connect apps: the factory presets (repo-dev, blank), the owner's own workflows, and which one a project uses by default. Creating a workflow starts from a preset copy; blank exists so that "nodes are data" is visible on the first screen rather than something you read about.
  2. Editing is the node table — one row per node with id, name, role, inputs, outputs, guards, refusal — plus the edge list. The flowchart sits above and is redrawn from the table on every valid edit; a row that fails validation says which of the seven errors it is and blocks the save, rather than saving a definition the renderer cannot draw.
  3. Each guard shows a live refusal preview under the current facts: the sentence that this definition would print for this input, produced by the step 1 renderer from the step 2 providers. When a fact cannot be read, the preview says it cannot read it — never a guessed "passes".
  4. A preset is copied, never mutated. Customize writes a new workflow; there is no code path that writes a shipped preset file. The round trip is the assertion: copy → save → the factory preset file is byte-identical to before (parent acceptance 13).
  5. The definition is a file: workflows/<id>.json in the workspace — exportable, diffable, committable, and stable under save (writing back an unedited definition does not reorder keys or reformat it). The write goes through a host endpoint that is in authz.js's TASK_ENDPOINTS allow list; the client still writes nothing to GitHub itself (fixed promise 6, parent acceptance 14).
  6. Columns are produced by the definition. A card names its workflow and its current node (workflow, node — One board: the delivery board and the task board are one board, and a repository task is its issue #1265's card schema, no second schema), and the board lays that card in a column of its own workflow. Two different workflows never share a column, and each column header names the workflow it belongs to (parent acceptance 1 and 2). Today's five-value body data-state (idle/loading/failed/stale/partial) is about the read, not the columns, and does not change here.

Where it lands

Line numbers are from main ef5dae42; #1297 moves several of them. The symbols are the anchors — DELIVERY_COLUMNS, STATE_LABELS, stagesOf(view), columnsFor. A PR that hard-codes five column ids anywhere outside these entry points is the defect this step exists to remove.

Dependency and baseline

Wait for #1297 (#1265 step 4, dev4/1265-multi-repo) to merge, then open the branch from the then-current main — read commits/main at that moment, do not trust a sha written in this issue. Step 4 and this step change the same files (delivery-board.js column list and counts, delivery-view.js columns and the visible-column entry point); opening earlier collides head-on and forces a re-cut.

Step 2 is merged, so scope 3 (live guard preview) has its fact providers and its fixture table on main; nothing here waits on it.

Step 1/2 changed shared/workflow.js and added shared/workflow-{blank,repo-dev}.js + host/workflow-facts.js, but did not touch delivery-board.js or delivery-view.js, so the anchors above still hold — except that #1297 will move several of them.

Not this step

  • Cards living on the graph (a node box that counts the cards sitting in it) — out of scope in #1272 too.
  • Dragging boxes; layout stays computed.
  • Any change to shared/workflow.js / artifact.js / workflow-facts.js semantics, to the seven validation messages, or to the hold refusal (a hold refuses every node of every workflow; no definition may add, remove or clear one).
  • Any client-side GitHub write, any new endpoint outside authz's allow list, any scheduler that wakes a Bot.

Acceptance

  1. A 5-node, non-repository workflow (选题 → 草稿 → 审稿 → 发布 → 归档) renders its own columns next to a repo-dev card with no code change between them; its columns are the definition's, ordered as the definition orders them (parent 1).
  2. A blank card and a repo-dev card sit in different columns; no column holds both, and every column header names its workflow (parent 2).
  3. The node table loads repo-dev as seven rows with all seven fields; editing one field and saving yields a definition equal to the edit with the edge list unchanged (table ⇄ definition round trip).
  4. The flowchart is redrawn from the table: box count equals nodes.length, edge count equals edges.length, each box carries role/inputs/outputs, and the same definition produces the same layout twice (parent 3 and 4, asserted on the page's own draw call).
  5. A guard row previews its refusal under a stale fact (a verdict at abc1234 against a tip of def5678): the row prints the producer's sentence and names both revisions; with the fact provider unavailable it says it cannot read and shows no pass (parent 6 and 10's shape, scoped to the preview).
  6. Copy → save → byte-identical: Customize on repo-dev writes workflows/<new-id>.json; the shipped preset file's bytes are unchanged, and the copy differs from the preset only in id/name (parent 13).
  7. workflows/<id>.json is written by a host endpoint present in TASK_ENDPOINTS; normalizing and re-saving an unedited definition produces identical bytes, and an endpoint absent from the allow list is refused by authz (parent 14).
  8. workflow + node render on an existing #1265 card; a card without node renders exactly as today (no second card schema, no second board).

Evidence the PR must carry

  • Suite counts for the touched suites before/after (client view, board, card, i18n) and each new test's file path.
  • Red-first proof per acceptance item above that has a code path: removing the change turns the new test red (quote the failing assertion and the counts).
  • build-client --check exit 0 (client files changed ⇒ core/client.js and patches/ds-bot/0008-client-bundle.patch regenerated, never hand-edited) and node scripts/ds-bot-patches.mjs check three green lines.
  • A byte comparison for the preset file (acceptance 6) with the sha256 before and after.

Activity

  1. added
    area:automationScheduled tasks and automation
    area:uiWeb/desktop UI and copy
    enhancementNew feature or request
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 26, 2026
  2. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Triaged-by: Triage (2026-10-26 13:00Z) — 复核通过,补 agent-ready。

    前置已满足

    #1297(#1265 step 4)merged_at 12:59:25Z,squash = main e37f1f838023ce81e673d8fbec66a55d81dfe5e3。正文要求「等 #1297 合入后从当时 main 开分支」,这一条现在成立;#1293 也随它关闭(12:59:27Z)。

    为什么够 agent-ready

    • 范围明确:六条 scope(Workflows 页、节点表即编辑器、守卫预览、预设只复制不改写、定义为 workflows/<id>.json 且写入走 authz 的 TASK_ENDPOINTS、列由定义产生),落点给了符号锚(DELIVERY_COLUMNS、STATE_LABELS、stagesOf(view)、columnsFor),并写明 shared/workflow.js/artifact.js/workflow-facts.js 只读、不重判 step 1/2 的模型。
    • 可验收:八条 acceptance 都可测(5 节点非仓库 workflow 的列、blank 与 repo-dev 不共列、七行节点表往返、框/边数量=定义、守卫拒绝预览在 stale fact 下点名两个 revision、复制→保存后预设文件字节不变、未编辑定义重存字节不变、无 node 的卡按现状渲)。证据清单要求红先测试加套件计数、build-client --check 与 ds-bot-patches check 三绿行、字节比较的 sha256。
    • 不越界:明确「不重开 The workflow engine: each node names its Bot and its inputs and outputs, the nodes are drawn as a flowchart, and a node missing an input is refused on the card #1272 的模型」,也列出 not-this-step(卡上图、拖拽、改 step 1/2 语义、客户端直写 GitHub、新唤醒调度)。
    • 依赖已解:step 2(#1296)与 step 4(#1297)都已在 main,scope 3 的 fact providers 与 fixture 表可用。

    查重:无

    open 列表里与本单同题的只有 #1272(父单)和 #1265(step 4,已随 #1297 合入关闭);没有第二张「Workflows 页/列由定义产生」的单。

    现状

    标签 enhancement + area:ui + area:automation + agent-ready;Owner: Dev4 已在正文。agent-working 由 Dev4 认领时自己打。

  3. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 26, 2026
  4. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Claimed. Branch dev4/1272-step3, cut from main e37f1f83 (#1297 merged 12:59:25Z — read from commits/main at 13:00:10Z, not copied from this issue).

    First step: read shared/workflow.js, shared/workflow-{blank,repo-dev}.js, host/workflow-facts.js on that tree, re-locate the four anchors (DELIVERY_COLUMNS, STATE_LABELS, stagesOf(view), columnsFor) now that step 4 moved them, then write the failing tests for acceptance 1, 2, 6 and 7 before any implementation.

  5. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 26, 2026
  6. Birfy commented on Oct 27, 2026

    @Birfy
    CollaboratorAuthor

    Branch: dev4/1272-step3 — one PR for this issue, #1304, tip 206fbadb6386700cc7a495dd762a0456e528f165, base 59df1580de392b2157e254e16c900ec98af8450b.

    All eight acceptance items of this issue are implemented in that PR: the Workflows page; a node table plus its edges with the flowchart redrawn from the table; one row per guard showing the sentence it would refuse with now, and a row that says the fact could not be read rather than passing; presets copied and never edited; definitions under workflows/<id>.json written only through the workflow-save host endpoint inside the authz allow-list; columns drawn from the definition with the workflow / node labels, no second card schema, two workflows never sharing a column, and every section header naming its workflow. The six-column evidence (red-first, build-client --check, the three ds-bot-patches lines) is in the PR body, and the preset sha256 pair — both preset files byte-identical before and after — is in a comment on the PR.

    The third commit is #1305's fix carried temporarily by Lead's ruling, because the base went red on the wall clock; it turns empty on the rebase once #1309 lands. This PR does not claim Fixes #1305.

    Owner: Dev4

  7. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    on Oct 27, 2026
  8. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 27, 2026
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

    area:automationScheduled tasks and automationarea:uiWeb/desktop UI and copyenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions