Archify Lifecycle Renderer 完全指南:用 JSON 构建可验证的阶段生命周期图
2026/9/14 14:06:20 网站建设 项目流程

Archify Lifecycle Renderer 完全指南:用 JSON 构建可验证的阶段生命周期图

【免费下载链接】archifyAgent skill for beautiful, verifiable architecture, workflow, sequence,>项目地址: https://gitcode.com/GitHub_Trending/arch/archify

Archify 的 Lifecycle Renderer 是一种将diagram_type: "lifecycle"的 JSON 描述文件渲染成自包含 HTML 图表的专用渲染器,专为表达"阶段、事件与终态"并存的生命周期而设计——例如 Agent 任务运行的生命周期、部署发布流程、订单履约链路等。读完本文,你将掌握生命周期 JSON 的完整编写语法(lane/state/transition 语义)、布局预算与路由预设的使用方法,并能利用渲染器内置的零依赖校验与质量门禁(standard/showcase 双档)产出可验证、可交付的高质量 SVG/HTML 图表。

一、快速开始:渲染一个生命周期图

Lifecycle Renderer 的入口是 render-lifecycle.mjs,它是一个零依赖安装的 Node.js 命令行渲染器,用法如下:

node archify/renderers/lifecycle/render-lifecycle.mjs input.lifecycle.json output.html

其输入为遵循 lifecycle.schema.json 的 JSON 文件,输出为套用标准 Archify HTML 模板的独立 HTML 文件。渲染器使用仓库内置的 standalone 校验器进行 Schema 校验,无需安装任何 npm 依赖

output.html是可省略的:省略时渲染器会按以下优先级决定输出路径(对应 cli.mjs 中的resolveOutputPath逻辑):

  1. 命令行第二个参数(显式输出路径);
  2. JSON 中meta.output字段;
  3. 兜底为当前工作目录下的lifecycle.html

如果你想直接看到效果,仓库已内置一个完整可运行的示例,直接执行:

node archify/renderers/lifecycle/render-lifecycle.mjs archify/examples/agent-run.lifecycle.json

即可按示例 JSON 中的meta.outputexamples/lifecycle-agent-run.html)生成渲染结果。渲染器入口的默认示例正是agent-run.lifecycle.json(见 render-lifecycle.mjs)。

二、输入结构:Lifecycle JSON 的顶层骨架

一份合法的 Lifecycle JSON 必须包含以下顶层字段,最小骨架如下(摘自 README):

{ "schema_version": 1, "diagram_type": "lifecycle", "meta": { "title": "Agent Run Lifecycle", "viewBox": [980, 660] }, "lanes": [], "states": [], "transitions": [], "cards": [] }

依据 lifecycle.schema.json,各字段的约束为:

字段必填约束
schema_version固定为1const
diagram_type固定为"lifecycle"const
meta至少包含非空title
lanes数组,长度 1~4,每项必填idlabel
states数组,至少 2 项
transitions数组,每项至少包含fromto
cards摘要卡片数组(见下文)

整个 Schema 采用additionalProperties: false严格模式,任何未声明字段都会被直接判为非法。

2.1 语义化且保留的 Lane ID

生命周期图的三个横向"带"(band)完全由 lane 的 id 决定,这是整个布局体系的核心约定(源码实现在 render-lifecycle.mjs 的bandFor()):

  • main(必填):映射到顶部"阶段带"(Phase band),承载主生命周期横轨;
  • terminal:映射到底部"结果带"(Outcome band),承载终态退出;
  • 其他任意 id:最多 4 条 lane 总数内,所有非main/terminal的 lane共享同一个中部"事件带"(Event band),彼此之间通过yOffset在视觉上错开。

三条带的标题文字直接取自你的 lane label(见bandTitles()renderBands()):中部事件带会把所有事件 lane 的 label 用+拼接,例如"Interruptions + Recovery loop"

2.2 完整实战示例:Agent Run Lifecycle

仓库中的 agent-run.lifecycle.json 是文档明确指出的完整工作示例,它演示了主阶段带 + 事件带 + 终态带的全部语义:

{ "schema_version": 1, "diagram_type": "lifecycle", "meta": { "title": "Agent Run Lifecycle", "output": "examples/lifecycle-agent-run.html", "viewBox": [980, 660], "animation": "trace", "quality_profile": "showcase", "views": [ { "id": "main-lifecycle", "label": "Main lifecycle", "focus": ["queued", "planning", "executing", "reviewing", "completed"], "note": "Follow the ordered phases from accepted request to completed response." }, { "id": "human-waits", "label": "Human and input waits", "focus": ["executing", "approval", "reviewing", "blocked"], "note": "See where the run pauses without becoming terminal." }, { "id": "recovery-and-exits", "label": "Recovery and terminal exits", "focus": ["executing", "failed", "blocked", "cancelled", "expired"], "note": "Separate retryable failure from cancellation and expiry." } ] }, "lanes": [ { "id": "main", "label": "Lifecycle phases" }, { "id": "waiting", "label": "Interruptions" }, { "id": "exceptions", "label": "Recovery loop" }, { "id": "terminal", "label": "Terminal exits" } ], "states": [ { "id": "queued", "type": "start", "label": "Queued", "sublabel": "request accepted", "lane": "main", "col": 0, "step": "01", "tag": "entry" }, { "id": "planning", "type": "active", "label": "Planning", "sublabel": "build task graph", "lane": "main", "col": 1, "step": "02", "tag": "model" }, { "id": "executing", "type": "active", "label": "Executing", "sublabel": "tool calls", "lane": "main", "col": 2, "step": "03", "tag": "work" }, { "id": "reviewing", "type": "decision", "label": "Reviewing", "sublabel": "quality gate", "lane": "main", "col": 3, "step": "04", "tag": "check" }, { "id": "completed", "type": "success", "label": "Completed", "sublabel": "final response", "lane": "main", "col": 4, "step": "05", "tag": "done" }, { "id": "approval", "type": "waiting", "label": "Needs Approval", "sublabel": "human gate", "lane": "waiting", "col": 0, "tag": "pause" }, { "id": "blocked", "type": "waiting", "label": "Blocked", "sublabel": "missing input", "lane": "waiting", "col": 1, "tag": "wait" }, { "id": "failed", "type": "failure", "label": "Failed", "sublabel": "recoverable error", "lane": "exceptions", "col": 0, "yOffset": 78, "tag": "retryable" }, { "id": "cancelled", "type": "failure", "label": "Cancelled", "sublabel": "user stopped", "lane": "terminal", "col": 0, "tag": "terminal" }, { "id": "expired", "type": "failure", "label": "Expired", "sublabel": "timeout", "lane": "terminal", "col": 1, "tag": "terminal" } ], "transitions": [ { "id": "approval-needed", "from": "executing", "to": "approval", "variant": "security", "fromSide": "bottom", "toSide": "top", "route": "straight" }, { "id": "review-blocked", "from": "reviewing", "to": "blocked", "variant": "default", "route": "drop" }, { "id": "execution-failed", "from": "executing", "to": "failed", "variant": "security", "fromSide": "left", "toSide": "left", "via": [[320, 157], [320, 385]] }, { "id": "failed-retry", "from": "failed", "to": "executing", "variant": "emphasis", "fromSide": "left", "toSide": "top", "via": [[20, 385], [20, 80], [402, 80]] }, { "id": "block-expired", "from": "blocked", "to": "expired", "variant": "security", "fromSide": "bottom", "toSide": "top", "route": "straight" }, { "id": "approval-cancelled", "from": "approval", "to": "cancelled", "variant": "security", "fromSide": "bottom", "toSide": "top", "via": [[480, 336], [480, 432], [402, 432]] } ], "cards": [ { "dot": "emerald", "title": "Main Path", "items": ["The run has five ordered phases from queue to completion", "The primary lifecycle is carried by one horizontal rail", "Completion is a phase, not a detached side box"] }, { "dot": "amber", "title": "Human + Input Gates", "items": ["Approval pauses execution without ending the run", "Blocked waits for missing user input", "Wait states remain non-terminal until cancellation or expiry"] }, { "dot": "rose", "title": "Terminal + Recovery", "items": ["Failed loops back while retry budget remains", "Cancelled and Expired are exits from the lifecycle", "Terminal exits do not point back into active execution"] } ] }

这个示例同时体现了meta.views(引导视图,最多 5 个,每个含focus语义 id 列表)、animation: "trace"(轨迹动画)、quality_profile: "showcase"cards(摘要卡片)等高级特性。仓库还在 test/fixtures/v1-baseline/agent-run.lifecycle.json 提供了一份不依赖任何高级特性的 v1 基线版本,用于兼容性回归验证。

三、State 与 Transition 字段详解

3.1 State 字段

依据 lifecycle.schema.json,每个 state 必填idtypelabellanecol,可选字段如下:

字段类型/约束说明
type枚举:start/active/waiting/decision/success/failure/neutral/external决定配色、图例项与语义标记(见typeClass/textClass映射,render-lifecycle.mjs)
sublabel字符串主标签下方的次要说明,随详情层(detail)展示
tag字符串状态右下角的角标文本,如"entry""pause"
step字符串有序阶段序号,如"01""02",渲染在状态左上角
brand字符串或{url, sha256}对象品牌标记(brand mark),见共享品牌协议
col整数 0~4列号,对应所在带的列中心表(见下文布局预算)
width/height数字,分别 ≥48 / ≥36覆盖该带默认状态尺寸
yOffset数字纵向偏移,用于在同一事件带内错开不同 lane 的状态

3.2 Transition 字段

每个 transition 必填fromto(均引用 state id),可选字段:

字段说明
id可选但推荐;一旦提供即成为查看器链接的持久身份,且全局唯一(见 cli.mjs 的validateRelationshipIds
label/note连线标签与附注
variant枚举default/emphasis/security/dashed,决定线型与箭头样式
route路由预设:auto(默认)、straightdropbottom-channeltop-channelright-channelleft-channel
fromSide/toSide端点出口/入口方向:left/right/top/bottom
channelX/channelY手动指定通道坐标,覆盖路由预设的默认通道位置
cornerRadius多段连线圆角半径,默认 10,0为直角折线
via显式途经点数组(每点为[x, y]),作者指定的点具有最高优先级
width线宽(≥0.5)
labelAt/labelDx/labelDy/labelSegment标签位置微调:绝对点位、dx/dy 偏移、所在线段索引

3.3 meta 共享字段

meta还支持来自 common.schema.json 的共享定义:

  • localeenzh-CN(渲染器内部文本与无障碍文案据此本地化,见 i18n.mjs);
  • animationtrace(轨迹动画)或none
  • visual_presetclassic/signal-flow/blueprint/editorial
  • quality_profilestandard(默认)或showcase
  • views:引导视图,最多 5 个;
  • legend:图例覆盖配置;
  • viewBox[宽度, 高度]数组,宽度 ≥420、高度 ≥566(Schema 最小值),默认[980, 660]

四、布局预算:三带坐标系

Lifecycle 渲染器采用固定化的三带布局,坐标在 render-lifecycle.mjs 中定义为常量。README 给出了完整的布局预算表:

Lane idTop y列中心默认状态尺寸
阶段带 Phasemain(必填)126col0–4 → x = 94, 248, 402, 556, 710118×62
事件带 Event其他任意 id278col0–2 → x = 402, 556, 710126×58
结果带 Outcometerminal450col0–2 → x = 402, 556, 710118×58

关键设计:事件带与结果带的列是相对主阶段轨有意偏移的——下带col: N与主带col: N + 2使用相同的 x 坐标。也就是说,下带第 0、1、2 列分别对齐在主带第 2、3、4 列的正下方。这种对齐让"中断/终态"天然落在主流程后半段的下方,视觉上形成稳定的竖直"出口通道"。

4.1 布局常量汇总

常量
viewBox默认[980, 660];Schema 最小[420, 566]
状态水平边界x 落在[32, width − 32]内;状态底部不得低于height − 122
状态间距任意两个状态之间 ≥10px——跨 lane 检查,因为所有事件 lane 共享同一条带;同带内靠colyOffset分开
连线长度端点间距 ≥32px
图例行基线最终基线 y =height − 36;额外测量的图例行向上回绕

主生命周期轨(primary lifecycle rail)沿阶段带运行,并延伸到最右侧被占用的阶段列(见renderLifecycleRail(),轨线从x=154起以 2.2px 强调线 + 箭头收尾)。

4.2 路由预设

过渡连线的路径完全由route预设 + 通道坐标 +via途经点决定,源码实现在routeVia()(render-lifecycle.mjs):

预设行为
straight直线,无中间点
dropchannelY处折弯(默认取起终点纵向中点)
bottom-channelchannelY处水平折弯(默认max(两状态底边) + 34
top-channelchannelY处水平折弯(默认min(两状态顶边) − 28
right-channelchannelX处竖直折弯(默认max(两状态右边) + 36
left-channelchannelX处竖直折弯(默认min(两状态左边) − 36
via显式途经点,完全由作者指定,最高优先级
auto(默认)按端点出/入方向自动推断单弯或双弯

多段连线会统一做圆角处理,cornerRadius默认 10,设为0得到锐利直角折线。自动路由的端点还会经过automaticPortSpread(自动端口分散)处理,同侧多条连线会自动在状态边上分散锚点,避免端口重叠(见 render-lifecycle.mjs)。

五、图例(Legend)

生命周期图例默认从states[].type推导需要展示的种类。meta.legend.entries支持按稳定顺序覆盖以下 key:startactivewaitingdecisionsuccessfailureneutralexternal(该稳定顺序同时被渲染器的LEGEND_CATALOG固化,见 render-lifecycle.mjs)。

共享图例契约(legend.mjs)支持三种模式与逐项覆盖:

"legend": { "mode": "auto", "entries": { "success": { "label": "完成", "visible": true }, "failure": { "label": "失败/终态", "visible": true }, "neutral": { "visible": false } } }
  • modeauto(只展示图中出现的种类)、all(展示全部)、hidden(不渲染图例);
  • 每项可覆盖labelvisible
  • 只有被图中实际渲染状态支撑的种类才会获得 Semantic Legend 交互控件interactive标记取决于该 kind 是否 present,见resolveLegend())。

图例的布局由共享measureLegend()统一计算:自动换行、多行向上回绕、行数超限时在unfit: 'error'(作者显式声明图例时)与unfit: 'hide'(未声明时)之间选择失败或隐藏行为。

六、设计规则:把生命周期画成"阶段地图"

README 明确给出了一套创作纪律,这是 Lifecycle 类型区别于普通状态机图的核心哲学:

  • 把生命周期图当作阶段地图(phase map),而不是密集的状态转移图——不要试图塞进所有状态细节;
  • mainlane 把主生命周期放在一条水平轨上;
  • step标签标记有序阶段,如010203
  • 下带只用于中断、恢复与终态退出
  • 除非必要,不要把连线标签放进主 SVG——优先使用节点标签、tag、图例项与摘要卡片传达信息;
  • 避免斜线与交叉线;终态退出应尽可能从源事件竖直下坠
  • 语义选型约定:success表示完成、failure表示失败/终态退出、waiting表示暂停、decision表示质量门禁。

七、校验与质量门禁:渲染失败即交付失败

Lifecycle Renderer 的校验分两层执行,全部在写文件之前完成(validateLifecycle()在 render-lifecycle.mjs 中定义,出错时通过throwDiagnosticProblems以非零退出码结束)。

7.1 Schema 层

违反 Schema 的输入会以带路径前缀(path-prefixed)的错误消息退出,消息会标注到具体元素的 id 或 label,方便快速定位。

7.2 布局层(可检测即失败)

渲染器在 Schema 之外还做了大量几何级检测,任一失败都会阻止输出:

  • 缺少mainlane、重复的 state id、未知 lane、未知连线端点;
  • 状态超出生命周期区域(水平越界或越过height − 122下边界);
  • 状态重叠(含跨 lane)、标签与状态或其他标签碰撞、标签宽于所属状态、过短到不可读的连线;
  • 连线穿越无关状态(2px Clean Flow 净空);
  • 生命周期带是有意的直通容器(pass-through containers),不作为障碍物参与路由;
  • 文本宽度采用CJK 感知估算:全角字形按 2 个单位计宽(textUnits),中文标签不会出现宽度误判。

7.3 quality_profile:standard 与 showcase 双档

设置meta.quality_profile: "showcase"可获得更严苛的交付级校验:

检测项standard(默认)showcase
无关连线 proper X 交叉作为 artifact-receipt 警告失败,报composition/proper-crossing
无关连线重叠 ≥8px(共线走廊)警告失败
任意路由段 <8px容忍失败
内部拐弯段 <16px容忍失败
8–15px 的普通端点短桩有效仍有效

最后的产品检查还会抽样验证圆角Q命令是否存在(保证圆角真正落到 SVG 输出中)。另外,作者显式指定的via途经点在 v1 Schema 中是权威性的:即使处于 showcase 档,也会被原样渲染而不做端点侧门禁的二次篡改,只有自动路由才应用端点侧门禁(见 render-lifecycle.mjs 的注释与shouldCheckRelation)。

八、渲染流水线与产物

渲染器的执行流程(renderSvg(),render-lifecycle.mjs)依次组装:

  1. 背景网格url(#grid)填充);
  2. 三条生命周期带renderBands()绘制 112/264/436 处的虚线段(stroke-dasharray="3,8")与带标题,标题带01 /02 /03 /前缀;
  3. 主生命周期轨renderLifecycleRail()
  4. 连线路径renderTransitionPath()输出带data-composition-points(供后续几何审计)的 path,并按variant选择箭头 marker;
  5. 状态节点renderState()输出带data-node-*语义属性、可聚焦(tabindex="0")的节点组,按animateAttr附加--step动画步进;
  6. 连线标签renderTransitionLabel()
  7. 图例renderLegend()

最后writeDiagram()(cli.mjs)把 SVG 与摘要卡片填充进 assets/template.html,写入独立 HTML 文件——该产物自带查看器交互(节点聚焦、引导视图、语义图例、动画),可离线打开。此外,产物还会附带仓库证据(repository evidence)数据(verifyRepositoryEvidence),让图表可被追溯。

九、进阶:动画、引导视图与摘要卡片

9.1 动画

meta.animation: "trace"会为节点与连线附加data-animate--step步进样式,实现按拓扑顺序的轨迹动画;步进数上限 12(见animateAttr),以保证在固定时长的 WebM 捕获窗口内完成。

9.2 引导视图(Guided Views)

meta.views数组(最多 5 项)把复杂生命周期拆成可讲解的焦点视图,每项含idlabelfocus(语义 id 列表)与可选note。共享校验validateGuidedViews会强制focus引用的 id 必须真实存在且无重复,避免出现"视图指向不存在的状态"。

9.3 摘要卡片(Cards)

cards数组把核心结论沉淀为图下方的摘要卡(点色可选cyan/emerald/violet/amber/rose/orange/slate),适合用三张卡片分别总结"主路径 / 人工与输入门禁 / 终态与恢复"。

十、把 Lifecycle 渲染器接入你的流程

Lifecycle Renderer 可以被任何语言/脚本以子进程方式调用:传入 JSON 路径,读取 stdout 的输出路径,检查退出码即可判断校验是否通过。批量渲染场景可以参考 render-examples.mjs 中['lifecycle', 'agent-run.lifecycle.json', 'lifecycle-agent-run.html']的注册方式,把 lifecycle 渲染纳入统一渲染管线。若希望以当前仓库为证据根目录做仓库证据注入,可通过ARCHIFY_REPO_ROOT环境变量指定。

适用场景总结:Agent 任务运行生命周期、CI/CD 流水线阶段与恢复、部署发布流程、人工审批门禁、任何"有序阶段 + 中断/恢复 + 终态"并存的过程建模。记住一句话:主流程上横轨,中断与终态下坠,质量门禁用decision,交付前记得打开showcase

【免费下载链接】archifyAgent skill for beautiful, verifiable architecture, workflow, sequence,>项目地址: https://gitcode.com/GitHub_Trending/arch/archify

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询